+9
-2
repo/repo.go
+9
-2
repo/repo.go
···
7
"io"
8
9
"github.com/bluesky-social/indigo/atproto/repo"
10
lexutil "github.com/bluesky-social/indigo/lex/util"
11
"github.com/bluesky-social/indigo/mst"
12
"github.com/bluesky-social/indigo/util"
···
49
mst *mst.MerkleSearchTree
50
51
dirty bool
52
}
53
54
// Returns a copy of commit without the Sig field. Helpful when verifying signature.
···
111
112
func NewRepo(ctx context.Context, did string, bs cbor.IpldBlockstore) *Repo {
113
cst := util.CborStore(bs)
114
115
t := mst.NewEmptyMST(cst)
116
sc := SignedCommit{
···
124
mst: t,
125
sc: sc,
126
dirty: true,
127
}
128
}
129
130
func OpenRepo(ctx context.Context, bs cbor.IpldBlockstore, root cid.Cid) (*Repo, error) {
131
cst := util.CborStore(bs)
132
133
var sc SignedCommit
134
if err := cst.Get(ctx, root, &sc); err != nil {
···
144
bs: bs,
145
cst: cst,
146
repoCid: root,
147
}, nil
148
}
149
···
191
return cid.Undef, "", err
192
}
193
194
-
tid := NextTID()
195
196
nmst, err := t.Add(ctx, nsid+"/"+tid, k, -1)
197
if err != nil {
···
294
Did: r.RepoDid(),
295
Version: ATP_REPO_VERSION,
296
Data: rcid,
297
-
Rev: NextTID(),
298
}
299
300
sb, err := ncom.BytesForSigning()
···
7
"io"
8
9
"github.com/bluesky-social/indigo/atproto/repo"
10
+
"github.com/bluesky-social/indigo/atproto/syntax"
11
lexutil "github.com/bluesky-social/indigo/lex/util"
12
"github.com/bluesky-social/indigo/mst"
13
"github.com/bluesky-social/indigo/util"
···
50
mst *mst.MerkleSearchTree
51
52
dirty bool
53
+
54
+
clk *syntax.TIDClock
55
}
56
57
// Returns a copy of commit without the Sig field. Helpful when verifying signature.
···
114
115
func NewRepo(ctx context.Context, did string, bs cbor.IpldBlockstore) *Repo {
116
cst := util.CborStore(bs)
117
+
clk := syntax.NewTIDClock(0)
118
119
t := mst.NewEmptyMST(cst)
120
sc := SignedCommit{
···
128
mst: t,
129
sc: sc,
130
dirty: true,
131
+
clk: &clk,
132
}
133
}
134
135
func OpenRepo(ctx context.Context, bs cbor.IpldBlockstore, root cid.Cid) (*Repo, error) {
136
cst := util.CborStore(bs)
137
+
clk := syntax.NewTIDClock(0)
138
139
var sc SignedCommit
140
if err := cst.Get(ctx, root, &sc); err != nil {
···
150
bs: bs,
151
cst: cst,
152
repoCid: root,
153
+
clk: &clk,
154
}, nil
155
}
156
···
198
return cid.Undef, "", err
199
}
200
201
+
tid := r.clk.Next().String()
202
203
nmst, err := t.Add(ctx, nsid+"/"+tid, k, -1)
204
if err != nil {
···
301
Did: r.RepoDid(),
302
Version: ATP_REPO_VERSION,
303
Data: rcid,
304
+
Rev: r.clk.Next().String(),
305
}
306
307
sb, err := ncom.BytesForSigning()
-41
repo/tid.go
-41
repo/tid.go
···
1
-
package repo
2
-
3
-
import (
4
-
"math/rand"
5
-
"sync"
6
-
"time"
7
-
)
8
-
9
-
const alpha = "234567abcdefghijklmnopqrstuvwxyz"
10
-
11
-
func s32encode(i uint64) string {
12
-
var s string
13
-
for i > 0 {
14
-
c := i & 0x1f
15
-
i = i >> 5
16
-
s = alpha[c:c+1] + s
17
-
}
18
-
return s
19
-
}
20
-
21
-
func init() {
22
-
clockId = uint64(rand.Int() & 0x1f)
23
-
}
24
-
25
-
var lastTime uint64
26
-
var clockId uint64
27
-
var ltLock sync.Mutex
28
-
29
-
func NextTID() string {
30
-
t := uint64(time.Now().UnixMicro())
31
-
32
-
ltLock.Lock()
33
-
if lastTime >= t {
34
-
t = lastTime + 1
35
-
}
36
-
37
-
lastTime = t
38
-
ltLock.Unlock()
39
-
40
-
return s32encode(uint64(t)) + s32encode(clockId)
41
-
}
···
+7
-5
repomgr/repomgr.go
+7
-5
repomgr/repomgr.go
···
13
14
atproto "github.com/bluesky-social/indigo/api/atproto"
15
bsky "github.com/bluesky-social/indigo/api/bsky"
16
"github.com/bluesky-social/indigo/carstore"
17
lexutil "github.com/bluesky-social/indigo/lex/util"
18
"github.com/bluesky-social/indigo/models"
···
38
if _, ok := cs.(*carstore.NonArchivalCarstore); ok {
39
noArchive = true
40
}
41
42
return &RepoManager{
43
cs: cs,
···
45
kmgr: kmgr,
46
log: slog.Default().With("system", "repomgr"),
47
noArchive: noArchive,
48
}
49
}
50
···
70
71
log *slog.Logger
72
noArchive bool
73
}
74
75
type ActorInfo struct {
···
771
return nil
772
}
773
774
-
func rkeyForCollection(collection string) string {
775
-
return repo.NextTID()
776
-
}
777
-
778
func (rm *RepoManager) BatchWrite(ctx context.Context, user models.Uid, writes []*atproto.RepoApplyWrites_Input_Writes_Elem) error {
779
ctx, span := otel.Tracer("repoman").Start(ctx, "BatchWrite")
780
defer span.End()
···
807
if c.Rkey != nil {
808
rkey = *c.Rkey
809
} else {
810
-
rkey = rkeyForCollection(c.Collection)
811
}
812
813
nsid := c.Collection + "/" + rkey
···
13
14
atproto "github.com/bluesky-social/indigo/api/atproto"
15
bsky "github.com/bluesky-social/indigo/api/bsky"
16
+
"github.com/bluesky-social/indigo/atproto/syntax"
17
"github.com/bluesky-social/indigo/carstore"
18
lexutil "github.com/bluesky-social/indigo/lex/util"
19
"github.com/bluesky-social/indigo/models"
···
39
if _, ok := cs.(*carstore.NonArchivalCarstore); ok {
40
noArchive = true
41
}
42
+
43
+
clk := syntax.NewTIDClock(0)
44
45
return &RepoManager{
46
cs: cs,
···
48
kmgr: kmgr,
49
log: slog.Default().With("system", "repomgr"),
50
noArchive: noArchive,
51
+
clk: &clk,
52
}
53
}
54
···
74
75
log *slog.Logger
76
noArchive bool
77
+
78
+
clk *syntax.TIDClock
79
}
80
81
type ActorInfo struct {
···
777
return nil
778
}
779
780
func (rm *RepoManager) BatchWrite(ctx context.Context, user models.Uid, writes []*atproto.RepoApplyWrites_Input_Writes_Elem) error {
781
ctx, span := otel.Tracer("repoman").Start(ctx, "BatchWrite")
782
defer span.End()
···
809
if c.Rkey != nil {
810
rkey = *c.Rkey
811
} else {
812
+
rkey = rm.clk.Next().String()
813
}
814
815
nsid := c.Collection + "/" + rkey