Skip to content
Snippets Groups Projects
Commit a86c5cbf authored by Hugo Trentesaux's avatar Hugo Trentesaux
Browse files

refac diff view

parent 99557ecf
Branches
No related tags found
No related merge requests found
...@@ -43,3 +43,4 @@ npx tsx src/scripts/start-indexer.ts ...@@ -43,3 +43,4 @@ npx tsx src/scripts/start-indexer.ts
## TODO ## TODO
When using Kubo node, libp2p is not needed at all. When using Kubo node, libp2p is not needed at all.
Insert pubkey instead of ss58 address if we want data to be compatible across networks
import type { CID } from 'multiformats' import type { CID } from 'multiformats'
import { kubo } from './kubo' import { kubo } from './kubo'
import { emptyInode, type IndexHist, type IndexInode, type IndexLeaf } from './types'
import { IPNS_HIST, BASE, KEYSIZE } from './consts'
// interface to easily iterate over the AMT // interface to easily iterate over the AMT
export async function* getAll(cid: CID): AsyncIterable<CID[]> { export async function* getAll(cid: CID): AsyncIterable<CID[]> {
...@@ -19,3 +21,143 @@ export async function* getAll(cid: CID): AsyncIterable<CID[]> { ...@@ -19,3 +21,143 @@ export async function* getAll(cid: CID): AsyncIterable<CID[]> {
// interface to easily iterate over diff of two AMT // interface to easily iterate over diff of two AMT
export async function* getDiff(cid1: CID, cid2: CID) {} export async function* getDiff(cid1: CID, cid2: CID) {}
// recursive comparison of inodes
// the differences are added asynchronously in "addedLeft" and "addedRight" arrays
// meaning that these arrays will still grow after the function returns
export function compareInodes(
// key of compared inodes, used as termination condition to know if we reached the leaf
k: string,
// reference node for comparison
left: IndexInode,
// node to compare with reference
right: IndexInode,
// list of nodes in left not present in right, (key,value) pairs
addedLeft: Array<[string, CID]>,
// list of nodes in right not present in left, (key,value) pairs
addedRight: Array<[string, CID]>
) {
// termination condition, since we know the size of the key
if (k.length == KEYSIZE) {
console.log('comparing leaf ' + k)
compareLeafs(k, left as unknown as IndexLeaf, right as unknown as IndexLeaf, addedLeft, addedRight)
return
}
// console.log('comparing node ' + k)
// iterate over nodes children
for (let i = 0; i < BASE; i++) {
// get left and right entries
const li = left.children[i]
const ri = right.children[i]
if (li == null && ri == null) {
// do not compare if they are both null
continue
}
if (li == null) {
// right is not null and was added
const nk = k + ri![0]
console.log('added right ' + nk)
addedRight.push([k, ri![1]])
continue
}
if (ri == null) {
// left is not null and was added
console.log('added left')
const nk = k + li![0]
addedLeft.push([nk, li![1]])
continue
}
// both buckets have items, unstructure them to get key and value
const [lik, lic] = li
const [rik, ric] = ri
if (lic.toString() == ric.toString()) {
// do not compare if the cid is the same
console.log('same ' + k + lik)
continue
}
if (lik == rik) {
// keys are the same and only content changed, dig deeper in both
const nk = k + lik
Promise.all([kubo.dag.get(lic), kubo.dag.get(ric)]).then((r) => {
const [lin, rin] = r
compareInodes(nk, lin.value, rin.value, addedLeft, addedRight)
})
continue
}
// there is a key diff, we have to compare
if (lik.length > rik.length && lik.startsWith(rik)) {
const nk = k + rik
console.log('diff ' + nk)
// intermediate inode might have been added to the right
// create virtual node then dig deeper in right
const lvnode = emptyInode()
const b = parseInt(lik[rik.length], BASE)
lvnode.children[b] = [lik.slice(rik.length), lic]
kubo.dag.get(ric).then((r) => {
compareInodes(nk, lvnode, r.value, addedLeft, addedRight)
})
continue
}
if (lik.length < rik.length && rik.startsWith(lik)) {
const nk = k + lik
console.log('diff ' + nk)
// intermediate inode might have been added to the left
// create virtual node then dig deeper in right
const rvnode = emptyInode()
const b = parseInt(rik[lik.length], BASE)
rvnode.children[b] = [rik, ric]
kubo.dag.get(ric).then((l) => {
compareInodes(nk, l.value, rvnode, addedLeft, addedRight)
})
continue
}
// keys do not cover the same time period
// content is then completely different
addedLeft.push([k + lik, lic])
addedRight.push([k + rik, ric])
continue
}
}
// compare leaves by "eating" cids one by one
function compareLeafs(
k: string,
left: IndexLeaf,
right: IndexLeaf,
addedLeft: Array<[string, CID]>,
addedRight: Array<[string, CID]>
) {
while (true) {
const l = left.leaf.shift()
const r = right.leaf.shift()
if (l == undefined) {
right.leaf.map((e) => {
addedRight.push([k, e])
})
return
}
if (r == undefined) {
left.leaf.map((e) => {
addedLeft.push([k, e])
})
return
}
if (l == r) {
continue
}
if (l < r) {
addedLeft.push([k, l])
right.leaf.unshift(r)
continue
}
if (l > r) {
addedRight.push([k, r])
left.leaf.unshift(l)
continue
}
}
}
...@@ -37,7 +37,7 @@ pubsub.addEventListener('message', (message) => { ...@@ -37,7 +37,7 @@ pubsub.addEventListener('message', (message) => {
const isValid = isValidSignature(bytesPayload, dag.sig, dag.pubk) const isValid = isValidSignature(bytesPayload, dag.sig, dag.pubk)
if (isValid) { if (isValid) {
// here we would do the processing // here we would do the processing
// addToIndex(cid, dag) addToIndex(cid, dag)
} else { } else {
feed.value.push('[invalid sig] ' + msg) feed.value.push('[invalid sig] ' + msg)
} }
......
<script setup lang="ts"> <script setup lang="ts">
import { kubo } from '@/kubo' import { kubo } from '@/kubo'
import { emptyInode, type IndexHist, type IndexInode, type IndexLeaf } from '../types' import { IPNS_HIST, KEYSIZE } from '../consts'
import { IPNS_HIST, BASE, KEYSIZE } from '../consts'
import { CID } from 'multiformats' import { CID } from 'multiformats'
import { ref, type Ref, onMounted } from 'vue' import { ref, type Ref, onMounted } from 'vue'
import { compareInodes } from '../interface'
const leftMsg = ref('') const leftMsg = ref('')
const rightMsg = ref('') const rightMsg = ref('')
...@@ -32,142 +32,13 @@ async function compareRoots() { ...@@ -32,142 +32,13 @@ async function compareRoots() {
result.value = 'computing diff...' result.value = 'computing diff...'
// fetch root nodes // fetch root nodes
const [leftRoot, rightRoot] = await Promise.all([kubo.dag.get(leftRootCid.value), kubo.dag.get(rightRootCid.value)]) const [leftRoot, rightRoot] = await Promise.all([kubo.dag.get(leftRootCid.value), kubo.dag.get(rightRootCid.value)])
// compare // compare inodes, the diff will be added asynchronously in the addedLeft and addedRight arrays
compareInodes('', leftRoot.value, rightRoot.value, addedLeft.value, addedRight.value) compareInodes('', leftRoot.value, rightRoot.value, addedLeft.value, addedRight.value)
// print result // print result
result.value = 'diff' result.value = 'diff'
} }
function compareInodes( // init diff comparison with the latest addition to the tree
k: string,
left: IndexInode,
right: IndexInode,
addedLeft: Array<[string, CID]>,
addedRight: Array<[string, CID]>
) {
if (k.length == KEYSIZE) {
console.log('comparing leaf ' + k)
compareLeafs(k, left as unknown as IndexLeaf, right as unknown as IndexLeaf, addedLeft, addedRight)
return
}
// console.log('comparing node ' + k)
for (let i = 0; i < BASE; i++) {
// get left and right entries
const li = left.children[i]
const ri = right.children[i]
if (li == null && ri == null) {
// do not compare if they are both null
continue
}
if (li == null) {
// right is not null and was added
const nk = k + ri![0]
console.log('added right ' + nk)
addedRight.push([k, ri![1]])
continue
}
if (ri == null) {
// left is not null and was added
console.log('added left')
const nk = k + li![0]
addedLeft.push([nk, li![1]])
continue
}
// both buckets have items, unstructure them to get key and value
const [lik, lic] = li
const [rik, ric] = ri
if (lic.toString() == ric.toString()) {
// do not compare if the cid is the same
console.log('same ' + k + lik)
continue
}
if (lik == rik) {
const nk = k + lik
// keys are the same and only content changed, dig deeper in both
Promise.all([kubo.dag.get(lic), kubo.dag.get(ric)]).then((r) => {
const [lin, rin] = r
compareInodes(nk, lin.value, rin.value, addedLeft, addedRight)
})
continue
}
// there is a key diff, we have to compare
if (lik.length > rik.length && lik.startsWith(rik)) {
const nk = k + rik
console.log('diff ' + nk)
// intermediate inode might have been added to the right
// create virtual node then dig deeper in right
const lvnode = emptyInode()
const b = parseInt(lik[rik.length], BASE)
lvnode.children[b] = [lik.slice(rik.length), lic]
kubo.dag.get(ric).then((r) => {
compareInodes(nk, lvnode, r.value, addedLeft, addedRight)
})
continue
}
if (lik.length < rik.length && rik.startsWith(lik)) {
const nk = k + lik
console.log('diff ' + nk)
// intermediate inode might have been added to the left
// create virtual node then dig deeper in right
const rvnode = emptyInode()
const b = parseInt(rik[lik.length], BASE)
rvnode.children[b] = [rik, ric]
kubo.dag.get(ric).then((l) => {
compareInodes(nk, l.value, rvnode, addedLeft, addedRight)
})
continue
}
// keys do not cover the same time period
// content is then completely different
addedLeft.push([k + lik, lic])
addedRight.push([k + rik, ric])
continue
}
}
function compareLeafs(
k: string,
left: IndexLeaf,
right: IndexLeaf,
addedLeft: Array<[string, CID]>,
addedRight: Array<[string, CID]>
) {
while (true) {
const l = left.leaf.shift()
const r = right.leaf.shift()
if (l == undefined) {
right.leaf.map((e) => {
addedRight.push([k, e])
})
return
}
if (r == undefined) {
left.leaf.map((e) => {
addedLeft.push([k, e])
})
return
}
if (l == r) {
continue
}
if (l < r) {
addedLeft.push([k, l])
right.leaf.unshift(r)
continue
}
if (l > r) {
addedRight.push([k, r])
left.leaf.unshift(l)
continue
}
}
}
function initWithLastCommit() { function initWithLastCommit() {
async function resolveHist(): Promise<CID> { async function resolveHist(): Promise<CID> {
for await (const name of kubo.name.resolve(IPNS_HIST, { nocache: true })) { for await (const name of kubo.name.resolve(IPNS_HIST, { nocache: true })) {
...@@ -182,6 +53,9 @@ function initWithLastCommit() { ...@@ -182,6 +53,9 @@ function initWithLastCommit() {
if (hist.value.last_history) { if (hist.value.last_history) {
kubo.dag.get(hist.value.last_history).then((hist1) => { kubo.dag.get(hist.value.last_history).then((hist1) => {
leftRootCid.value = hist1?.value.current_index leftRootCid.value = hist1?.value.current_index
if (leftRootCid.value) {
compareRoots()
}
}) })
} }
}) })
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment