func (r *Replication) Log(data []byte) (*Log, error) { if r.cfg.Replication.Compression { //todo optimize var err error if data, err = snappy.Encode(nil, data); err != nil { return nil, err } } r.m.Lock() lastID, err := r.s.LastID() if err != nil { r.m.Unlock() return nil, err } commitId := r.commitID if lastID < commitId { lastID = commitId } else if lastID > commitId { r.m.Unlock() return nil, ErrCommitIDBehind } l := new(Log) l.ID = lastID + 1 l.CreateTime = uint32(time.Now().Unix()) if r.cfg.Replication.Compression { l.Compression = 1 } else { l.Compression = 0 } l.Data = data if err = r.s.StoreLog(l); err != nil { r.m.Unlock() return nil, err } r.m.Unlock() r.ncm.Lock() close(r.nc) r.nc = make(chan struct{}) r.ncm.Unlock() return l, nil }
func (l *Ledis) Dump(w io.Writer) error { var err error var commitID uint64 var snap *store.Snapshot l.wLock.Lock() if l.r != nil { if commitID, err = l.r.LastCommitID(); err != nil { l.wLock.Unlock() return err } } if snap, err = l.ldb.NewSnapshot(); err != nil { l.wLock.Unlock() return err } l.wLock.Unlock() wb := bufio.NewWriterSize(w, 4096) h := &DumpHead{commitID} if err = h.Write(wb); err != nil { return err } it := snap.NewIterator() it.SeekToFirst() compressBuf := make([]byte, 4096) var key []byte var value []byte for ; it.Valid(); it.Next() { key = it.RawKey() value = it.RawValue() if key, err = snappy.Encode(compressBuf, key); err != nil { return err } if err = binary.Write(wb, binary.BigEndian, uint16(len(key))); err != nil { return err } if _, err = wb.Write(key); err != nil { return err } if value, err = snappy.Encode(compressBuf, value); err != nil { return err } if err = binary.Write(wb, binary.BigEndian, uint32(len(value))); err != nil { return err } if _, err = wb.Write(value); err != nil { return err } } if err = wb.Flush(); err != nil { return err } compressBuf = nil return nil }