utils/synclog/meta_info.go (74 lines of code) (raw):

package synclog import ( "bytes" "encoding/binary" "fmt" "os" unix "golang.org/x/sys/unix" ) type MetaInfo struct { metaFile *os.File metaData []byte // use mmap to open meta file meta *MetaData } func OpenMetaFile(dirPath string) (*MetaInfo, error) { metaFilePath := fmt.Sprintf("%s/meta", dirPath) metaInfo := &MetaInfo{} metaFileInfo, err := os.Stat(metaFilePath) if os.IsNotExist(err) { metaFile, err := os.OpenFile(metaFilePath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0644) if err != nil { return nil, fmt.Errorf("create meta file %s: %v fail", metaFilePath, err) } err = unix.Ftruncate(int(metaFile.Fd()), 1024) if err != nil { return nil, err } metaData, err := unix.Mmap(int(metaFile.Fd()), 0, 1024, unix.PROT_WRITE, unix.MAP_SHARED) if err != nil { return nil, err } metaInfo.metaData = metaData meta := NewMetaData() metaInfo.metaFile = metaFile metaInfo.meta = meta metaBytes := meta.ToBytes() copy(metaInfo.metaData, metaBytes) } else if err != nil { return nil, fmt.Errorf("can't stat meta file %s: %v", metaFilePath, err) } else { metaFile, err := os.OpenFile(metaFilePath, os.O_RDWR, 0644) if err != nil { return nil, fmt.Errorf("open meta file %s: %v fail", metaFilePath, err) } metaData, err := unix.Mmap(int(metaFile.Fd()), 0, int(metaFileInfo.Size()), unix.PROT_WRITE, unix.MAP_SHARED) if err != nil { return nil, err } metaInfo.metaData = metaData metaInfo.metaFile = metaFile meta := NewMetaData() metaSize := meta.MetaSize() buf := make([]byte, metaSize) copy(buf, metaInfo.metaData) if err := meta.FromBytes(bytes.NewReader(buf)); err != nil { return nil, err } metaInfo.meta = meta } return metaInfo, nil } func (m *MetaInfo) SaveOffset(offset uint32) { m.meta.Offset = offset buf := bufferPool.Get().(*bytes.Buffer) buf.Reset() defer bufferPool.Put(buf) binary.Write(buf, binary.LittleEndian, offset) copy(m.metaData[m.meta.MetaSize()-4:], buf.Bytes()) } func (m *MetaInfo) Close() error { if err := unix.Munmap(m.metaData); err != nil { return err } return m.metaFile.Close() }