mirror of https://github.com/ledisdb/ledisdb.git
138 lines
2.0 KiB
Go
138 lines
2.0 KiB
Go
|
package wal
|
||
|
|
||
|
import (
|
||
|
"encoding/binary"
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"path"
|
||
|
"sync"
|
||
|
)
|
||
|
|
||
|
type FileIDGenerator struct {
|
||
|
LogIDGenerator
|
||
|
|
||
|
m sync.Mutex
|
||
|
f *os.File
|
||
|
|
||
|
id uint64
|
||
|
}
|
||
|
|
||
|
func NewFileIDGenerator(base string) (*FileIDGenerator, error) {
|
||
|
if err := os.MkdirAll(base, 0755); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
g := new(FileIDGenerator)
|
||
|
|
||
|
name := path.Join(base, "log.id")
|
||
|
|
||
|
var err error
|
||
|
if g.f, err = os.OpenFile(name, os.O_CREATE|os.O_RDWR, 0644); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
s, _ := g.f.Stat()
|
||
|
if s.Size() == 0 {
|
||
|
g.id = 0
|
||
|
} else if s.Size() == 8 {
|
||
|
if err = binary.Read(g.f, binary.BigEndian, &g.id); err != nil {
|
||
|
g.f.Close()
|
||
|
return nil, err
|
||
|
} else if g.id == InvalidLogID {
|
||
|
g.f.Close()
|
||
|
return nil, fmt.Errorf("read invalid log id in %s", name)
|
||
|
}
|
||
|
} else {
|
||
|
g.f.Close()
|
||
|
return nil, fmt.Errorf("log id file %s is invalid", name)
|
||
|
}
|
||
|
|
||
|
return g, nil
|
||
|
}
|
||
|
|
||
|
func (g *FileIDGenerator) Reset(id uint64) error {
|
||
|
g.m.Lock()
|
||
|
defer g.m.Unlock()
|
||
|
|
||
|
if g.f == nil {
|
||
|
return fmt.Errorf("generator closed")
|
||
|
}
|
||
|
|
||
|
if g.id < id {
|
||
|
g.id = id
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (g *FileIDGenerator) GenerateID() (uint64, error) {
|
||
|
g.m.Lock()
|
||
|
defer g.m.Unlock()
|
||
|
|
||
|
if g.f == nil {
|
||
|
return 0, fmt.Errorf("generator closed")
|
||
|
}
|
||
|
|
||
|
if _, err := g.f.Seek(0, os.SEEK_SET); err != nil {
|
||
|
return 0, nil
|
||
|
}
|
||
|
|
||
|
id := g.id + 1
|
||
|
|
||
|
if err := binary.Write(g.f, binary.BigEndian, id); err != nil {
|
||
|
return 0, nil
|
||
|
}
|
||
|
|
||
|
g.id = id
|
||
|
|
||
|
return id, nil
|
||
|
}
|
||
|
|
||
|
func (g *FileIDGenerator) Close() error {
|
||
|
g.m.Lock()
|
||
|
defer g.m.Unlock()
|
||
|
|
||
|
if g.f != nil {
|
||
|
err := g.f.Close()
|
||
|
g.f = nil
|
||
|
return err
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
type MemIDGenerator struct {
|
||
|
m sync.Mutex
|
||
|
|
||
|
LogIDGenerator
|
||
|
|
||
|
id uint64
|
||
|
}
|
||
|
|
||
|
func NewMemIDGenerator(baseID uint64) *MemIDGenerator {
|
||
|
g := &MemIDGenerator{id: baseID}
|
||
|
return g
|
||
|
}
|
||
|
|
||
|
func (g *MemIDGenerator) Reset(id uint64) error {
|
||
|
g.m.Lock()
|
||
|
defer g.m.Unlock()
|
||
|
|
||
|
if g.id < id {
|
||
|
g.id = id
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (g *MemIDGenerator) GenerateID() (uint64, error) {
|
||
|
g.m.Lock()
|
||
|
defer g.m.Unlock()
|
||
|
|
||
|
g.id++
|
||
|
id := g.id
|
||
|
return id, nil
|
||
|
}
|
||
|
|
||
|
func (g *MemIDGenerator) Close() error {
|
||
|
return nil
|
||
|
}
|