deno.land / x / replicache@v10.0.0-beta.0 / db / visitor.ts

نووسراو ببینە
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import {assertBTreeNode} from '../btree/mod';import { assertCommitData, CommitData, IndexChangeMeta, IndexRecord, LocalMeta, Meta, MetaTyped, SnapshotMeta,} from './commit';import type * as dag from '../dag/mod';import {emptyHash, Hash} from '../hash';import {InternalNode, isInternalNode, Node} from '../btree/node';import {HashRefType} from './hash-ref-type';import {ChunkNotFoundError} from '../dag/store.js';
export class Visitor { readonly dagRead: dag.Read; private _visitedHashes: Set<Hash> = new Set();
constructor(dagRead: dag.Read) { this.dagRead = dagRead; }
async visitCommit( h: Hash, hashRefType = HashRefType.RequireStrong, ): Promise<void> { if (this._visitedHashes.has(h)) { return; } this._visitedHashes.add(h);
const chunk = await this.dagRead.getChunk(h); if (!chunk) { if (hashRefType === HashRefType.AllowWeak) { return; } throw new ChunkNotFoundError(h); }
const {data} = chunk; assertCommitData(data); await this.visitCommitChunk(chunk as dag.Chunk<CommitData<Meta>>); }
async visitCommitChunk(chunk: dag.Chunk<CommitData<Meta>>): Promise<void> { const {data} = chunk; await Promise.all([ this._visitCommitMeta(data.meta), this._visitCommitValue(data.valueHash), this._visitCommitIndexes(data.indexes), ]); }
private _visitCommitMeta(meta: Meta): Promise<void> { switch (meta.type) { case MetaTyped.IndexChange: return this._visitIndexChangeMeta(meta);
case MetaTyped.Local: return this._visitLocalMeta(meta);
case MetaTyped.Snapshot: return this._visitSnapshot(meta); } }
private async _visitBasisHash( basisHash: Hash | null, hashRefType?: HashRefType, ): Promise<void> { if (basisHash !== null) { await this.visitCommit(basisHash, hashRefType); } }
private async _visitSnapshot(meta: SnapshotMeta): Promise<void> { // basisHash is weak for Snapshot Commits await this._visitBasisHash(meta.basisHash, HashRefType.AllowWeak); }
private async _visitLocalMeta(meta: LocalMeta): Promise<void> { await this._visitBasisHash(meta.basisHash, HashRefType.RequireStrong); if (meta.originalHash !== null) { await this.visitCommit(meta.originalHash, HashRefType.AllowWeak); } }
private _visitIndexChangeMeta(meta: IndexChangeMeta): Promise<void> { return this._visitBasisHash(meta.basisHash, HashRefType.RequireStrong); }
private _visitCommitValue(valueHash: Hash): Promise<void> { return this.visitBTreeNode(valueHash); }
async visitBTreeNode(h: Hash): Promise<void> { // we use the emptyHash for an empty btree if (h === emptyHash) { return; }
if (this._visitedHashes.has(h)) { return; } this._visitedHashes.add(h);
const chunk = await this.dagRead.mustGetChunk(h); const {data} = chunk; assertBTreeNode(data);
await this.visitBTreeNodeChunk(chunk as dag.Chunk<Node>); }
async visitBTreeNodeChunk(chunk: dag.Chunk<Node>): Promise<void> { const {data} = chunk; if (isInternalNode(data)) { await this._visitBTreeInternalNode(chunk as dag.Chunk<InternalNode>); } }
private async _visitBTreeInternalNode( chunk: dag.Chunk<InternalNode>, ): Promise<void> { const {data} = chunk; await Promise.all( data[1].map(entry => this.visitBTreeNode(entry[1] as Hash)), ); }
private async _visitCommitIndexes( indexes: readonly IndexRecord[], ): Promise<void> { await Promise.all( indexes.map(async index => this.visitBTreeNode(index.valueHash)), ); }}
replicache

Version Info

Tagged at
2 years ago