return Sets from some Tangle APIs

This commit is contained in:
Andre Staltz 2023-04-14 16:41:25 +03:00
parent 93d9b5425a
commit 6a19cd91a8
2 changed files with 64 additions and 16 deletions

View File

@ -60,12 +60,18 @@ class Tangle {
*/ */
#perDepth = new Map() #perDepth = new Map()
/**
* @type {number}
*/
#maxDepth
/** /**
* *
* @param {string} rootHash * @param {string} rootHash
* @param {Iterable<Rec>} recordsIter * @param {Iterable<Rec>} recordsIter
*/ */
constructor(rootHash, recordsIter) { constructor(rootHash, recordsIter) {
this.#maxDepth = 0
for (const rec of recordsIter) { for (const rec of recordsIter) {
const msgHash = rec.hash const msgHash = rec.hash
const tangles = rec.msg.metadata.tangles const tangles = rec.msg.metadata.tangles
@ -81,6 +87,7 @@ class Tangle {
} }
this.#prev.set(msgHash, prev) this.#prev.set(msgHash, prev)
const depth = tangles[rootHash].depth const depth = tangles[rootHash].depth
if (depth > this.#maxDepth) this.#maxDepth = depth
this.#depth.set(msgHash, depth) this.#depth.set(msgHash, depth)
const atDepth = this.#perDepth.get(depth) ?? [] const atDepth = this.#perDepth.get(depth) ?? []
atDepth.push(msgHash) atDepth.push(msgHash)
@ -103,7 +110,8 @@ class Tangle {
*/ */
topoSort() { topoSort() {
const sorted = [] const sorted = []
for (let i = 0; i < 1e9; i++) { const max = this.#maxDepth
for (let i = 0; i <= max; i++) {
const atDepth = this.#getAllAtDepth(i) const atDepth = this.#getAllAtDepth(i)
if (atDepth.length === 0) break if (atDepth.length === 0) break
for (const msgHash of atDepth) { for (const msgHash of atDepth) {
@ -114,19 +122,19 @@ class Tangle {
} }
/** /**
* @returns {Array<string>} * @returns {Set<string>}
*/ */
getTips() { getTips() {
return [...this.#tips] return this.#tips
} }
/** /**
* @param {number} depth * @param {number} depth
* @returns {Array<string>} * @returns {Set<string>}
*/ */
getLipmaa(depth) { getLipmaaSet(depth) {
const lipmaaDepth = lipmaa(depth + 1) - 1 const lipmaaDepth = lipmaa(depth + 1) - 1
return this.#getAllAtDepth(lipmaaDepth) return new Set(this.#getAllAtDepth(lipmaaDepth))
} }
/** /**
@ -137,6 +145,14 @@ class Tangle {
return this.#depth.has(msgHash) return this.#depth.has(msgHash)
} }
/**
* @param {string} msgHash
* @returns {number}
*/
getDepth(msgHash) {
return this.#depth.get(msgHash) ?? -1
}
#shortestPathToRoot(msgHash) { #shortestPathToRoot(msgHash) {
const path = [] const path = []
let current = msgHash let current = msgHash
@ -169,6 +185,10 @@ class Tangle {
) )
return { deletables, emptyables } return { deletables, emptyables }
} }
getMaxDepth() {
return this.#maxDepth
}
} }
module.exports = Tangle module.exports = Tangle

View File

@ -96,6 +96,23 @@ test('Tangle.has', (t) => {
t.end() t.end()
}) })
test('Tangle.getDepth', t=> {
const tangle = new Tangle(rootPost, peer.db.records())
t.equals(tangle.getDepth(rootPost), 0, 'depth of rootPost is 0')
t.equals(tangle.getDepth(reply1Lo), 1, 'depth of reply1Lo is 1')
t.equals(tangle.getDepth(reply1Hi), 1, 'depth of reply1Hi is 1')
t.equals(tangle.getDepth(reply2A), 2, 'depth of reply2A is 2')
t.equals(tangle.getDepth(reply3Lo), 3, 'depth of reply3Lo is 3')
t.equals(tangle.getDepth(reply3Hi), 3, 'depth of reply3Hi is 3')
t.end()
})
test('Tangle.getMaxDepth', t => {
const tangle = new Tangle(rootPost, peer.db.records())
t.equals(tangle.getMaxDepth(), 3, 'max depth is 3')
t.end()
})
test('Tangle.topoSort', (t) => { test('Tangle.topoSort', (t) => {
const tangle = new Tangle(rootPost, peer.db.records()) const tangle = new Tangle(rootPost, peer.db.records())
const sorted = tangle.topoSort() const sorted = tangle.topoSort()
@ -115,20 +132,31 @@ test('Tangle.getTips', (t) => {
const tangle = new Tangle(rootPost, peer.db.records()) const tangle = new Tangle(rootPost, peer.db.records())
const tips = tangle.getTips() const tips = tangle.getTips()
t.equals(tips.length, 2, 'there are 2 tips') t.equals(tips.size, 2, 'there are 2 tips')
t.true(tips.includes(reply3Lo), 'tips contains reply3Lo') t.true(tips.has(reply3Lo), 'tips contains reply3Lo')
t.true(tips.includes(reply3Hi), 'tips contains reply3Hi') t.true(tips.has(reply3Hi), 'tips contains reply3Hi')
t.end() t.end()
}) })
test('Tangle.getLipmaa', (t) => { test('Tangle.getLipmaaSet', (t) => {
const tangle = new Tangle(rootPost, peer.db.records()) const tangle = new Tangle(rootPost, peer.db.records())
t.deepEquals(tangle.getLipmaa(0), [], 'lipmaa 0 (empty)') t.equals(tangle.getLipmaaSet(0).size, 0, 'lipmaa 0 (empty)')
t.deepEquals(tangle.getLipmaa(1), [rootPost], 'lipmaa 1 (-1)')
t.deepEquals(tangle.getLipmaa(2), [reply1Lo, reply1Hi], 'lipmaa 2 (-1)') t.equals(tangle.getLipmaaSet(1).size, 1, 'lipmaa 1 (-1)')
t.deepEquals(tangle.getLipmaa(3), [rootPost], 'lipmaa 3 (leap!)') t.true(tangle.getLipmaaSet(1).has(rootPost), 'lipmaa 1 (-1)')
t.deepEquals(tangle.getLipmaa(4), [reply3Lo, reply3Hi], 'lipmaa 4 (-1)')
t.deepEquals(tangle.getLipmaa(5), [], 'lipmaa 5 (empty)') t.equals(tangle.getLipmaaSet(2).size, 2, 'lipmaa 2 (-1)')
t.true(tangle.getLipmaaSet(2).has(reply1Lo), 'lipmaa 2 (-1)')
t.true(tangle.getLipmaaSet(2).has(reply1Hi), 'lipmaa 2 (-1)')
t.equals(tangle.getLipmaaSet(3).size, 1, 'lipmaa 3 (leap!)')
t.true(tangle.getLipmaaSet(3).has(rootPost), 'lipmaa 3 (leap!)')
t.equals(tangle.getLipmaaSet(4).size, 2, 'lipmaa 4 (-1)')
t.true(tangle.getLipmaaSet(4).has(reply3Lo), 'lipmaa 4 (-1)')
t.true(tangle.getLipmaaSet(4).has(reply3Hi), 'lipmaa 4 (-1)')
t.equals(tangle.getLipmaaSet(5).size, 0, 'lipmaa 5 (empty)')
t.end() t.end()
}) })