blockstore-core
Version:
Contains various implementations of the API contract described in interface-blockstore
79 lines • 2.38 kB
JavaScript
import { logger } from '@libp2p/logger';
import { NotFoundError } from 'interface-store';
import filter from 'it-filter';
import merge from 'it-merge';
import { BaseBlockstore } from './base.js';
const log = logger('blockstore:core:tiered');
/**
* A blockstore that can combine multiple stores. Puts and deletes
* will write through to all blockstores. Has and get will
* try each store sequentially. getAll will use every store but also
* deduplicate any yielded pairs.
*/
export class TieredBlockstore extends BaseBlockstore {
stores;
constructor(stores) {
super();
this.stores = stores.slice();
}
async put(key, value, options) {
await Promise.all(this.stores.map(async (store) => {
await store.put(key, value, options);
}));
return key;
}
async get(key, options) {
let error;
for (const store of this.stores) {
try {
const res = await store.get(key, options);
if (res != null) {
return res;
}
}
catch (err) {
error = err;
log.error(err);
}
}
throw error ?? new NotFoundError();
}
async has(key, options) {
for (const s of this.stores) {
if (await s.has(key, options)) {
return true;
}
}
return false;
}
async delete(key, options) {
await Promise.all(this.stores.map(async (store) => {
await store.delete(key, options);
}));
}
async *putMany(source, options = {}) {
for await (const pair of source) {
await this.put(pair.cid, pair.block, options);
yield pair.cid;
}
}
async *deleteMany(source, options = {}) {
for await (const cid of source) {
await this.delete(cid, options);
yield cid;
}
}
async *getAll(options) {
// deduplicate yielded pairs
const seen = new Set();
yield* filter(merge(...this.stores.map(s => s.getAll(options))), (pair) => {
const cidStr = pair.cid.toString();
if (seen.has(cidStr)) {
return false;
}
seen.add(cidStr);
return true;
});
}
}
//# sourceMappingURL=tiered.js.map