This commit is contained in:
Daniel Holmgren 2022-02-18 14:46:21 -06:00
parent 2625a18f87
commit 2f699a0650
4 changed files with 48 additions and 29 deletions

@ -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[] {

@ -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

@ -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")
})

@ -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()