Umstellung auf uuid
All checks were successful
release-tag / release-image (push) Successful in 1m32s
All checks were successful
release-tag / release-image (push) Successful in 1m32s
This commit is contained in:
@@ -11,7 +11,6 @@ import (
|
||||
type MemStore struct {
|
||||
mu sync.Mutex
|
||||
items map[ID]File
|
||||
next ID
|
||||
|
||||
// optionales Eventing
|
||||
subs []chan ChangeEvent
|
||||
@@ -20,7 +19,6 @@ type MemStore struct {
|
||||
func NewMemStore() *MemStore {
|
||||
return &MemStore{
|
||||
items: make(map[ID]File),
|
||||
next: 1,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,39 +37,54 @@ func (m *MemStore) Get(_ context.Context, id ID) (File, error) {
|
||||
func (m *MemStore) List(_ context.Context, next ID, limit int) ([]File, ID, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
if limit <= 0 || limit > 1000 {
|
||||
limit = 100
|
||||
}
|
||||
ids := make([]ID, 0, len(m.items))
|
||||
for id := range m.items {
|
||||
ids = append(ids, id)
|
||||
|
||||
// sortiere deterministisch nach UpdatedAt, dann ID
|
||||
all := make([]File, 0, len(m.items))
|
||||
for _, v := range m.items {
|
||||
all = append(all, v)
|
||||
}
|
||||
slices.Sort(ids)
|
||||
slices.SortFunc(all, func(a, b File) int {
|
||||
if a.UpdatedAt == b.UpdatedAt {
|
||||
if a.ID == b.ID {
|
||||
return 0
|
||||
}
|
||||
if a.ID < b.ID {
|
||||
return -1
|
||||
}
|
||||
return 1
|
||||
}
|
||||
if a.UpdatedAt < b.UpdatedAt {
|
||||
return -1
|
||||
}
|
||||
return 1
|
||||
})
|
||||
|
||||
start := 0
|
||||
if next > 0 {
|
||||
for i, id := range ids {
|
||||
if id >= next {
|
||||
if next != "" {
|
||||
for i, it := range all {
|
||||
if it.ID >= next {
|
||||
start = i
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
end := start + limit
|
||||
if end > len(ids) {
|
||||
end = len(ids)
|
||||
if end > len(all) {
|
||||
end = len(all)
|
||||
}
|
||||
|
||||
out := make([]File, 0, end-start)
|
||||
for _, id := range ids[start:end] {
|
||||
it := m.items[id]
|
||||
for _, it := range all[start:end] {
|
||||
if !it.Deleted {
|
||||
out = append(out, it)
|
||||
}
|
||||
}
|
||||
var nextOut ID
|
||||
if end < len(ids) {
|
||||
nextOut = ids[end]
|
||||
if end < len(all) {
|
||||
nextOut = all[end].ID
|
||||
}
|
||||
return out, nextOut, nil
|
||||
}
|
||||
@@ -85,9 +98,12 @@ func (m *MemStore) Create(_ context.Context, name string) (File, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
now := time.Now().UnixNano()
|
||||
it := File{ID: m.next, Name: name, UpdatedAt: now}
|
||||
uid, err := NewUUIDv4()
|
||||
if err != nil {
|
||||
return File{}, err
|
||||
}
|
||||
it := File{ID: uid, Name: name, UpdatedAt: now}
|
||||
m.items[it.ID] = it
|
||||
m.next++
|
||||
m.emit(it)
|
||||
return it, nil
|
||||
}
|
||||
@@ -147,9 +163,6 @@ func (m *MemStore) ApplyRemote(_ context.Context, s Snapshot) error {
|
||||
li, ok := m.items[ri.ID]
|
||||
if !ok || ri.UpdatedAt > li.UpdatedAt {
|
||||
m.items[ri.ID] = ri
|
||||
if ri.ID >= m.next {
|
||||
m.next = ri.ID + 1
|
||||
}
|
||||
m.emitLocked(ri)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,13 +2,15 @@ package filesvc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
/*** Domain ***/
|
||||
|
||||
type ID = int64
|
||||
type ID = string
|
||||
|
||||
type File struct {
|
||||
ID ID `json:"id"`
|
||||
@@ -76,3 +78,13 @@ type MeshStore interface {
|
||||
Replicable
|
||||
Watchable // optional – kann Noop sein
|
||||
}
|
||||
|
||||
func NewUUIDv4() (string, error) {
|
||||
b := make([]byte, 16)
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
return "", err
|
||||
}
|
||||
b[6] = (b[6] & 0x0f) | 0x40 // Version 4
|
||||
b[8] = (b[8] & 0x3f) | 0x80 // Variant RFC4122
|
||||
return fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:16]), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user