func (l *List) commit() (committed bool, rerr error) { l.Lock() defer l.Unlock() if len(l.mlayer) == 0 { atomic.StoreInt64(&l.dirtyTs, 0) return false, nil } var final types.PostingList ubuf := make([]byte, 16) h := md5.New() count := 0 l.iterate(0, func(p *types.Posting) bool { // Checksum code. n := binary.PutVarint(ubuf, int64(count)) h.Write(ubuf[0:n]) n = binary.PutUvarint(ubuf, p.Uid) h.Write(ubuf[0:n]) h.Write(p.Value) h.Write([]byte(p.Label)) count++ // I think it's okay to take the pointer from the iterator, because we have a lock // over List; which won't be released until final has been marshalled. Thus, the // underlying data wouldn't be changed. final.Postings = append(final.Postings, p) return true }) final.Checksum = h.Sum(nil) data, err := final.Marshal() x.Checkf(err, "Unable to marshal posting list") sw := l.StartWait() ce := commitEntry{ key: l.key, val: data, sw: sw, } commitCh <- ce // Now reset the mutation variables. atomic.StorePointer(&l.pbuffer, nil) // Make prev buffer eligible for GC. atomic.StoreInt64(&l.dirtyTs, 0) // Set as clean. l.mlayer = l.mlayer[:0] l.lastCompact = time.Now() return true, nil }