this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

MST walk, and repo tweak (#984)

Adds a `Walk` method to `Tree` for visiting all key/value in the MST.

Also updates `GetRecordBytes` to return the CID, along with actual
bytes. It needs to be looked up from the MST anyways, and this results
in one less call/lookup in some cases. Code which doesn't need the CID
can just ignore that return type.

authored by

bnewbold and committed by
GitHub
ce3c9547 528f0e6a

+30 -9
+19
atproto/repo/mst/node.go
··· 291 291 return nil 292 292 } 293 293 294 + func (n *Node) walk(f func(key []byte, val cid.Cid) error) error { 295 + if n == nil { 296 + return fmt.Errorf("nil tree pointer") 297 + } 298 + for _, e := range n.Entries { 299 + if e.IsValue() { 300 + if err := f(e.Key, *e.Value); err != nil { 301 + return err 302 + } 303 + } 304 + if e.Child != nil { 305 + if err := e.Child.walk(f); err != nil { 306 + return err 307 + } 308 + } 309 + } 310 + return nil 311 + } 312 + 294 313 // Reads the value (CID) corresponding to the key. If key is not in the tree, returns (nil, nil). 295 314 // 296 315 // n: Node at top of sub-tree to operate on. Must not be nil.
+5
atproto/repo/mst/tree.go
··· 79 79 return t.Root.getCID(key, -1) 80 80 } 81 81 82 + // Walks the Tree, invoking the callback function on each key/value pair. 83 + func (t *Tree) Walk(f func(key []byte, val cid.Cid) error) error { 84 + return t.Root.walk(f) 85 + } 86 + 82 87 // Creates a new Tree by loading key/value pairs from a map. 83 88 func LoadTreeFromMap(m map[string]cid.Cid) (*Tree, error) { 84 89 if m == nil {
+4 -4
atproto/repo/repo.go
··· 48 48 return c, nil 49 49 } 50 50 51 - func (repo *Repo) GetRecordBytes(ctx context.Context, collection syntax.NSID, rkey syntax.RecordKey) ([]byte, error) { 51 + func (repo *Repo) GetRecordBytes(ctx context.Context, collection syntax.NSID, rkey syntax.RecordKey) ([]byte, *cid.Cid, error) { 52 52 c, err := repo.GetRecordCID(ctx, collection, rkey) 53 53 if err != nil { 54 - return nil, err 54 + return nil, nil, err 55 55 } 56 56 blk, err := repo.RecordStore.Get(ctx, *c) 57 57 if err != nil { 58 - return nil, err 58 + return nil, nil, err 59 59 } 60 60 // TODO: not verifying CID 61 - return blk.RawData(), nil 61 + return blk.RawData(), c, nil 62 62 } 63 63 64 64 // Snapshots the current state of the repository, resulting in a new (unsigned) `Commit` struct.
+2 -5
atproto/repo/sync.go
··· 61 61 if err != nil { 62 62 return nil, fmt.Errorf("invalid repo path in ops list: %w", err) 63 63 } 64 - val, err := repo.GetRecordCID(ctx, nsid, rkey) 64 + // don't use the returned bytes, but do actually read them out of store (not just CID) 65 + _, val, err := repo.GetRecordBytes(ctx, nsid, rkey) 65 66 if err != nil { 66 67 return nil, err 67 68 } 68 69 if *c != *val { 69 70 return nil, fmt.Errorf("record op doesn't match MST tree value") 70 - } 71 - _, err = repo.GetRecordBytes(ctx, nsid, rkey) 72 - if err != nil { 73 - return nil, err 74 71 } 75 72 } 76 73 }