diff options
author | Michael Muré <batolettre@gmail.com> | 2018-08-05 15:27:46 +0200 |
---|---|---|
committer | Michael Muré <batolettre@gmail.com> | 2018-08-05 15:27:46 +0200 |
commit | b2f20c9a61715b0a60f9e55688dbed221d775c7e (patch) | |
tree | 827d9a62a86cdd10061cb5f0289935c158f54191 /util/persisted_lamport.go | |
parent | 90fb85e067326b0f0a121e781f87df762f385592 (diff) | |
download | git-bug-b2f20c9a61715b0a60f9e55688dbed221d775c7e.tar.gz |
util: add a Lamport clock implementation as well as a persistable one
Diffstat (limited to 'util/persisted_lamport.go')
-rw-r--r-- | util/persisted_lamport.go | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/util/persisted_lamport.go b/util/persisted_lamport.go new file mode 100644 index 00000000..43a2863c --- /dev/null +++ b/util/persisted_lamport.go @@ -0,0 +1,81 @@ +package util + +import ( + "fmt" + "io/ioutil" + "os" + "path/filepath" +) + +type PersistedLamport struct { + LamportClock + filePath string +} + +func NewPersistedLamport(filePath string) *PersistedLamport { + clock := &PersistedLamport{ + filePath: filePath, + } + return clock +} + +func LoadPersistedLamport(filePath string) (*PersistedLamport, error) { + clock := &PersistedLamport{ + filePath: filePath, + } + + err := clock.read() + if err != nil { + return nil, err + } + + return clock, nil +} + +func (c *PersistedLamport) Witness(time LamportTime) error { + c.LamportClock.Witness(time) + return c.Write() +} + +func (c *PersistedLamport) Time() LamportTime { + // Equivalent to: + // + // res = c.LamportClock.Time() + // bugClock.Increment() + // + // ... but thread safe + return c.Increment() - 1 +} + +func (c *PersistedLamport) read() error { + content, err := ioutil.ReadFile(c.filePath) + 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") + } + + c.LamportClock = NewLamportClockWithTime(value) + + return nil +} + +func (c *PersistedLamport) Write() error { + dir := filepath.Dir(c.filePath) + err := os.MkdirAll(dir, 0777) + if err != nil { + return err + } + + data := []byte(fmt.Sprintf("%d", c.LamportClock.Time())) + return ioutil.WriteFile(c.filePath, data, 0644) +} |