pdf of design

master
Bel LaPointe 2023-10-11 17:43:31 -06:00
parent 1a1640b772
commit 59b852110a
3 changed files with 30 additions and 4 deletions

View File

@ -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

View File

@ -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)