UNPKG

hypercore-storage

Version:

Storage engine for Hypercore

151 lines (116 loc) 4.75 kB
const b4a = require('b4a') const BlockDependencyStream = require('./block-dependency-stream.js') const { core, store } = require('./keys.js') const schema = require('../spec/hyperschema') const CORESTORE_CORE = schema.getEncoding('@corestore/core') const CORE_TREE_NODE = schema.getEncoding('@core/tree-node') const EMPTY = b4a.alloc(0) module.exports = { createBlockStream, createBitfieldStream, createUserDataStream, createCoreStream, createAliasStream, createDiscoveryKeyStream, createTreeNodeStream, createLocalStream } function createCoreStream (db, view) { const start = store.coreStart() const end = store.coreEnd() const ite = view.iterator(db, start, end, false) ite._readableState.map = mapCore return ite } function createDiscoveryKeyStream (db, view, namespace) { const start = namespace ? store.coreByAliasStart(namespace) : store.coreStart() const end = namespace ? store.coreByAliasEnd(namespace) : store.coreEnd() const ite = view.iterator(db, start, end, false) ite._readableState.map = namespace ? mapNamespaceDiscoveryKeys : mapAllDiscoveryKeys return ite } function createAliasStream (db, view, namespace) { const start = store.coreByAliasStart(namespace) const end = store.coreByAliasEnd(namespace) const ite = view.iterator(db, start, end, false) ite._readableState.map = mapAlias return ite } function createBlockIterator (ptr, db, view, start, end, reverse) { if (ptr.dependencies.length > 0) { return new BlockDependencyStream(ptr, db, view, start, end, reverse) } const s = core.block(ptr.dataPointer, start) const e = core.block(ptr.dataPointer, end === -1 ? Infinity : end) return view.iterator(db, s, e, reverse) } function createBlockStream (ptr, db, view, { gt = -1, gte = gt + 1, lte = -1, lt = lte === -1 ? -1 : lte + 1, reverse = false } = {}) { const ite = createBlockIterator(ptr, db, view, gte, lt, reverse) ite._readableState.map = mapBlock return ite } function createBitfieldStream (ptr, db, view, { gt = -1, gte = gt + 1, lte = -1, lt = lte === -1 ? -1 : lte + 1, reverse = false } = {}) { const s = core.bitfield(ptr.dataPointer, gte, 0) const e = core.bitfield(ptr.dataPointer, lt === -1 ? Infinity : lt, 0) const ite = view.iterator(db, s, e, false) ite._readableState.map = mapBitfield return ite } // NOTE: this does not do dependency lookups atm function createTreeNodeStream (ptr, db, view, { gt = -1, gte = gt + 1, lte = -1, lt = lte === -1 ? -1 : lte + 1, reverse = false } = {}) { const s = core.tree(ptr.dataPointer, gte, 0) const e = core.tree(ptr.dataPointer, lt === -1 ? Infinity : lt, 0) const ite = view.iterator(db, s, e, false) ite._readableState.map = mapTreeNode return ite } function createUserDataStream (ptr, db, view, { gt = null, gte = '', lte = null, lt = null, reverse = false } = {}) { if (gt !== null || lte !== null) throw new Error('gt and lte not yet supported for user data streams') const s = core.userData(ptr.dataPointer, gte) const e = lt === null ? core.userDataEnd(ptr.dataPointer) : core.userData(ptr.dataPointer, lt) const ite = view.iterator(db, s, e, false) ite._readableState.map = mapUserData return ite } function createLocalStream (ptr, db, view, { gt = null, gte = EMPTY, lte = null, lt = null, reverse = false } = {}) { if (gt !== null || lte !== null) throw new Error('gt and lte not yet supported for local streams') const s = core.local(ptr.dataPointer, gte) const e = lt === null ? core.localEnd(ptr.dataPointer) : core.local(ptr.dataPointer, lt) const ite = view.iterator(db, s, e, false) ite._readableState.map = mapLocal return ite } function mapBitfield (data) { const [index, type] = core.bitfieldIndexAndType(data.key) if (type !== 0) return null // ignore for now return { index, page: data.value } } function mapLocal (data) { const key = core.localKey(data.key) return { key, value: data.value } } function mapUserData (data) { const key = core.userDataKey(data.key) return { key, value: data.value } } function mapCore (data) { const discoveryKey = store.discoveryKey(data.key) const core = CORESTORE_CORE.decode({ start: 0, end: data.value.byteLength, buffer: data.value }) return { discoveryKey, core } } function mapAllDiscoveryKeys (data) { return store.discoveryKey(data.key) } function mapNamespaceDiscoveryKeys (data) { return data.value } function mapAlias (data) { const alias = store.alias(data.key) return { alias, discoveryKey: data.value } } function mapBlock (data) { return { index: core.blockIndex(data.key), value: data.value } } function mapTreeNode (data) { return CORE_TREE_NODE.decode({ start: 0, end: data.value.byteLength, buffer: data.value }) }