diff --git a/common/src/user-store/branch.ts b/common/src/user-store/branch.ts index 6417e4d9..674a2532 100644 --- a/common/src/user-store/branch.ts +++ b/common/src/user-store/branch.ts @@ -42,9 +42,9 @@ export class Branch { } async getCurrTable(): Promise<SSTable | null> { - const key = this.keys()[0] - if (key === undefined) return null - return this.getTable(key) + const name = this.tableNames()[0] + if (name === undefined) return null + return this.getTable(name) } async getTable(name: Timestamp): Promise<SSTable | null> { @@ -55,9 +55,9 @@ export class Branch { } async findTableForId(id: Timestamp): Promise<SSTable | null> { - const key = this.keys().find(k => id.compare(k) >= 0) - if (!key) return null - return this.getTable(key) + const name = this.tableNames().find(n => id.compare(n) >= 0) + if (!name) return null + return this.getTable(name) } async updateRoot(): Promise<void> { @@ -65,14 +65,14 @@ export class Branch { } async compressTables(): Promise<void> { - const keys = this.keys() - if (keys.length < 1) return - const mostRecent = await this.getTable(keys[0]) + const tableNames = this.tableNames() + if (tableNames.length < 1) return + const mostRecent = await this.getTable(tableNames[0]) if (mostRecent === null) return - const compressed = await this.compressCascade(mostRecent, keys.slice(1)) + const compressed = await this.compressCascade(mostRecent, tableNames.slice(1)) const tableName = compressed.oldestId() - if (tableName && tableName.compare(keys[0]) !== 0 ) { - delete this.data[keys[0].toString()] + if (tableName && tableName.compare(tableNames[0]) !== 0 ) { + delete this.data[tableNames[0].toString()] this.data[tableName.toString()] = compressed.cid } await this.updateRoot() @@ -87,7 +87,7 @@ export class Branch { const filtered = tables.filter(t => t?.size === size) as SSTable[] // need 4 tables to merge down a level if (filtered.length < 3 || size === TableSize.xl) { - // if no merge at this level, we just write the previous level & bail + // if no merge at this level, we just return the p;revious level return mostRecent } @@ -122,8 +122,10 @@ export class Branch { return table.removeEntry(id) } - keys(): Timestamp[] { - return Object.keys(this.data).sort().reverse().map(k => Timestamp.parse(k)) + tableNames(newestFirst = false): Timestamp[] { + const sorted = Object.keys(this.data).sort() + const ordered= newestFirst ? sorted : sorted.reverse() + return ordered.map(k => Timestamp.parse(k)) } cids(): CID[] { diff --git a/common/src/user-store/ss-table.ts b/common/src/user-store/ss-table.ts index 0e5b57c8..b754cb61 100644 --- a/common/src/user-store/ss-table.ts +++ b/common/src/user-store/ss-table.ts @@ -4,13 +4,6 @@ import { IdMapping } from "../types.js" import IpldStore from "../blockstore/ipld-store.js" import Timestamp from "../timestamp.js" -export enum TableSize { - sm = 'sm', - md = 'md', - lg = 'lg', - xl = 'xl', -} - export class SSTable { store: IpldStore @@ -108,12 +101,14 @@ export class SSTable { return str ? Timestamp.parse(str) : null } - ids(): Timestamp[] { - return Object.keys(this.data).sort().reverse().map(k => Timestamp.parse(k)) + ids(newestFirst = false): Timestamp[] { + const sorted = Object.keys(this.data).sort() + const ordered= newestFirst ? sorted : sorted.reverse() + return ordered.map(k => Timestamp.parse(k)) } cids(): CID[] { - return Object.values(this.data).sort().reverse() + return Object.values(this.data) } maxSize(): number { @@ -125,6 +120,14 @@ export class SSTable { } } + +export enum TableSize { + sm = 'sm', + md = 'md', + lg = 'lg', + xl = 'xl', +} + const sizeForName = (size: TableSize): number => { switch (size) { case TableSize.sm: return 100 diff --git a/common/test/branch.ts b/common/test/branch.ts index 45e2ebf9..f1356189 100644 --- a/common/test/branch.ts +++ b/common/test/branch.ts @@ -27,10 +27,10 @@ test("splitting tables", async t => { await branch.addEntry(Timestamp.now(), cid) await wait(1) } - t.is(branch.keys().length, 1, "Does not split at 100 entries") + t.is(branch.tableNames().length, 1, "Does not split at 100 entries") await branch.addEntry(Timestamp.now(), cid) - t.is(branch.keys().length, 2, "Does split at 101 entries") + t.is(branch.tableNames().length, 2, "Does split at 101 entries") }) test("compressing tables", async t => { @@ -40,8 +40,8 @@ test("compressing tables", async t => { await branch.addEntry(Timestamp.now(), cid) await wait(1) } - t.is(branch.keys().length, 4, "Does not compress at 4 tables") + t.is(branch.tableNames().length, 4, "Does not compress at 4 tables") await branch.addEntry(Timestamp.now(), cid) - t.is(branch.keys().length, 2, "Compresses oldest 4 tables once there are 5 tables") + t.is(branch.tableNames().length, 2, "Compresses oldest 4 tables once there are 5 tables") }) diff --git a/common/test/ss-table.ts b/common/test/ss-table.ts index 678264e1..3a4e3ce0 100644 --- a/common/test/ss-table.ts +++ b/common/test/ss-table.ts @@ -5,6 +5,20 @@ import IpldStore from '../src/blockstore/ipld-store.js' import Timestamp from '../src/timestamp.js' import { wait } from '../src/util.js' +import { CID } from 'multiformats' + +type Context = { + store: IpldStore + cid: CID +} + +test.beforeEach(async t => { + const store = IpldStore.createInMemory() + const cid = await store.put({ test: 123 }) + t.context = { store, cid } + t.pass('Context setup') +}) + test('sort keys', async t => { // const store = IpldStore.createInMemory()