diff options
author | Michael Muré <batolettre@gmail.com> | 2020-06-26 19:20:36 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-26 19:20:36 +0200 |
commit | 1e3dd82fd619f7b43b3193016232ef69f9707f42 (patch) | |
tree | 00e847500b34c6f9a721c71474993d1c08ae8fb1 /util/lamport/persisted_clock.go | |
parent | 2dd0dbb1344ae9293aae05346f977b5d5907934b (diff) | |
parent | 88ad7e606f1cbf9e47b968a208e3510f7f9a81c5 (diff) | |
download | git-bug-1e3dd82fd619f7b43b3193016232ef69f9707f42.tar.gz |
Merge pull request #411 from MichaelMure/repo-rework
Repository rework
Diffstat (limited to 'util/lamport/persisted_clock.go')
-rw-r--r-- | util/lamport/persisted_clock.go | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/util/lamport/persisted_clock.go b/util/lamport/persisted_clock.go new file mode 100644 index 00000000..e70b01ef --- /dev/null +++ b/util/lamport/persisted_clock.go @@ -0,0 +1,100 @@ +package lamport + +import ( + "errors" + "fmt" + "io/ioutil" + "os" + "path/filepath" +) + +var ErrClockNotExist = errors.New("clock doesn't exist") + +type PersistedClock struct { + *MemClock + filePath string +} + +// NewPersistedClock create a new persisted Lamport clock +func NewPersistedClock(filePath string) (*PersistedClock, error) { + clock := &PersistedClock{ + MemClock: NewMemClock(), + filePath: filePath, + } + + dir := filepath.Dir(filePath) + err := os.MkdirAll(dir, 0777) + if err != nil { + return nil, err + } + + err = clock.Write() + if err != nil { + return nil, err + } + + return clock, nil +} + +// LoadPersistedClock load a persisted Lamport clock from a file +func LoadPersistedClock(filePath string) (*PersistedClock, error) { + clock := &PersistedClock{ + filePath: filePath, + } + + err := clock.read() + if err != nil { + return nil, err + } + + return clock, nil +} + +// Increment is used to return the value of the lamport clock and increment it afterwards +func (pc *PersistedClock) Increment() (Time, error) { + time, err := pc.MemClock.Increment() + if err != nil { + return 0, err + } + return time, pc.Write() +} + +// Witness is called to update our local clock if necessary after +// witnessing a clock value received from another process +func (pc *PersistedClock) Witness(time Time) error { + // TODO: rework so that we write only when the clock was actually updated + err := pc.MemClock.Witness(time) + if err != nil { + return err + } + return pc.Write() +} + +func (pc *PersistedClock) read() error { + content, err := ioutil.ReadFile(pc.filePath) + if os.IsNotExist(err) { + return ErrClockNotExist + } + if err != nil { + return err + } + + var value uint64 + n, err := fmt.Sscanf(string(content), "%d", &value) + if err != nil { + return err + } + + if n != 1 { + return fmt.Errorf("could not read the clock") + } + + pc.MemClock = NewMemClockWithTime(value) + + return nil +} + +func (pc *PersistedClock) Write() error { + data := []byte(fmt.Sprintf("%d", pc.counter)) + return ioutil.WriteFile(pc.filePath, data, 0644) +} |