Пример #1
0
// Saves Meta data from dirTree to meta File
func saveMeta(data *ReveloData) error {
	var Meta *horcrux.Meta
	var err error

	data.lock.RLock()
	Meta, err = dirTree.GetMeta(data.Root)
	Meta.Config = data.Config
	Meta.CurrVer = data.CurrVer
	data.lock.RUnlock()

	if err != nil {
		log.Error("saveMeta: Cannot get Meta data")
		return err
	}

	js, err := json.MarshalIndent(Meta, "", "    ")
	if err != nil {
		log.WithFields(
			log.Fields{"Meta": Meta, "Error": err}).Error("saveMeta: Cannot marshal meta")
		return err
	}

	metaFile, err := os.OpenFile(data.cacheDir+"/"+data.metaName, os.O_WRONLY|os.O_SYNC, 0600)
	if err != nil {
		log.WithFields(log.Fields{"Meta File": data.metaName, "Error": err}).Error("saveMeta: Cannot open meta file")
		return err
	}
	defer metaFile.Close()

	// XXX Using File EX lock to avoid multiple access
	for err = syscall.Flock(int(metaFile.Fd()), syscall.LOCK_EX); err == syscall.EINTR; {
	}

	if err != nil {
		log.WithFields(log.Fields{"Error": err}).Error("saveMeta: Cannot lock meta file")
		return err
	}

	defer syscall.Flock(int(metaFile.Fd()), syscall.LOCK_UN)

	metaFile.Truncate(0) //XXX: Do Truncate(n) after write succeeds!!
	n, err := metaFile.Write(js)
	if err != nil {
		log.WithFields(log.Fields{
			"Meta file": data.metaName, "Wrote": n, "Size": len(js), "Error": err,
		}).Error("saveMeta: Cannot write to meta file")
		return err
	}

	log.Debug("saveMeta: Done")
	return nil
}
Пример #2
0
// Walks the tree and gets the flat Meta data
func GetMeta(root *Node) (*horcrux.Meta, error) {
	var Meta *horcrux.Meta
	var queue [MIN_KIDS * MIN_KIDS]*Node

	if root == nil {
		log.Error("GetMeta: nil root")
		return nil, syscall.EINVAL
	}

	q := queue[0:0]

	Meta = new(horcrux.Meta)
	Meta.Entries = make([]horcrux.Entry, 0, MIN_KIDS*MIN_KIDS)
	node := root
	idx := 0
	for node != nil {
		/*
			log.WithFields(log.Fields{
				"Idx":    idx,
				"Name":   node.Entry.Name,
				"Prefix": node.Entry.Prefix,
			}).Debug("Getting Entry")
		*/

		Meta.Entries = append(Meta.Entries, node.Entry)
		idx++
		for i := 0; i < node.numKids; i++ {
			name := node.kidsArr[i]
			n := node.kidsMap[name]
			/*
				log.WithFields(log.Fields{
					"Entry Name":   n.Entry.Name,
					"Entry Prefix": n.Entry.Prefix,
				}).Debug("Queuing node..")
			*/
			q = enqueue(q, n)
		}
		q, node = dequeue(q)
	}

	Meta.NumFiles = idx
	Meta.Entries = Meta.Entries[:idx]
	return Meta, nil
}