pdf of design
parent
1a1640b772
commit
59b852110a
Binary file not shown.
|
|
@ -1,12 +1,15 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"render231011/internal/thestore"
|
"render231011/internal/thestore"
|
||||||
"slices"
|
"slices"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Oplog struct {
|
type Oplog struct {
|
||||||
|
mutex *sync.RWMutex
|
||||||
events []timestampedEvent
|
events []timestampedEvent
|
||||||
idx int // todo
|
idx int // todo
|
||||||
lastTruncated time.Time
|
lastTruncated time.Time
|
||||||
|
|
@ -17,10 +20,15 @@ type timestampedEvent struct {
|
||||||
e thestore.Event
|
e thestore.Event
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (timestampedEvent timestampedEvent) String() string {
|
||||||
|
return fmt.Sprintf("@%v: %+v", timestampedEvent.t.Unix(), timestampedEvent.e)
|
||||||
|
}
|
||||||
|
|
||||||
// gotcha duration? bigger N? whatever
|
// gotcha duration? bigger N? whatever
|
||||||
func NewOplog() *Oplog {
|
func NewOplog() *Oplog {
|
||||||
return &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) {
|
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,
|
t: t,
|
||||||
e: event,
|
e: event,
|
||||||
})
|
}
|
||||||
|
oplog.idx++
|
||||||
|
if oplog.idx >= len(oplog.events) {
|
||||||
|
oplog.idx = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (oplog *Oplog) Since(t time.Time) ([]thestore.Event, bool) {
|
func (oplog *Oplog) Since(t time.Time) ([]thestore.Event, bool) {
|
||||||
|
oplog.mutex.RLock()
|
||||||
|
defer oplog.mutex.RUnlock()
|
||||||
|
|
||||||
if !t.After(oplog.lastTruncated) {
|
if !t.After(oplog.lastTruncated) {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
result := make([]thestore.Event, 0, 5)
|
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) {
|
if !oplog.events[i].t.After(t) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
result = append(result, oplog.events[i].e)
|
result = append(result, oplog.events[i].e)
|
||||||
|
|
||||||
|
i--
|
||||||
|
if i < 0 {
|
||||||
|
i = len(oplog.events)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
slices.Reverse(result)
|
slices.Reverse(result)
|
||||||
return result, len(result) > 0
|
return result, len(result) > 0
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ func TestOplog(t *testing.T) {
|
||||||
oplog.push(time.Unix(3, 0), thestore.Event{ID: "3"})
|
oplog.push(time.Unix(3, 0), thestore.Event{ID: "3"})
|
||||||
oplog.push(time.Unix(4, 0), thestore.Event{ID: "4"})
|
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))
|
got, _ := oplog.Since(time.Unix(2, 0))
|
||||||
if len(got) != 2 {
|
if len(got) != 2 {
|
||||||
t.Error(got)
|
t.Error(got)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue