diff --git a/render-2023-10-11/LaPointe Bree interview 2023-10-11.pdf b/render-2023-10-11/LaPointe Bree interview 2023-10-11.pdf new file mode 100644 index 0000000..6e0d269 Binary files /dev/null and b/render-2023-10-11/LaPointe Bree interview 2023-10-11.pdf differ diff --git a/render-2023-10-11/cmd/cache-service/oplog.go b/render-2023-10-11/cmd/cache-service/oplog.go index 5ed4e49..8837af9 100644 --- a/render-2023-10-11/cmd/cache-service/oplog.go +++ b/render-2023-10-11/cmd/cache-service/oplog.go @@ -1,12 +1,15 @@ package main import ( + "fmt" "render231011/internal/thestore" "slices" + "sync" "time" ) type Oplog struct { + mutex *sync.RWMutex events []timestampedEvent idx int // todo lastTruncated time.Time @@ -17,10 +20,15 @@ type timestampedEvent struct { e thestore.Event } +func (timestampedEvent timestampedEvent) String() string { + return fmt.Sprintf("@%v: %+v", timestampedEvent.t.Unix(), timestampedEvent.e) +} + // gotcha duration? bigger N? whatever func NewOplog() *Oplog { return &Oplog{ - events: make([]timestampedEvent, 0, 1024), + events: make([]timestampedEvent, 2), + mutex: &sync.RWMutex{}, } } @@ -30,23 +38,39 @@ func (oplog *Oplog) Push(event thestore.Event) { } func (oplog *Oplog) push(t time.Time, event thestore.Event) { - oplog.events = append(oplog.events, timestampedEvent{ + oplog.mutex.Lock() + defer oplog.mutex.Unlock() + oplog.lastTruncated = oplog.events[oplog.idx].t + oplog.events[oplog.idx] = timestampedEvent{ t: t, e: event, - }) + } + oplog.idx++ + if oplog.idx >= len(oplog.events) { + oplog.idx = 0 + } } func (oplog *Oplog) Since(t time.Time) ([]thestore.Event, bool) { + oplog.mutex.RLock() + defer oplog.mutex.RUnlock() + if !t.After(oplog.lastTruncated) { return nil, false } result := make([]thestore.Event, 0, 5) - for i := len(oplog.events) - 1; i >= 0; i-- { + i := (oplog.idx + len(oplog.events) - 1) % len(oplog.events) + for i != oplog.idx { if !oplog.events[i].t.After(t) { break } result = append(result, oplog.events[i].e) + + i-- + if i < 0 { + i = len(oplog.events) + } } slices.Reverse(result) return result, len(result) > 0 diff --git a/render-2023-10-11/cmd/cache-service/oplog_test.go b/render-2023-10-11/cmd/cache-service/oplog_test.go index 24999ed..948690a 100644 --- a/render-2023-10-11/cmd/cache-service/oplog_test.go +++ b/render-2023-10-11/cmd/cache-service/oplog_test.go @@ -13,6 +13,8 @@ func TestOplog(t *testing.T) { oplog.push(time.Unix(3, 0), thestore.Event{ID: "3"}) oplog.push(time.Unix(4, 0), thestore.Event{ID: "4"}) + t.Logf("%+v, %s", oplog, oplog.lastTruncated.UTC()) + got, _ := oplog.Since(time.Unix(2, 0)) if len(got) != 2 { t.Error(got)