@optimystic/db-p2p 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.min.js +52 -0
- package/dist/index.min.js.map +7 -0
- package/dist/src/cluster/client.d.ts +12 -0
- package/dist/src/cluster/client.d.ts.map +1 -0
- package/dist/src/cluster/client.js +65 -0
- package/dist/src/cluster/client.js.map +1 -0
- package/dist/src/cluster/cluster-repo.d.ts +79 -0
- package/dist/src/cluster/cluster-repo.d.ts.map +1 -0
- package/dist/src/cluster/cluster-repo.js +613 -0
- package/dist/src/cluster/cluster-repo.js.map +1 -0
- package/dist/src/cluster/partition-detector.d.ts +59 -0
- package/dist/src/cluster/partition-detector.d.ts.map +1 -0
- package/dist/src/cluster/partition-detector.js +129 -0
- package/dist/src/cluster/partition-detector.js.map +1 -0
- package/dist/src/cluster/service.d.ts +49 -0
- package/dist/src/cluster/service.d.ts.map +1 -0
- package/dist/src/cluster/service.js +107 -0
- package/dist/src/cluster/service.js.map +1 -0
- package/dist/src/index.d.ts +29 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +29 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/it-utility.d.ts +4 -0
- package/dist/src/it-utility.d.ts.map +1 -0
- package/dist/src/it-utility.js +32 -0
- package/dist/src/it-utility.js.map +1 -0
- package/dist/src/libp2p-key-network.d.ts +59 -0
- package/dist/src/libp2p-key-network.d.ts.map +1 -0
- package/dist/src/libp2p-key-network.js +278 -0
- package/dist/src/libp2p-key-network.js.map +1 -0
- package/dist/src/libp2p-node.d.ts +28 -0
- package/dist/src/libp2p-node.d.ts.map +1 -0
- package/dist/src/libp2p-node.js +270 -0
- package/dist/src/libp2p-node.js.map +1 -0
- package/dist/src/logger.d.ts +3 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +6 -0
- package/dist/src/logger.js.map +1 -0
- package/dist/src/network/get-network-manager.d.ts +4 -0
- package/dist/src/network/get-network-manager.d.ts.map +1 -0
- package/dist/src/network/get-network-manager.js +17 -0
- package/dist/src/network/get-network-manager.js.map +1 -0
- package/dist/src/network/network-manager-service.d.ts +82 -0
- package/dist/src/network/network-manager-service.d.ts.map +1 -0
- package/dist/src/network/network-manager-service.js +283 -0
- package/dist/src/network/network-manager-service.js.map +1 -0
- package/dist/src/peer-utils.d.ts +2 -0
- package/dist/src/peer-utils.d.ts.map +1 -0
- package/dist/src/peer-utils.js +28 -0
- package/dist/src/peer-utils.js.map +1 -0
- package/dist/src/protocol-client.d.ts +12 -0
- package/dist/src/protocol-client.d.ts.map +1 -0
- package/dist/src/protocol-client.js +34 -0
- package/dist/src/protocol-client.js.map +1 -0
- package/dist/src/repo/client.d.ts +17 -0
- package/dist/src/repo/client.d.ts.map +1 -0
- package/dist/src/repo/client.js +82 -0
- package/dist/src/repo/client.js.map +1 -0
- package/dist/src/repo/cluster-coordinator.d.ts +59 -0
- package/dist/src/repo/cluster-coordinator.d.ts.map +1 -0
- package/dist/src/repo/cluster-coordinator.js +539 -0
- package/dist/src/repo/cluster-coordinator.js.map +1 -0
- package/dist/src/repo/coordinator-repo.d.ts +29 -0
- package/dist/src/repo/coordinator-repo.d.ts.map +1 -0
- package/dist/src/repo/coordinator-repo.js +102 -0
- package/dist/src/repo/coordinator-repo.js.map +1 -0
- package/dist/src/repo/redirect.d.ts +14 -0
- package/dist/src/repo/redirect.d.ts.map +1 -0
- package/dist/src/repo/redirect.js +9 -0
- package/dist/src/repo/redirect.js.map +1 -0
- package/dist/src/repo/service.d.ts +52 -0
- package/dist/src/repo/service.d.ts.map +1 -0
- package/dist/src/repo/service.js +181 -0
- package/dist/src/repo/service.js.map +1 -0
- package/dist/src/repo/types.d.ts +7 -0
- package/dist/src/repo/types.d.ts.map +1 -0
- package/dist/src/repo/types.js +2 -0
- package/dist/src/repo/types.js.map +1 -0
- package/dist/src/routing/libp2p-known-peers.d.ts +4 -0
- package/dist/src/routing/libp2p-known-peers.d.ts.map +1 -0
- package/dist/src/routing/libp2p-known-peers.js +19 -0
- package/dist/src/routing/libp2p-known-peers.js.map +1 -0
- package/dist/src/routing/responsibility.d.ts +14 -0
- package/dist/src/routing/responsibility.d.ts.map +1 -0
- package/dist/src/routing/responsibility.js +45 -0
- package/dist/src/routing/responsibility.js.map +1 -0
- package/dist/src/routing/simple-cluster-coordinator.d.ts +23 -0
- package/dist/src/routing/simple-cluster-coordinator.d.ts.map +1 -0
- package/dist/src/routing/simple-cluster-coordinator.js +59 -0
- package/dist/src/routing/simple-cluster-coordinator.js.map +1 -0
- package/dist/src/storage/arachnode-fret-adapter.d.ts +65 -0
- package/dist/src/storage/arachnode-fret-adapter.d.ts.map +1 -0
- package/dist/src/storage/arachnode-fret-adapter.js +93 -0
- package/dist/src/storage/arachnode-fret-adapter.js.map +1 -0
- package/dist/src/storage/block-storage.d.ts +31 -0
- package/dist/src/storage/block-storage.d.ts.map +1 -0
- package/dist/src/storage/block-storage.js +154 -0
- package/dist/src/storage/block-storage.js.map +1 -0
- package/dist/src/storage/file-storage.d.ts +30 -0
- package/dist/src/storage/file-storage.d.ts.map +1 -0
- package/dist/src/storage/file-storage.js +127 -0
- package/dist/src/storage/file-storage.js.map +1 -0
- package/dist/src/storage/helpers.d.ts +3 -0
- package/dist/src/storage/helpers.d.ts.map +1 -0
- package/dist/src/storage/helpers.js +28 -0
- package/dist/src/storage/helpers.js.map +1 -0
- package/dist/src/storage/i-block-storage.d.ts +32 -0
- package/dist/src/storage/i-block-storage.d.ts.map +1 -0
- package/dist/src/storage/i-block-storage.js +2 -0
- package/dist/src/storage/i-block-storage.js.map +1 -0
- package/dist/src/storage/i-raw-storage.d.ts +20 -0
- package/dist/src/storage/i-raw-storage.d.ts.map +1 -0
- package/dist/src/storage/i-raw-storage.js +2 -0
- package/dist/src/storage/i-raw-storage.js.map +1 -0
- package/dist/src/storage/memory-storage.d.ts +27 -0
- package/dist/src/storage/memory-storage.d.ts.map +1 -0
- package/dist/src/storage/memory-storage.js +87 -0
- package/dist/src/storage/memory-storage.js.map +1 -0
- package/dist/src/storage/restoration-coordinator-v2.d.ts +63 -0
- package/dist/src/storage/restoration-coordinator-v2.d.ts.map +1 -0
- package/dist/src/storage/restoration-coordinator-v2.js +157 -0
- package/dist/src/storage/restoration-coordinator-v2.js.map +1 -0
- package/dist/src/storage/ring-selector.d.ts +56 -0
- package/dist/src/storage/ring-selector.d.ts.map +1 -0
- package/dist/src/storage/ring-selector.js +118 -0
- package/dist/src/storage/ring-selector.js.map +1 -0
- package/dist/src/storage/storage-monitor.d.ts +23 -0
- package/dist/src/storage/storage-monitor.d.ts.map +1 -0
- package/dist/src/storage/storage-monitor.js +40 -0
- package/dist/src/storage/storage-monitor.js.map +1 -0
- package/dist/src/storage/storage-repo.d.ts +17 -0
- package/dist/src/storage/storage-repo.d.ts.map +1 -0
- package/dist/src/storage/storage-repo.js +267 -0
- package/dist/src/storage/storage-repo.js.map +1 -0
- package/dist/src/storage/struct.d.ts +29 -0
- package/dist/src/storage/struct.d.ts.map +1 -0
- package/dist/src/storage/struct.js +2 -0
- package/dist/src/storage/struct.js.map +1 -0
- package/dist/src/sync/client.d.ts +27 -0
- package/dist/src/sync/client.d.ts.map +1 -0
- package/dist/src/sync/client.js +32 -0
- package/dist/src/sync/client.js.map +1 -0
- package/dist/src/sync/protocol.d.ts +58 -0
- package/dist/src/sync/protocol.d.ts.map +1 -0
- package/dist/src/sync/protocol.js +12 -0
- package/dist/src/sync/protocol.js.map +1 -0
- package/dist/src/sync/service.d.ts +62 -0
- package/dist/src/sync/service.d.ts.map +1 -0
- package/dist/src/sync/service.js +168 -0
- package/dist/src/sync/service.js.map +1 -0
- package/package.json +73 -0
- package/readme.md +497 -0
- package/src/cluster/client.ts +63 -0
- package/src/cluster/cluster-repo.ts +711 -0
- package/src/cluster/partition-detector.ts +158 -0
- package/src/cluster/service.ts +156 -0
- package/src/index.ts +30 -0
- package/src/it-utility.ts +36 -0
- package/src/libp2p-key-network.ts +334 -0
- package/src/libp2p-node.ts +335 -0
- package/src/logger.ts +9 -0
- package/src/network/get-network-manager.ts +17 -0
- package/src/network/network-manager-service.ts +334 -0
- package/src/peer-utils.ts +24 -0
- package/src/protocol-client.ts +54 -0
- package/src/repo/client.ts +112 -0
- package/src/repo/cluster-coordinator.ts +592 -0
- package/src/repo/coordinator-repo.ts +137 -0
- package/src/repo/redirect.ts +17 -0
- package/src/repo/service.ts +219 -0
- package/src/repo/types.ts +7 -0
- package/src/routing/libp2p-known-peers.ts +26 -0
- package/src/routing/responsibility.ts +63 -0
- package/src/routing/simple-cluster-coordinator.ts +70 -0
- package/src/storage/arachnode-fret-adapter.ts +128 -0
- package/src/storage/block-storage.ts +182 -0
- package/src/storage/file-storage.ts +163 -0
- package/src/storage/helpers.ts +29 -0
- package/src/storage/i-block-storage.ts +40 -0
- package/src/storage/i-raw-storage.ts +30 -0
- package/src/storage/memory-storage.ts +108 -0
- package/src/storage/restoration-coordinator-v2.ts +191 -0
- package/src/storage/ring-selector.ts +155 -0
- package/src/storage/storage-monitor.ts +59 -0
- package/src/storage/storage-repo.ts +320 -0
- package/src/storage/struct.ts +34 -0
- package/src/sync/client.ts +42 -0
- package/src/sync/protocol.ts +71 -0
- package/src/sync/service.ts +229 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/storage/helpers.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,WAAW,CAAC,MAAuB;IAC/C,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC;IAEtC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,MAAM,GAAoB,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC;IAE7C,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;QACxC,gEAAgE;QAChE,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;YACxB,SAAS;QACb,CAAC;QACD,iEAAiE;QACjE,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YACtB,0DAA0D;YAC1D,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;gBACzB,IAAI,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;YACxB,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1C,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { IBlock, Transform, ActionId, ActionRev } from "@optimystic/db-core";
|
|
2
|
+
/** Interface for block-level storage operations */
|
|
3
|
+
export interface IBlockStorage {
|
|
4
|
+
/** Gets the latest revision information for this block */
|
|
5
|
+
getLatest(): Promise<ActionRev | undefined>;
|
|
6
|
+
/** Gets a materialized block at the given revision */
|
|
7
|
+
getBlock(rev?: number): Promise<{
|
|
8
|
+
block: IBlock;
|
|
9
|
+
actionRev: ActionRev;
|
|
10
|
+
} | undefined>;
|
|
11
|
+
/** Gets an action by ID */
|
|
12
|
+
getTransaction(actionId: ActionId): Promise<Transform | undefined>;
|
|
13
|
+
/** Gets a pending action by ID */
|
|
14
|
+
getPendingTransaction(actionId: ActionId): Promise<Transform | undefined>;
|
|
15
|
+
/** Lists all pending action IDs */
|
|
16
|
+
listPendingTransactions(): AsyncIterable<ActionId>;
|
|
17
|
+
/** Saves a pending action */
|
|
18
|
+
savePendingTransaction(actionId: ActionId, transform: Transform): Promise<void>;
|
|
19
|
+
/** Deletes a pending action */
|
|
20
|
+
deletePendingTransaction(actionId: ActionId): Promise<void>;
|
|
21
|
+
/** Lists revisions in ascending or descending order between startRev and endRev (inclusive) */
|
|
22
|
+
listRevisions(startRev: number, endRev: number): AsyncIterable<ActionRev>;
|
|
23
|
+
/** Saves a materialized block */
|
|
24
|
+
saveMaterializedBlock(actionId: ActionId, block: IBlock | undefined): Promise<void>;
|
|
25
|
+
/** Saves a revision */
|
|
26
|
+
saveRevision(rev: number, actionId: ActionId): Promise<void>;
|
|
27
|
+
/** Promotes a pending action to committed */
|
|
28
|
+
promotePendingTransaction(actionId: ActionId): Promise<void>;
|
|
29
|
+
/** Sets the latest revision information */
|
|
30
|
+
setLatest(latest: ActionRev): Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=i-block-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-block-storage.d.ts","sourceRoot":"","sources":["../../../src/storage/i-block-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAElF,mDAAmD;AACnD,MAAM,WAAW,aAAa;IAC1B,0DAA0D;IAC1D,SAAS,IAAI,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAE5C,sDAAsD;IACtD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,SAAS,CAAA;KAAE,GAAG,SAAS,CAAC,CAAC;IAErF,2BAA2B;IAC3B,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAEnE,kCAAkC;IAClC,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAE1E,mCAAmC;IACnC,uBAAuB,IAAI,aAAa,CAAC,QAAQ,CAAC,CAAC;IAEnD,6BAA6B;IAC7B,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhF,+BAA+B;IAC/B,wBAAwB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5D,+FAA+F;IAC/F,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IAE1E,iCAAiC;IACjC,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpF,uBAAuB;IACvB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7D,6CAA6C;IAC7C,yBAAyB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7D,2CAA2C;IAC3C,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-block-storage.js","sourceRoot":"","sources":["../../../src/storage/i-block-storage.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { BlockId, ActionId, ActionRev, Transform, IBlock } from "@optimystic/db-core";
|
|
2
|
+
import type { BlockMetadata } from "./struct.js";
|
|
3
|
+
export interface IRawStorage {
|
|
4
|
+
getMetadata(blockId: BlockId): Promise<BlockMetadata | undefined>;
|
|
5
|
+
saveMetadata(blockId: BlockId, metadata: BlockMetadata): Promise<void>;
|
|
6
|
+
getRevision(blockId: BlockId, rev: number): Promise<ActionId | undefined>;
|
|
7
|
+
saveRevision(blockId: BlockId, rev: number, actionId: ActionId): Promise<void>;
|
|
8
|
+
/** List revisions in ascending or descending order, depending on startRev and endRev - startRev and endRev are inclusive */
|
|
9
|
+
listRevisions(blockId: BlockId, startRev: number, endRev: number): AsyncIterable<ActionRev>;
|
|
10
|
+
getPendingTransaction(blockId: BlockId, actionId: ActionId): Promise<Transform | undefined>;
|
|
11
|
+
savePendingTransaction(blockId: BlockId, actionId: ActionId, transform: Transform): Promise<void>;
|
|
12
|
+
deletePendingTransaction(blockId: BlockId, actionId: ActionId): Promise<void>;
|
|
13
|
+
listPendingTransactions(blockId: BlockId): AsyncIterable<ActionId>;
|
|
14
|
+
getTransaction(blockId: BlockId, actionId: ActionId): Promise<Transform | undefined>;
|
|
15
|
+
saveTransaction(blockId: BlockId, actionId: ActionId, transform: Transform): Promise<void>;
|
|
16
|
+
getMaterializedBlock(blockId: BlockId, actionId: ActionId): Promise<IBlock | undefined>;
|
|
17
|
+
saveMaterializedBlock(blockId: BlockId, actionId: ActionId, block?: IBlock): Promise<void>;
|
|
18
|
+
promotePendingTransaction(blockId: BlockId, actionId: ActionId): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=i-raw-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-raw-storage.d.ts","sourceRoot":"","sources":["../../../src/storage/i-raw-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,WAAW;IAE3B,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC;IAClE,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAGvE,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;IAC1E,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,4HAA4H;IAC5H,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IAG5F,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAC5F,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClG,wBAAwB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IAEnE,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IACrF,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAG3F,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACxF,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAG3F,yBAAyB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-raw-storage.js","sourceRoot":"","sources":["../../../src/storage/i-raw-storage.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { BlockId, IBlock, Transform, ActionId, ActionRev } from "@optimystic/db-core";
|
|
2
|
+
import type { BlockMetadata } from "./struct.js";
|
|
3
|
+
import type { IRawStorage } from "./i-raw-storage.js";
|
|
4
|
+
export declare class MemoryRawStorage implements IRawStorage {
|
|
5
|
+
private metadata;
|
|
6
|
+
private revisions;
|
|
7
|
+
private pendingActions;
|
|
8
|
+
private actions;
|
|
9
|
+
private materializedBlocks;
|
|
10
|
+
private getRevisionKey;
|
|
11
|
+
private getActionKey;
|
|
12
|
+
getMetadata(blockId: BlockId): Promise<BlockMetadata | undefined>;
|
|
13
|
+
saveMetadata(blockId: BlockId, metadata: BlockMetadata): Promise<void>;
|
|
14
|
+
getRevision(blockId: BlockId, rev: number): Promise<ActionId | undefined>;
|
|
15
|
+
saveRevision(blockId: BlockId, rev: number, actionId: ActionId): Promise<void>;
|
|
16
|
+
listRevisions(blockId: BlockId, startRev: number, endRev: number): AsyncIterable<ActionRev>;
|
|
17
|
+
getPendingTransaction(blockId: BlockId, actionId: ActionId): Promise<Transform | undefined>;
|
|
18
|
+
savePendingTransaction(blockId: BlockId, actionId: ActionId, transform: Transform): Promise<void>;
|
|
19
|
+
deletePendingTransaction(blockId: BlockId, actionId: ActionId): Promise<void>;
|
|
20
|
+
listPendingTransactions(blockId: BlockId): AsyncIterable<ActionId>;
|
|
21
|
+
getTransaction(blockId: BlockId, actionId: ActionId): Promise<Transform | undefined>;
|
|
22
|
+
saveTransaction(blockId: BlockId, actionId: ActionId, transform: Transform): Promise<void>;
|
|
23
|
+
getMaterializedBlock(blockId: BlockId, actionId: ActionId): Promise<IBlock | undefined>;
|
|
24
|
+
saveMaterializedBlock(blockId: BlockId, actionId: ActionId, block?: IBlock): Promise<void>;
|
|
25
|
+
promotePendingTransaction(blockId: BlockId, actionId: ActionId): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=memory-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-storage.d.ts","sourceRoot":"","sources":["../../../src/storage/memory-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,qBAAa,gBAAiB,YAAW,WAAW;IACnD,OAAO,CAAC,QAAQ,CAAqC;IACrD,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,cAAc,CAAgC;IACtD,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,kBAAkB,CAA6B;IAEvD,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,YAAY;IAId,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IAIjE,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAItE,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IAIzE,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7E,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC;IAsB5F,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAI3F,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjG,wBAAwB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5E,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC;IASnE,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAIpF,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1F,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAIvF,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS1F,yBAAyB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAQpF"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
export class MemoryRawStorage {
|
|
2
|
+
metadata = new Map();
|
|
3
|
+
revisions = new Map(); // blockId:rev -> actionId
|
|
4
|
+
pendingActions = new Map(); // blockId:actionId -> transform
|
|
5
|
+
actions = new Map(); // blockId:actionId -> transform
|
|
6
|
+
materializedBlocks = new Map(); // blockId:actionId -> block
|
|
7
|
+
getRevisionKey(blockId, rev) {
|
|
8
|
+
return `${blockId}:${rev}`;
|
|
9
|
+
}
|
|
10
|
+
getActionKey(blockId, actionId) {
|
|
11
|
+
return `${blockId}:${actionId}`;
|
|
12
|
+
}
|
|
13
|
+
async getMetadata(blockId) {
|
|
14
|
+
return this.metadata.get(blockId);
|
|
15
|
+
}
|
|
16
|
+
async saveMetadata(blockId, metadata) {
|
|
17
|
+
this.metadata.set(blockId, metadata);
|
|
18
|
+
}
|
|
19
|
+
async getRevision(blockId, rev) {
|
|
20
|
+
return this.revisions.get(this.getRevisionKey(blockId, rev));
|
|
21
|
+
}
|
|
22
|
+
async saveRevision(blockId, rev, actionId) {
|
|
23
|
+
this.revisions.set(this.getRevisionKey(blockId, rev), actionId);
|
|
24
|
+
}
|
|
25
|
+
async *listRevisions(blockId, startRev, endRev) {
|
|
26
|
+
const ascending = startRev <= endRev;
|
|
27
|
+
const actualStart = ascending ? startRev : endRev;
|
|
28
|
+
const actualEnd = ascending ? endRev : startRev;
|
|
29
|
+
const results = [];
|
|
30
|
+
for (let rev = actualStart; rev <= actualEnd; rev++) {
|
|
31
|
+
const actionId = this.revisions.get(this.getRevisionKey(blockId, rev));
|
|
32
|
+
if (actionId) {
|
|
33
|
+
results.push({ rev, actionId });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (!ascending) {
|
|
37
|
+
results.reverse();
|
|
38
|
+
}
|
|
39
|
+
for (const result of results) {
|
|
40
|
+
yield result;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async getPendingTransaction(blockId, actionId) {
|
|
44
|
+
return this.pendingActions.get(this.getActionKey(blockId, actionId));
|
|
45
|
+
}
|
|
46
|
+
async savePendingTransaction(blockId, actionId, transform) {
|
|
47
|
+
this.pendingActions.set(this.getActionKey(blockId, actionId), transform);
|
|
48
|
+
}
|
|
49
|
+
async deletePendingTransaction(blockId, actionId) {
|
|
50
|
+
this.pendingActions.delete(this.getActionKey(blockId, actionId));
|
|
51
|
+
}
|
|
52
|
+
async *listPendingTransactions(blockId) {
|
|
53
|
+
const prefix = `${blockId}:`;
|
|
54
|
+
for (const [key] of Array.from(this.pendingActions.entries())) {
|
|
55
|
+
if (key.startsWith(prefix)) {
|
|
56
|
+
yield key.substring(prefix.length);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async getTransaction(blockId, actionId) {
|
|
61
|
+
return this.actions.get(this.getActionKey(blockId, actionId));
|
|
62
|
+
}
|
|
63
|
+
async saveTransaction(blockId, actionId, transform) {
|
|
64
|
+
this.actions.set(this.getActionKey(blockId, actionId), transform);
|
|
65
|
+
}
|
|
66
|
+
async getMaterializedBlock(blockId, actionId) {
|
|
67
|
+
return this.materializedBlocks.get(this.getActionKey(blockId, actionId));
|
|
68
|
+
}
|
|
69
|
+
async saveMaterializedBlock(blockId, actionId, block) {
|
|
70
|
+
const key = this.getActionKey(blockId, actionId);
|
|
71
|
+
if (block) {
|
|
72
|
+
this.materializedBlocks.set(key, block);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
this.materializedBlocks.delete(key);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async promotePendingTransaction(blockId, actionId) {
|
|
79
|
+
const key = this.getActionKey(blockId, actionId);
|
|
80
|
+
const transform = this.pendingActions.get(key);
|
|
81
|
+
if (transform) {
|
|
82
|
+
this.actions.set(key, transform);
|
|
83
|
+
this.pendingActions.delete(key);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=memory-storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-storage.js","sourceRoot":"","sources":["../../../src/storage/memory-storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { BlockId } from '@optimystic/db-core';
|
|
2
|
+
import type { BlockArchive, RestoreCallback } from './struct.js';
|
|
3
|
+
import type { IPeerNetwork } from '@optimystic/db-core';
|
|
4
|
+
import type { ArachnodeFretAdapter } from './arachnode-fret-adapter.js';
|
|
5
|
+
/**
|
|
6
|
+
* Coordinates block restoration across discovered Arachnode storage rings.
|
|
7
|
+
*
|
|
8
|
+
* Queries rings in order of broader coverage (inner rings first):
|
|
9
|
+
* 1. Transaction ring peers (my ring)
|
|
10
|
+
* 2. Inner storage rings (Ring N-1, N-2, ..., Ring 0)
|
|
11
|
+
*
|
|
12
|
+
* Each ring is discovered dynamically via FRET neighbor snapshots.
|
|
13
|
+
*/
|
|
14
|
+
export declare class RestorationCoordinator {
|
|
15
|
+
private readonly fretAdapter;
|
|
16
|
+
private readonly peerNetwork;
|
|
17
|
+
private readonly protocolPrefix;
|
|
18
|
+
private readonly metrics;
|
|
19
|
+
constructor(fretAdapter: ArachnodeFretAdapter, peerNetwork: IPeerNetwork, protocolPrefix: string);
|
|
20
|
+
private readonly log;
|
|
21
|
+
/**
|
|
22
|
+
* Restore a block by querying discovered storage rings.
|
|
23
|
+
*/
|
|
24
|
+
restore(blockId: BlockId, rev?: number): Promise<BlockArchive | undefined>;
|
|
25
|
+
/**
|
|
26
|
+
* Create a RestoreCallback function that uses this coordinator.
|
|
27
|
+
*/
|
|
28
|
+
createRestoreCallback(): RestoreCallback;
|
|
29
|
+
/**
|
|
30
|
+
* Get peers in my transaction ring for a given block.
|
|
31
|
+
*/
|
|
32
|
+
private getMyRingPeers;
|
|
33
|
+
/**
|
|
34
|
+
* Get my own ring depth from Arachnode info.
|
|
35
|
+
*/
|
|
36
|
+
private getMyRingDepth;
|
|
37
|
+
/**
|
|
38
|
+
* Filter peers by partition responsibility.
|
|
39
|
+
*/
|
|
40
|
+
private filterByPartition;
|
|
41
|
+
/**
|
|
42
|
+
* Extract prefix bits from block ID for partition matching.
|
|
43
|
+
*/
|
|
44
|
+
private extractBlockPrefix;
|
|
45
|
+
/**
|
|
46
|
+
* Query a specific peer for a block.
|
|
47
|
+
*/
|
|
48
|
+
private queryPeer;
|
|
49
|
+
/**
|
|
50
|
+
* Record successful restoration from a ring.
|
|
51
|
+
*/
|
|
52
|
+
private recordSuccess;
|
|
53
|
+
/**
|
|
54
|
+
* Get restoration metrics for monitoring.
|
|
55
|
+
*/
|
|
56
|
+
getMetrics(): {
|
|
57
|
+
totalRequests: number;
|
|
58
|
+
successByRing: Map<number, number>;
|
|
59
|
+
failureByRing: Map<number, number>;
|
|
60
|
+
averageDurationMs: number;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=restoration-coordinator-v2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restoration-coordinator-v2.d.ts","sourceRoot":"","sources":["../../../src/storage/restoration-coordinator-v2.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAGnD,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAGxE;;;;;;;;GAQG;AACH,qBAAa,sBAAsB;IASjC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAVhC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAKtB;gBAGgB,WAAW,EAAE,oBAAoB,EACjC,WAAW,EAAE,YAAY,EACzB,cAAc,EAAE,MAAM;IAGxC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAsC;IAE1D;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAsChF;;OAEG;IACH,qBAAqB,IAAI,eAAe;IAMxC;;OAEG;YACW,cAAc;IAM5B;;OAEG;IACH,OAAO,CAAC,cAAc;IAKtB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAczB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAmB1B;;OAEG;YACW,SAAS;IAiBvB;;OAEG;IACH,OAAO,CAAC,aAAa;IAerB;;OAEG;IACH,UAAU,IAAI;QACb,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,iBAAiB,EAAE,MAAM,CAAC;KAC1B;CAGD"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { hashKey } from 'p2p-fret';
|
|
2
|
+
import { peerIdFromString } from '@libp2p/peer-id';
|
|
3
|
+
import { SyncClient } from '../sync/client.js';
|
|
4
|
+
import { createLogger } from '../logger.js';
|
|
5
|
+
/**
|
|
6
|
+
* Coordinates block restoration across discovered Arachnode storage rings.
|
|
7
|
+
*
|
|
8
|
+
* Queries rings in order of broader coverage (inner rings first):
|
|
9
|
+
* 1. Transaction ring peers (my ring)
|
|
10
|
+
* 2. Inner storage rings (Ring N-1, N-2, ..., Ring 0)
|
|
11
|
+
*
|
|
12
|
+
* Each ring is discovered dynamically via FRET neighbor snapshots.
|
|
13
|
+
*/
|
|
14
|
+
export class RestorationCoordinator {
|
|
15
|
+
fretAdapter;
|
|
16
|
+
peerNetwork;
|
|
17
|
+
protocolPrefix;
|
|
18
|
+
metrics = {
|
|
19
|
+
totalRequests: 0,
|
|
20
|
+
successByRing: new Map(),
|
|
21
|
+
failureByRing: new Map(),
|
|
22
|
+
averageDurationMs: 0
|
|
23
|
+
};
|
|
24
|
+
constructor(fretAdapter, peerNetwork, protocolPrefix) {
|
|
25
|
+
this.fretAdapter = fretAdapter;
|
|
26
|
+
this.peerNetwork = peerNetwork;
|
|
27
|
+
this.protocolPrefix = protocolPrefix;
|
|
28
|
+
}
|
|
29
|
+
log = createLogger('storage:restoration');
|
|
30
|
+
/**
|
|
31
|
+
* Restore a block by querying discovered storage rings.
|
|
32
|
+
*/
|
|
33
|
+
async restore(blockId, rev) {
|
|
34
|
+
const startTime = Date.now();
|
|
35
|
+
this.metrics.totalRequests++;
|
|
36
|
+
// 1. Try my transaction ring peers first
|
|
37
|
+
const myPeers = await this.getMyRingPeers(blockId);
|
|
38
|
+
const myRingDepth = this.getMyRingDepth();
|
|
39
|
+
for (const peerId of myPeers) {
|
|
40
|
+
const archive = await this.queryPeer(peerId, blockId, rev);
|
|
41
|
+
if (archive) {
|
|
42
|
+
this.recordSuccess(myRingDepth, blockId, Date.now() - startTime);
|
|
43
|
+
return archive;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// 2. Try inner storage rings (broader coverage)
|
|
47
|
+
for (let ringDepth = myRingDepth - 1; ringDepth >= 0; ringDepth--) {
|
|
48
|
+
const storagePeers = this.fretAdapter.findPeersAtRing(ringDepth);
|
|
49
|
+
// Filter to peers responsible for this block's partition
|
|
50
|
+
const responsiblePeers = this.filterByPartition(storagePeers, blockId, ringDepth);
|
|
51
|
+
for (const peerIdStr of responsiblePeers) {
|
|
52
|
+
const archive = await this.queryPeer(peerIdStr, blockId, rev);
|
|
53
|
+
if (archive) {
|
|
54
|
+
this.recordSuccess(ringDepth, blockId, Date.now() - startTime);
|
|
55
|
+
return archive;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// No ring had the data
|
|
60
|
+
const duration = Date.now() - startTime;
|
|
61
|
+
this.log('restore failed for block %s after %dms', blockId, duration);
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Create a RestoreCallback function that uses this coordinator.
|
|
66
|
+
*/
|
|
67
|
+
createRestoreCallback() {
|
|
68
|
+
return async (blockId, rev) => {
|
|
69
|
+
return await this.restore(blockId, rev);
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get peers in my transaction ring for a given block.
|
|
74
|
+
*/
|
|
75
|
+
async getMyRingPeers(blockId) {
|
|
76
|
+
const blockIdBytes = new TextEncoder().encode(blockId);
|
|
77
|
+
const coord = await hashKey(blockIdBytes);
|
|
78
|
+
return this.fretAdapter.getFret().assembleCohort(coord, 10);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Get my own ring depth from Arachnode info.
|
|
82
|
+
*/
|
|
83
|
+
getMyRingDepth() {
|
|
84
|
+
const myInfo = this.fretAdapter.getMyArachnodeInfo();
|
|
85
|
+
return myInfo?.ringDepth ?? 8; // Default to Ring 8
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Filter peers by partition responsibility.
|
|
89
|
+
*/
|
|
90
|
+
filterByPartition(peers, blockId, ringDepth) {
|
|
91
|
+
if (ringDepth === 0) {
|
|
92
|
+
return peers; // Ring 0 covers all blocks
|
|
93
|
+
}
|
|
94
|
+
const blockPrefix = this.extractBlockPrefix(blockId, ringDepth);
|
|
95
|
+
return peers.filter(peerId => {
|
|
96
|
+
const info = this.fretAdapter.getArachnodeInfo(peerId);
|
|
97
|
+
if (!info || !info.partition)
|
|
98
|
+
return false;
|
|
99
|
+
return info.partition.prefixValue === blockPrefix;
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Extract prefix bits from block ID for partition matching.
|
|
104
|
+
*/
|
|
105
|
+
extractBlockPrefix(blockId, bits) {
|
|
106
|
+
const bytes = new TextEncoder().encode(blockId);
|
|
107
|
+
// Hash the block ID to get uniform distribution
|
|
108
|
+
const hash = new Uint8Array(32);
|
|
109
|
+
for (let i = 0; i < Math.min(bytes.length, hash.length); i++) {
|
|
110
|
+
hash[i] = bytes[i];
|
|
111
|
+
}
|
|
112
|
+
// Extract first N bits
|
|
113
|
+
let value = 0;
|
|
114
|
+
for (let i = 0; i < bits; i++) {
|
|
115
|
+
const byteIndex = Math.floor(i / 8);
|
|
116
|
+
const bitIndex = 7 - (i % 8);
|
|
117
|
+
const bit = (hash[byteIndex] >> bitIndex) & 1;
|
|
118
|
+
value = (value << 1) | bit;
|
|
119
|
+
}
|
|
120
|
+
return value;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Query a specific peer for a block.
|
|
124
|
+
*/
|
|
125
|
+
async queryPeer(peerIdStr, blockId, rev) {
|
|
126
|
+
try {
|
|
127
|
+
const peerId = peerIdFromString(peerIdStr);
|
|
128
|
+
const client = new SyncClient(peerId, this.peerNetwork, this.protocolPrefix);
|
|
129
|
+
const response = await client.requestBlock({ blockId, rev });
|
|
130
|
+
return response.success ? response.archive : undefined;
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
this.log('queryPeer failed for %s - %o', peerIdStr, error);
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Record successful restoration from a ring.
|
|
139
|
+
*/
|
|
140
|
+
recordSuccess(ringDepth, blockId, durationMs) {
|
|
141
|
+
const count = this.metrics.successByRing.get(ringDepth) ?? 0;
|
|
142
|
+
this.metrics.successByRing.set(ringDepth, count + 1);
|
|
143
|
+
// Update rolling average duration
|
|
144
|
+
const totalSuccesses = Array.from(this.metrics.successByRing.values())
|
|
145
|
+
.reduce((sum, c) => sum + c, 0);
|
|
146
|
+
const prevTotal = this.metrics.averageDurationMs * (totalSuccesses - 1);
|
|
147
|
+
this.metrics.averageDurationMs = (prevTotal + durationMs) / totalSuccesses;
|
|
148
|
+
console.log(`[Ring ${ringDepth}] Successfully restored block ${blockId} in ${durationMs}ms`);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Get restoration metrics for monitoring.
|
|
152
|
+
*/
|
|
153
|
+
getMetrics() {
|
|
154
|
+
return { ...this.metrics };
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=restoration-coordinator-v2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restoration-coordinator-v2.js","sourceRoot":"","sources":["../../../src/storage/restoration-coordinator-v2.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAG/C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;;;;;GAQG;AACH,MAAM,OAAO,sBAAsB;IAShB;IACA;IACA;IAVD,OAAO,GAAG;QAC1B,aAAa,EAAE,CAAC;QAChB,aAAa,EAAE,IAAI,GAAG,EAAkB;QACxC,aAAa,EAAE,IAAI,GAAG,EAAkB;QACxC,iBAAiB,EAAE,CAAC;KACpB,CAAC;IAEF,YACkB,WAAiC,EACjC,WAAyB,EACzB,cAAsB;QAFtB,gBAAW,GAAX,WAAW,CAAsB;QACjC,gBAAW,GAAX,WAAW,CAAc;QACzB,mBAAc,GAAd,cAAc,CAAQ;IACrC,CAAC;IAEa,GAAG,GAAG,YAAY,CAAC,qBAAqB,CAAC,CAAA;IAE1D;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,OAAgB,EAAE,GAAY;QAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;QAE7B,yCAAyC;QACzC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QACnD,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAE1C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;YAC3D,IAAI,OAAO,EAAE,CAAC;gBACb,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;gBACjE,OAAO,OAAO,CAAC;YAChB,CAAC;QACF,CAAC;QAED,gDAAgD;QAChD,KAAK,IAAI,SAAS,GAAG,WAAW,GAAG,CAAC,EAAE,SAAS,IAAI,CAAC,EAAE,SAAS,EAAE,EAAE,CAAC;YACnE,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;YAEjE,yDAAyD;YACzD,MAAM,gBAAgB,GAAG,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;YAEnF,KAAK,MAAM,SAAS,IAAI,gBAAgB,EAAE,CAAC;gBACzC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;gBAC9D,IAAI,OAAO,EAAE,CAAC;oBACb,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;oBAC/D,OAAO,OAAO,CAAC;gBAChB,CAAC;YACF,CAAC;QACF,CAAC;QAED,uBAAuB;QACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QACxC,IAAI,CAAC,GAAG,CAAC,wCAAwC,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAA;QACrE,OAAO,SAAS,CAAC;IAClB,CAAC;IAED;;OAEG;IACH,qBAAqB;QACpB,OAAO,KAAK,EAAE,OAAgB,EAAE,GAAY,EAAE,EAAE;YAC/C,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACzC,CAAC,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,cAAc,CAAC,OAAgB;QAC5C,MAAM,YAAY,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,cAAc,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED;;OAEG;IACK,cAAc;QACrB,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,kBAAkB,EAAE,CAAC;QACrD,OAAO,MAAM,EAAE,SAAS,IAAI,CAAC,CAAC,CAAC,oBAAoB;IACpD,CAAC;IAED;;OAEG;IACK,iBAAiB,CAAC,KAAe,EAAE,OAAgB,EAAE,SAAiB;QAC7E,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,KAAK,CAAC,CAAC,2BAA2B;QAC1C,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAEhE,OAAO,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;YAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;YACvD,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS;gBAAE,OAAO,KAAK,CAAC;YAC3C,OAAO,IAAI,CAAC,SAAS,CAAC,WAAW,KAAK,WAAW,CAAC;QACnD,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,kBAAkB,CAAC,OAAgB,EAAE,IAAY;QACxD,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAChD,gDAAgD;QAChD,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;QAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9D,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACrB,CAAC;QAED,uBAAuB;QACvB,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACpC,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC7B,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,SAAS,CAAE,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC/C,KAAK,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC;QAC5B,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,SAAS,CAAC,SAAiB,EAAE,OAAgB,EAAE,GAAY;QACxE,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;YAC3C,MAAM,MAAM,GAAG,IAAI,UAAU,CAC5B,MAAM,EACN,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,cAAc,CACnB,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;YAC7D,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;QACxD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,GAAG,CAAC,8BAA8B,EAAE,SAAS,EAAE,KAAK,CAAC,CAAA;YAC1D,OAAO,SAAS,CAAC;QAClB,CAAC;IACF,CAAC;IAED;;OAEG;IACK,aAAa,CAAC,SAAiB,EAAE,OAAgB,EAAE,UAAkB;QAC5E,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC7D,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;QAErD,kCAAkC;QAClC,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;aACpE,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACjC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,GAAG,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC;QACxE,IAAI,CAAC,OAAO,CAAC,iBAAiB,GAAG,CAAC,SAAS,GAAG,UAAU,CAAC,GAAG,cAAc,CAAC;QAE3E,OAAO,CAAC,GAAG,CACV,SAAS,SAAS,iCAAiC,OAAO,OAAO,UAAU,IAAI,CAC/E,CAAC;IACH,CAAC;IAED;;OAEG;IACH,UAAU;QAMT,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;IAC5B,CAAC;CACD"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { StorageMonitor } from './storage-monitor.js';
|
|
2
|
+
import type { ArachnodeInfo, ArachnodeFretAdapter } from './arachnode-fret-adapter.js';
|
|
3
|
+
export interface RingSelectorConfig {
|
|
4
|
+
/** Minimum storage capacity in bytes */
|
|
5
|
+
minCapacity: number;
|
|
6
|
+
/** Thresholds for ring transitions */
|
|
7
|
+
thresholds: {
|
|
8
|
+
/** Move to outer ring when used > this % */
|
|
9
|
+
moveOut: number;
|
|
10
|
+
/** Move to inner ring when used < this % */
|
|
11
|
+
moveIn: number;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Determines appropriate ring depth based on storage capacity and network demand.
|
|
16
|
+
*
|
|
17
|
+
* Ring depth represents keyspace partitioning:
|
|
18
|
+
* - Ring 0: Full keyspace (1 partition)
|
|
19
|
+
* - Ring N: 2^N partitions
|
|
20
|
+
*
|
|
21
|
+
* A node selects its ring based on: available_capacity / estimated_neighborhood_demand
|
|
22
|
+
*/
|
|
23
|
+
export declare class RingSelector {
|
|
24
|
+
private readonly fretAdapter;
|
|
25
|
+
private readonly storageMonitor;
|
|
26
|
+
private readonly config;
|
|
27
|
+
constructor(fretAdapter: ArachnodeFretAdapter, storageMonitor: StorageMonitor, config: RingSelectorConfig);
|
|
28
|
+
/**
|
|
29
|
+
* Determine appropriate ring depth based on capacity and demand.
|
|
30
|
+
*/
|
|
31
|
+
determineRing(): Promise<number>;
|
|
32
|
+
/**
|
|
33
|
+
* Calculate partition for a given ring depth and peer ID.
|
|
34
|
+
*/
|
|
35
|
+
calculatePartition(ringDepth: number, peerId: string): Promise<{
|
|
36
|
+
prefixBits: number;
|
|
37
|
+
prefixValue: number;
|
|
38
|
+
} | undefined>;
|
|
39
|
+
/**
|
|
40
|
+
* Create Arachnode info for this node.
|
|
41
|
+
*/
|
|
42
|
+
createArachnodeInfo(peerId: string): Promise<ArachnodeInfo>;
|
|
43
|
+
/**
|
|
44
|
+
* Monitor capacity and determine if ring transition is needed.
|
|
45
|
+
*/
|
|
46
|
+
shouldTransition(): Promise<{
|
|
47
|
+
shouldMove: boolean;
|
|
48
|
+
direction?: 'in' | 'out';
|
|
49
|
+
newRingDepth?: number;
|
|
50
|
+
}>;
|
|
51
|
+
/**
|
|
52
|
+
* Extract first N bits from byte array as a number.
|
|
53
|
+
*/
|
|
54
|
+
private extractPrefix;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=ring-selector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ring-selector.d.ts","sourceRoot":"","sources":["../../../src/storage/ring-selector.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAEvF,MAAM,WAAW,kBAAkB;IAClC,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;IAEpB,sCAAsC;IACtC,UAAU,EAAE;QACX,4CAA4C;QAC5C,OAAO,EAAE,MAAM,CAAC;QAChB,4CAA4C;QAC5C,MAAM,EAAE,MAAM,CAAC;KACf,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,qBAAa,YAAY;IAEvB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAFN,WAAW,EAAE,oBAAoB,EACjC,cAAc,EAAE,cAAc,EAC9B,MAAM,EAAE,kBAAkB;IAG5C;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAyBtC;;OAEG;IACG,kBAAkB,CACvB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IAenE;;OAEG;IACG,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAmBjE;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC;QACjC,UAAU,EAAE,OAAO,CAAC;QACpB,SAAS,CAAC,EAAE,IAAI,GAAG,KAAK,CAAC;QACzB,YAAY,CAAC,EAAE,MAAM,CAAA;KACrB,CAAC;IA6BF;;OAEG;IACH,OAAO,CAAC,aAAa;CAUrB"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { hashPeerId } from 'p2p-fret';
|
|
2
|
+
/**
|
|
3
|
+
* Determines appropriate ring depth based on storage capacity and network demand.
|
|
4
|
+
*
|
|
5
|
+
* Ring depth represents keyspace partitioning:
|
|
6
|
+
* - Ring 0: Full keyspace (1 partition)
|
|
7
|
+
* - Ring N: 2^N partitions
|
|
8
|
+
*
|
|
9
|
+
* A node selects its ring based on: available_capacity / estimated_neighborhood_demand
|
|
10
|
+
*/
|
|
11
|
+
export class RingSelector {
|
|
12
|
+
fretAdapter;
|
|
13
|
+
storageMonitor;
|
|
14
|
+
config;
|
|
15
|
+
constructor(fretAdapter, storageMonitor, config) {
|
|
16
|
+
this.fretAdapter = fretAdapter;
|
|
17
|
+
this.storageMonitor = storageMonitor;
|
|
18
|
+
this.config = config;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Determine appropriate ring depth based on capacity and demand.
|
|
22
|
+
*/
|
|
23
|
+
async determineRing() {
|
|
24
|
+
const capacity = await this.storageMonitor.getCapacity();
|
|
25
|
+
if (capacity.available < this.config.minCapacity) {
|
|
26
|
+
// Not enough capacity for any ring
|
|
27
|
+
return -1;
|
|
28
|
+
}
|
|
29
|
+
// Estimate total network size from FRET
|
|
30
|
+
// We use a simple heuristic: assume average block size and typical data distribution
|
|
31
|
+
const avgBlockSize = 100 * 1024; // 100KB typical block
|
|
32
|
+
const estimatedTotalBlocks = 1000; // Conservative estimate
|
|
33
|
+
const estimatedTotalData = estimatedTotalBlocks * avgBlockSize;
|
|
34
|
+
// Calculate what fraction of keyspace we can cover
|
|
35
|
+
const coverage = capacity.available / estimatedTotalData;
|
|
36
|
+
// Ring depth: 0 = full keyspace, N = 2^N partitions
|
|
37
|
+
// If coverage = 0.01 (1%), we need ~100 partitions ≈ Ring 7
|
|
38
|
+
// If coverage = 1.0 (100%), we can handle full keyspace = Ring 0
|
|
39
|
+
const ringDepth = Math.max(0, Math.ceil(-Math.log2(Math.max(0.001, coverage))));
|
|
40
|
+
return Math.min(ringDepth, 16); // Cap at Ring 16 (65536 partitions)
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Calculate partition for a given ring depth and peer ID.
|
|
44
|
+
*/
|
|
45
|
+
async calculatePartition(ringDepth, peerId) {
|
|
46
|
+
if (ringDepth === 0) {
|
|
47
|
+
return undefined; // Full keyspace, no partition
|
|
48
|
+
}
|
|
49
|
+
// Hash peer ID to get coordinate
|
|
50
|
+
const coord = await hashPeerId({ toString: () => peerId });
|
|
51
|
+
// Extract prefix bits from coordinate
|
|
52
|
+
const prefixBits = ringDepth;
|
|
53
|
+
const prefixValue = this.extractPrefix(coord, prefixBits);
|
|
54
|
+
return { prefixBits, prefixValue };
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Create Arachnode info for this node.
|
|
58
|
+
*/
|
|
59
|
+
async createArachnodeInfo(peerId) {
|
|
60
|
+
const capacity = await this.storageMonitor.getCapacity();
|
|
61
|
+
const ringDepth = await this.determineRing();
|
|
62
|
+
const partition = ringDepth >= 0
|
|
63
|
+
? await this.calculatePartition(ringDepth, peerId)
|
|
64
|
+
: undefined;
|
|
65
|
+
return {
|
|
66
|
+
ringDepth: Math.max(0, ringDepth),
|
|
67
|
+
partition,
|
|
68
|
+
capacity: {
|
|
69
|
+
total: capacity.total,
|
|
70
|
+
used: capacity.used,
|
|
71
|
+
available: capacity.available
|
|
72
|
+
},
|
|
73
|
+
status: 'active'
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Monitor capacity and determine if ring transition is needed.
|
|
78
|
+
*/
|
|
79
|
+
async shouldTransition() {
|
|
80
|
+
const capacity = await this.storageMonitor.getCapacity();
|
|
81
|
+
const usedPercent = capacity.used / capacity.total;
|
|
82
|
+
if (usedPercent > this.config.thresholds.moveOut) {
|
|
83
|
+
// Move to outer ring (more granular partition)
|
|
84
|
+
const currentRingDepth = await this.determineRing();
|
|
85
|
+
return {
|
|
86
|
+
shouldMove: true,
|
|
87
|
+
direction: 'out',
|
|
88
|
+
newRingDepth: currentRingDepth + 1
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
if (usedPercent < this.config.thresholds.moveIn) {
|
|
92
|
+
// Move to inner ring (broader coverage)
|
|
93
|
+
const currentRingDepth = await this.determineRing();
|
|
94
|
+
if (currentRingDepth > 0) {
|
|
95
|
+
return {
|
|
96
|
+
shouldMove: true,
|
|
97
|
+
direction: 'in',
|
|
98
|
+
newRingDepth: currentRingDepth - 1
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return { shouldMove: false };
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Extract first N bits from byte array as a number.
|
|
106
|
+
*/
|
|
107
|
+
extractPrefix(bytes, bits) {
|
|
108
|
+
let value = 0;
|
|
109
|
+
for (let i = 0; i < bits; i++) {
|
|
110
|
+
const byteIndex = Math.floor(i / 8);
|
|
111
|
+
const bitIndex = 7 - (i % 8);
|
|
112
|
+
const bit = (bytes[byteIndex] >> bitIndex) & 1;
|
|
113
|
+
value = (value << 1) | bit;
|
|
114
|
+
}
|
|
115
|
+
return value;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=ring-selector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ring-selector.js","sourceRoot":"","sources":["../../../src/storage/ring-selector.ts"],"names":[],"mappings":"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"}
|