Abstractions in IPLD: high level and low level data representations
- Dominant language
- HTML
- Stars
- 1.2k
- Forks
- 247
- Avg merge
- 5d 21h
- Merged PRs (30d)
- 4
Description
This issues follows on my original proposal #90 (see the full scheme https://github.com/nicola/interplanetary-paths) discussed this weekend with the team in New York and conversations with @stebalien, @jbenet, @diasdavid, @mildred (ping @dignifiedquire )
**READ first**: because there is so much text already, I wrote **#important** whenever it is the important part to read (of mine of course - feel free to use this in your posts)
## Background
In this issue, I argue that there are two path schemes that we should offer to traverse IPLD objects:
- a low-level path scheme to traverse _data blocks_
- higher-level path scheme to traverse _data objects_.
### Different layers of abstraction
We can abstract the different forms of data in different layers. For example, imagine we have `file1.jpg` in the folder `dir`.
#### Layer 4 (application)
The nice path that an application like unixfs should offer to their final user should allow to do the following `/$hash/dir/file1.jpg`.
#### Layer 3 (IPLD object path)
Let's assume that the unixfs application decides to structure their data in this way:
```
/$hash === {
dir: {
files: {
file1.jpg: Link{@link: hash},
...
file10000.jpg: Link{@link: hash}
}
}
}
```
**Note**: in the case of unixfs, we could aim at merging Layer 3 with Layer 4, but for the sake of the argument, I just made unixfs a bit more complex than it should.
#### Layer 2 (IPLD block path)
However, since the folder is very big, our chunker (this can be implemented in many ways, let's assume that The Nicola IPLD Chunker works this way) is going to split the IPLD object in multiple _IPLD objects_, that we are going to call _IPLD blocks_
```
/$hash === {
dir: {
files: {
shard1: {
file1: Link{@link: hash},
...,
},
shard2: {
file5000: ...,
...,
}
}
}
}
```
#### Summary of the 4 layers and their paths
- **Layer 4**: Application (e.g. unixfs): `/$hash/dir/file1.jpg`
- **Layer 3**: IPLD object: `/$hash/dir/files/file1.jpg`
- **Layer 2**: IPLD blocks: `/$hash/shard3/files/shard1/file1/0/0/0//`
- **Layer 1**: JSON primitives ({key: value})
- **Layer 0**: Data primitives (strings, numbers, links)
##### Differences between 2 and 3
In other words the two key layers for IPLD are the 2nd and the 3rd.
The reason why they should have different path schemes is because they are both important to the final application developer (depending whether they are writing higher or lower level application).
The difference between the two is that one traverses the actual IPLD data blocks, while the other one abstracts that. From the previous example:
- **Layer 3**: `/hash/file3` would be a path of the final representation
- **Layer 2**: `/hash/shard1/file1` is what we will have to use instead.
##### Note on different path schemes
Also, the way the separator will traverse either layer may have different meaning, for example in Layer 3, maybe there is no need to have transparent links, while it can be important for Layer 2.
So for example
```
{
file1: Link({@link: hash, permission: 0777})
}
hash === {
name: "Nicola"
}
```
- Layer 3:
- `/file/name === Nicola`
- `/file/permission === undefined`
- Layer 3
- `/file//name === Nicola` (note the `//` meaning that we are traversing a link)
- `/file/permission === 0777`
##### Reworking examples in the current spec
For simplicity call `high-ipld` high level, and `low-ipld` the low level (the low level is the current IPLD)
```
> low-ipld cat QmCCC...CCC/cat.jpg
{
"data": "\u0008\u0002\u0012��\u0008����\u0000\u0010JFIF\u0000\u0001\u0001\u0001\u0000H\u0000H..."
}
> high-ipld cat QmCCC...CCC/cat.jpg
\u0008\u0002\u0012��\u0008����\u0000\u0010JFIF\u0000\u0001\u0001\u0001\u0000H\u0000H..."
```
```
> low-ipld cat --json QmCCC...CCC/doge.jpg
{
"subfiles": [
{
"@link": "QmPHPs1P3JaWi53q5qqiNauPhiTqa3S1mbszcVPHKGNWRh"
},
{
"@link": "QmPCuqUTNb21VDqtp5b8VsNzKEMtUsZCCVsEUBrjhERRSR"
},
{
"@link": "QmS7zrNSHEt5GpcaKrwdbnv1nckBreUxWnLaV4qivjaNr3"
}
]
}
> high-ipld cat QmCCC...CCC/doge.jpg
\u0008\u0002\u0012��\u0008����\u0000\u0010JFIF\u0000\u0001\u0001\u0001\u0000H\u0000H..."
```
```
> low-ipld cat --json QmCCC...CCC/blogpost
{
"shards": [
{
"@link": "QmPHPs1P3JaWi53q5qqiNauPhiTqa3S1mbszcVPHKGNWRh"
},
{
"@link": "QmPCuqUTNb21VDqtp5b8VsNzKEMtUsZCCVsEUBrjhERRSR"
},
{
"@link": "QmS7zrNSHEt5GpcaKrwdbnv1nckBreUxWnLaV4qivjaNr3"
}
]
}
> high-ipld cat QmCCC...CCC/blogpost
"This is a very long blogpost..."
```
#### Notes on implementation
##### Two paths options
- **Solution 1**: Different path scheme
Maybe it can be done with different prefixes (/ipld1 , /ipld2)
- **Solution 2**: Same path with different separator
By using a different separator than `/`, for example `.`, then we can mix the two path schemes. Assume that `/` will traverse the high level representation and `.` the lower level. I am not sure how this would work
#### Notes about this conversation
At the beginning my perception of IPLD was that pathing would resolve the high level representation, so that if I have a JSON, I could just be able to traverse it `/friends/0/name`, however the current IPLD pathing may not allow that.
Also, `blocks` and `objects` are in reference to file system concepts, they are open for better naming
**#important**
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.