sets seem to be working

This commit is contained in:
dholms 2022-07-21 17:10:56 -05:00
parent 1dc4f01371
commit 5c12a926fc
2 changed files with 110 additions and 21 deletions
packages/common
src/repo
tests

@ -34,7 +34,6 @@ export const leadingZerosOnHash = async (key: string): Promise<number> => {
}
const spliceIn = <T>(array: T[], item: T, index: number): T[] => {
// const spliceIndex = Math.max(index, 0)
return [...array.slice(0, index), item, ...array.slice(index)]
}
@ -64,10 +63,20 @@ export class MST {
return new MST(blockstore, cid, node, zeros)
}
static async load(blockstore: IpldStore, cid: CID): Promise<MST> {
static async load(
blockstore: IpldStore,
cid: CID,
zeros?: number,
): Promise<MST> {
const node = await blockstore.get(cid, nodeSchema)
return new MST(blockstore, cid, node, 0) // @TODO calculate 0s
if (!zeros) {
const firstLeaf = node.find((entry) => check.is(entry, leafPointer))
if (!firstLeaf) {
throw new Error('not a valid mst node: no leaves')
}
zeros = await leadingZerosOnHash(firstLeaf[0])
}
return new MST(blockstore, cid, node, zeros)
}
async put(): Promise<CID> {
@ -77,6 +86,9 @@ export class MST {
async set(key: string, value: CID): Promise<CID> {
const keyZeros = await leadingZerosOnHash(key)
if (keyZeros > 1) {
console.log('GREATER THAN 1')
}
// it belongs in this layer
if (keyZeros === this.zeros) {
const index = this.insertIndex(key)
@ -87,18 +99,52 @@ export class MST {
return this.put()
} else {
// else we need to investigate the subtree
const subTree = await MST.load(this.blockstore, prevNode)
const subTree = await MST.load(
this.blockstore,
prevNode,
this.zeros - 1,
)
// we try to split the subtree around the key
const splitSubTree = await subTree.splitAround(key)
const newNode = this.node.slice(0, index - 1)
if (splitSubTree[0]) newNode.push(splitSubTree[0])
newNode.push(value)
newNode.push([key, value])
if (splitSubTree[1]) newNode.push(splitSubTree[1])
newNode.push(...this.node.slice(index))
this.node = newNode
return this.put()
}
} else if (keyZeros < this.zeros) {
// it belongs on a lower layer
const index = this.insertIndex(key)
const prevNode = this.node[index - 1]
if (check.is(prevNode, treePointer)) {
// if entry before is a tree, we add it to that tree
const subTree = await MST.load(
this.blockstore,
prevNode,
this.zeros - 1,
)
const newSubTreeCid = await subTree.set(key, value)
this.node[index - 1] = newSubTreeCid
return this.put()
} else {
// else we need to create the subtree for it to go in
const subTree = await MST.create(this.blockstore, this.zeros - 1)
const newSubTreeCid = await subTree.set(key, value)
this.node = spliceIn(this.node, newSubTreeCid, index)
return this.put()
}
} else {
// it belongs in a different layer
// it belongs on a higher layer & we must push the rest of the tree down
const split = this.splitAround(key)
const newNode: Node = []
if (split[0]) newNode.push(split[0])
newNode.push([key, value])
if (split[1]) newNode.push(split[1])
this.node = newNode
this.zeros++
return this.put()
}
}

@ -4,25 +4,68 @@ import * as uint8arrays from 'uint8arrays'
import * as util from './_util'
import { sha256 } from '@adxp/crypto'
import { IpldStore } from '../src'
describe('Merkle Search Tree', () => {
it('blah', async () => {
let counts = {
0: 0,
1: 0,
2: 0,
3: 0,
4: 0,
5: 0,
6: 0,
}
for (let i = 0; i < 1000000; i++) {
it('works', async () => {
const blockstore = IpldStore.createInMemory()
const mst = await MST.create(blockstore)
const cid = await util.randomCid()
for (let i = 0; i < 1000; i++) {
const tid = TID.next()
const count = await leadingZerosOnHash(tid.toString())
counts[count]++
await mst.set(tid.toString(), cid)
}
console.log(counts)
console.log('zeroes: ', mst.zeros)
// await mst.set('1', cid)
// await mst.set('2', cid)
// await mst.set('3', cid)
// await mst.set('4', cid)
// await mst.set('5', cid)
// await mst.set('3j6ezmyjtgm2n', cid)
// await mst.set('6', cid)
// await mst.set('7', cid)
// await mst.set('8', cid)
// await mst.set('9', cid)
// await mst.set('10', cid)
// await mst.set('11', cid)
// await mst.set('12', cid)
// await mst.set('13', cid)
// await mst.set('14', cid)
// await mst.set('15', cid)
// await mst.set('16', cid)
// await mst.set('17', cid)
// await mst.set('18', cid)
// await mst.set('19', cid)
// await mst.set('20', cid)
// await mst.set('21', cid)
// await mst.set('22', cid)
// await mst.set('23', cid)
// await mst.set('24', cid)
// await mst.set('25', cid)
// await mst.set('26', cid)
// await mst.set('27', cid)
// await mst.set('28', cid)
// await mst.set('29', cid)
// await mst.set('30', cid)
})
// it('blah', async () => {
// let counts = {
// 0: 0,
// 1: 0,
// 2: 0,
// 3: 0,
// 4: 0,
// 5: 0,
// 6: 0,
// }
// for (let i = 0; i < 1000000; i++) {
// const tid = TID.next()
// const count = await leadingZerosOnHash(tid.toString())
// counts[count]++
// }
// console.log(counts)
// })
// it('does something', async () => {
// const mst = new MST()
// const cid = await util.randomCid()