Skip to content

Commit

Permalink
feat: filter entries with keys greater than this string (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
Alan Shaw authored Mar 19, 2024
1 parent 9f32fb0 commit 444ccd7
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 6 deletions.
37 changes: 31 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,13 @@ export const del = async (blocks, root, key) => {
* @param {API.BlockFetcher} blocks Bucket block storage.
* @param {API.ShardLink} root CID of the root node of the bucket.
* @param {object} [options]
* @param {string} [options.prefix]
* @param {string} [options.prefix] Filter results to entries with keys prefixed with this string.
* @param {string} [options.gt] Filter results to entries with keys greater than this string.
* @param {string} [options.gte] Filter results to entries with keys greater than or equal to this string.
* @returns {AsyncIterableIterator<API.ShardValueEntry>}
*/
export const entries = async function * (blocks, root, options = {}) {
const { prefix } = options
const { prefix, gt, gte } = options
const shards = new ShardFetcher(blocks)
const rshard = await shards.get(root)

Expand All @@ -238,7 +240,12 @@ export const entries = async function * (blocks, root, options = {}) {

if (Array.isArray(entry[1])) {
if (entry[1][1]) {
if (!prefix || (prefix && key.startsWith(prefix))) {
if (
(prefix && key.startsWith(prefix)) ||
(gt && key > gt) ||
(gte && key >= gte) ||
(!prefix && !gt && !gte)
) {
yield [key, entry[1][1]]
}
}
Expand All @@ -250,13 +257,31 @@ export const entries = async function * (blocks, root, options = {}) {
if (prefix.length > key.length && !prefix.startsWith(key)) {
continue
}
} else if (gt) {
if (gt.length <= key.length && !key.startsWith(gt)) {
continue
}
if (gt.length > key.length && !gt.startsWith(key)) {
continue
}
} else if (gte) {
if (gte.length <= key.length && !key.startsWith(gte)) {
continue
}
if (gte.length > key.length && !gte.startsWith(key)) {
continue
}
}
yield * ents(await shards.get(entry[1][0], key))
} else {
if (prefix && !key.startsWith(prefix)) {
continue
if (
(prefix && key.startsWith(prefix)) ||
(gt && key > gt) ||
(gte && key >= gte) ||
(!prefix && !gt && !gte)
) {
yield [key, entry[1]]
}
yield [key, entry[1]]
}
}
}
Expand Down
68 changes: 68 additions & 0 deletions test/entries.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,72 @@ describe('entries', () => {
assert.equal(results[i][0], key)
}
})

it('lists entries by key greater than string', async () => {
const empty = await ShardBlock.create()
const blocks = new Blockstore()
await blocks.put(empty.cid, empty.bytes)

/** @type {Array<[string, API.UnknownLink]>} */
const testdata = [
['cccc', await randomCID(32)],
['deee', await randomCID(32)],
['dooo', await randomCID(32)],
['beee', await randomCID(32)]
]

/** @type {API.ShardLink} */
let root = empty.cid
for (const [k, v] of testdata) {
const res = await put(blocks, root, k, v)
for (const b of res.additions) {
await blocks.put(b.cid, b.bytes)
}
root = res.root
}

const gt = 'beee'
const results = []
for await (const entry of entries(blocks, root, { gt })) {
results.push(entry)
}

for (const [i, key] of testdata.map(d => d[0]).filter(k => k > gt).sort().entries()) {
assert.equal(results[i][0], key)
}
})

it('lists entries by key greater than or equal to string', async () => {
const empty = await ShardBlock.create()
const blocks = new Blockstore()
await blocks.put(empty.cid, empty.bytes)

/** @type {Array<[string, API.UnknownLink]>} */
const testdata = [
['cccc', await randomCID(32)],
['deee', await randomCID(32)],
['dooo', await randomCID(32)],
['beee', await randomCID(32)]
]

/** @type {API.ShardLink} */
let root = empty.cid
for (const [k, v] of testdata) {
const res = await put(blocks, root, k, v)
for (const b of res.additions) {
await blocks.put(b.cid, b.bytes)
}
root = res.root
}

const gte = 'beee'
const results = []
for await (const entry of entries(blocks, root, { gte })) {
results.push(entry)
}

for (const [i, key] of testdata.map(d => d[0]).filter(k => k >= gte).sort().entries()) {
assert.equal(results[i][0], key)
}
})
})

0 comments on commit 444ccd7

Please sign in to comment.