Skip to content

Commit

Permalink
feat: adjust way count works for uniqueCount
Browse files Browse the repository at this point in the history
  • Loading branch information
kitsonk committed Oct 3, 2023
1 parent dbc87f6 commit 2b32547
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 9 deletions.
6 changes: 4 additions & 2 deletions keys.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,17 @@ Deno.test({
.set(["a", "b"], "b")
.set(["a", "b", "c"], "c")
.set(["a", "d", "f", "g"], "g")
.set(["a", "h"], "h")
.set(["e"], "e")
.commit();
assert(res.ok);

const actual = await uniqueCount(kv, ["a"]);

assertEquals(actual, [
{ key: ["a", "b"], count: 2 },
{ key: ["a", "b"], count: 1 },
{ key: ["a", "d"], count: 1 },
{ key: ["a", "h"], count: 0 },
]);
return teardown();
},
Expand All @@ -103,7 +105,7 @@ Deno.test({
const actual = await uniqueCount(kv, ["a"]);

assertEquals(actual, [
{ key: ["a", new Uint8Array([2, 3, 4])], count: 2 },
{ key: ["a", new Uint8Array([2, 3, 4])], count: 1 },
{ key: ["a", new Uint8Array([4, 5, 6])], count: 1 },
]);
return teardown();
Expand Down
25 changes: 18 additions & 7 deletions keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,18 @@ function addIfUnique(set: Set<Deno.KvKeyPart>, item: Uint8Array) {
set.add(item);
}

function addOrIncrement(map: Map<Deno.KvKeyPart, number>, item: Uint8Array) {
function addOrIncrement(
map: Map<Deno.KvKeyPart, number>,
item: Uint8Array,
increment: boolean,
) {
for (const [k, v] of map) {
if (ArrayBuffer.isView(k) && timingSafeEqual(k, item)) {
map.set(k, v + 1);
map.set(k, increment ? v + 1 : v);
return;
}
}
map.set(item, 1);
map.set(item, increment ? 1 : 0);
}

/** Return an array of keys that match the `selector` in the target `kv`
Expand Down Expand Up @@ -97,7 +101,9 @@ export async function unique(
}

/** Resolves with an array of unique sub keys/prefixes for the provided prefix
* along with the number of sub keys that match that prefix.
* along with the number of sub keys that match that prefix. The `count`
* represents the number of sub keys, a value of `0` indicates that only the
* exact key exists with no sub keys.
*
* This is useful when storing keys and values in a hierarchical/tree view,
* where you are retrieving a list including counts and you want to know all the
Expand All @@ -119,7 +125,7 @@ export async function unique(
*
* const kv = await Deno.openKv();
* console.log(await uniqueCount(kv, ["a"]));
* // { key: ["a", "b"], count: 2 }
* // { key: ["a", "b"], count: 1 }
* // { key: ["a", "d"], count: 2 }
* await kv.close();
* ```
Expand All @@ -140,9 +146,14 @@ export async function uniqueCount(
}
const part = key[prefixLength];
if (ArrayBuffer.isView(part)) {
addOrIncrement(prefixCounts, part);
addOrIncrement(prefixCounts, part, key.length > (prefixLength + 1));
} else {
prefixCounts.set(part, (prefixCounts.get(part) ?? 0) + 1);
if (!prefixCounts.has(part)) {
prefixCounts.set(part, 0);
}
if (key.length > (prefixLength + 1)) {
prefixCounts.set(part, prefixCounts.get(part)! + 1);
}
}
}
return [...prefixCounts].map(([part, count]) => ({
Expand Down

0 comments on commit 2b32547

Please sign in to comment.