UNPKG

datastore-core

Version:
108 lines 3.43 kB
import { Key } from 'interface-datastore'; import { OpenFailedError } from 'interface-store'; import { BaseDatastore } from './base.js'; import { KeyTransformDatastore } from './keytransform.js'; import { readShardFun, SHARDING_FN } from './shard.js'; const shardKey = new Key(SHARDING_FN); /** * Backend independent abstraction of go-ds-flatfs. * * Wraps another datastore such that all values are stored * sharded according to the given sharding function. */ export class ShardingDatastore extends BaseDatastore { child; shard; constructor(store, shard) { super(); this.child = new KeyTransformDatastore(store, { convert: this._convertKey.bind(this), invert: this._invertKey.bind(this) }); this.shard = shard; } async open() { this.shard = await ShardingDatastore.create(this.child, this.shard); } _convertKey(key) { const s = key.toString(); if (s === shardKey.toString()) { return key; } const parent = new Key(this.shard.fun(s)); return parent.child(key); } _invertKey(key) { const s = key.toString(); if (s === shardKey.toString()) { return key; } return Key.withNamespaces(key.list().slice(1)); } static async create(store, shard) { const hasShard = await store.has(shardKey); if (!hasShard) { if (shard == null) { throw new OpenFailedError('Shard is required when datastore doesn\'t have a shard key already'); } await store.put(shardKey, new TextEncoder().encode(shard.toString() + '\n')); } if (shard == null) { shard = await readShardFun('/', store); } // test shards const diskShard = await readShardFun('/', store); const a = diskShard.toString(); const b = shard.toString(); if (a !== b) { throw new Error(`specified fun ${b} does not match repo shard fun ${a}`); } return diskShard; } async put(key, val, options) { await this.child.put(key, val, options); return key; } async get(key, options) { return this.child.get(key, options); } async has(key, options) { return this.child.has(key, options); } async delete(key, options) { await this.child.delete(key, options); } async *putMany(source, options = {}) { yield* this.child.putMany(source, options); } async *getMany(source, options = {}) { yield* this.child.getMany(source, options); } async *deleteMany(source, options = {}) { yield* this.child.deleteMany(source, options); } batch() { return this.child.batch(); } query(q, options) { const omitShard = ({ key }) => key.toString() !== shardKey.toString(); const tq = { ...q, filters: [ omitShard ].concat(q.filters ?? []) }; return this.child.query(tq, options); } queryKeys(q, options) { const omitShard = (key) => key.toString() !== shardKey.toString(); const tq = { ...q, filters: [ omitShard ].concat(q.filters ?? []) }; return this.child.queryKeys(tq, options); } } //# sourceMappingURL=sharding.js.map