02_Choosing_a_data_structure.md
February 23, 2022 ยท View on GitHub
Choosing a data structure
Let's start implementing a comment system by choosing how we want to represent the comments in the Index.
Choosing a data structure first and working our way outwards to the store API, that best fits to the data structure and then implementing the Access Controller, since the Access Controller is very much independent from the Store and Index.
Requirements
Our data structure should achieve two things:
- It should store the CID of the sheet music and a string denoting the instrument.
- It should also store the comments, which themselves refer to a sheet music CID or a previous comment.
The simplest data structure that could fulfill these requirements would be a collection of trees. Each tree's root would be the Notes pieces and the children of that root would be the comments, the comments' comments and so on and so on.
Generating the Trees from the ipfs-log
Before starting to implement this data structure,
we'll also have to consider, how to generate
these trees from the oplog or ipfs-log.
In the index, we'll see the oplog as an Array of operations, each containing these fields:
opto denote the operation being madekeysome key, that we can set if we so choose.valuethe value of the actual operation.
For our purposes there can be these operations:
ADDNOTESto add a new piece of notes.DELETENOTESto delete a piece of notes.ADDCOMMENTto add a comment to a piece of notes or some other comments.DELETECOMMENTto delete a comment.
This seems pretty straight forward.
What happens when we delete notes or comments, with all those comments referring to them?
I propose using a simple rule: If a comment or piece of notes is deleted, all those refering to it are deleted too. Otherwise this tutorial becomes a complicated mess.
Implementing the Index.
Let's start by adding a new file to your project folder (if you haven't yet created one, do that now).
Isomorphic Bookends.
You know the drill, before starting with the actual implementation of the Index, we have to define the bookends that make our code work in the browser and in NodeJS:
"use strict"
try {
module.exports = NotesIndex
} catch (e) {
window.NotesIndex = NotesIndex
}
Not that complicated, really. Because an Index does not actually depend on libraries from OrbitDB.
It is using duck typing, instead of inheritance.
Defining the NotesIndex class.
Next, let's define the actual class
of the NotesIndex.
Add this to your file, between the bookends and the use strict.
class NotesIndex {
constructor() {
this._index = {}
}
}
We initialize the index to an empty object at first, because we don't yet have any data.
Defining the TreeNode helper class.
After this, let's first implement our own TreeNode data type,
that'll be used to represent the trees mentioned above.
Because Trees are fundamentally recursive data structures,
a Tree and a TreeNode are the same thing.
Both hold some data and have some children, who
are of type TreeNode.
class TreeNode {
constructor(data) {
this.data = data
this.children = []
}
addChild(data) {
let node = new TreeNode(data)
this.children.push(node)
return node
}
}
With this utility class, we can now get on to implementing the Index API.