83 lines
2.3 KiB
TypeScript
83 lines
2.3 KiB
TypeScript
import { KVStore } from "../../plugos/lib/kv_store.ts";
|
|
import type { SysCallMapping } from "../../plugos/system.ts";
|
|
|
|
export type KV = {
|
|
key: string;
|
|
value: any;
|
|
};
|
|
|
|
// Keyspace:
|
|
// ["index", page, key] -> value
|
|
// ["indexByKey", key, page] -> value
|
|
|
|
const sep = "!";
|
|
|
|
/**
|
|
* Implements the index syscalls using Deno's KV store.
|
|
* @param dbFile
|
|
* @returns
|
|
*/
|
|
export function pageIndexSyscalls(kv: KVStore): SysCallMapping {
|
|
const apiObj: SysCallMapping = {
|
|
"index.set": (_ctx, page: string, key: string, value: any) => {
|
|
return kv.batchSet(
|
|
[{
|
|
key: `index${sep}${page}${sep}${key}`,
|
|
value,
|
|
}, {
|
|
key: `indexByKey${sep}${key}${sep}${page}`,
|
|
value,
|
|
}],
|
|
);
|
|
},
|
|
"index.batchSet": async (_ctx, page: string, kvs: KV[]) => {
|
|
for (const { key, value } of kvs) {
|
|
await apiObj["index.set"](_ctx, page, key, value);
|
|
}
|
|
},
|
|
"index.delete": (_ctx, page: string, key: string) => {
|
|
return kv.batchDelete([
|
|
`index${sep}${page}${sep}${key}`,
|
|
`indexByKey${sep}${key}${sep}${page}`,
|
|
]);
|
|
},
|
|
"index.get": (_ctx, page: string, key: string) => {
|
|
return kv.get(`index${sep}${page}${sep}${key}`);
|
|
},
|
|
"index.queryPrefix": async (_ctx, prefix: string) => {
|
|
const results: { key: string; page: string; value: any }[] = [];
|
|
for (
|
|
const result of await kv.queryPrefix(`indexByKey!${prefix}`)
|
|
) {
|
|
const [_ns, key, page] = result.key.split(sep);
|
|
results.push({
|
|
key,
|
|
page,
|
|
value: result.value,
|
|
});
|
|
}
|
|
return results;
|
|
},
|
|
"index.clearPageIndexForPage": async (ctx, page: string) => {
|
|
await apiObj["index.deletePrefixForPage"](ctx, page, "");
|
|
},
|
|
"index.deletePrefixForPage": async (_ctx, page: string, prefix: string) => {
|
|
for (
|
|
const result of await kv.queryPrefix(
|
|
`index${sep}${page}${sep}${prefix}`,
|
|
)
|
|
) {
|
|
const [_ns, page, key] = result.key.split(sep);
|
|
await apiObj["index.delete"](_ctx, page, key);
|
|
}
|
|
},
|
|
"index.clearPageIndex": async (ctx) => {
|
|
for (const result of await kv.queryPrefix(`index${sep}`)) {
|
|
const [_ns, page, key] = result.key.split(sep);
|
|
await apiObj["index.delete"](ctx, page, key);
|
|
}
|
|
},
|
|
};
|
|
return apiObj;
|
|
}
|