friends algorithm rewrite
Because of user-invites and same-as we need a) a more flexible way to represent relations between feeds, and b)
the ability for modules to express aspects of those relationships. (and I think same-as will have many uses: same-as for pubs and same-as for groups)
This is the last piece to user-invites, it's been simmering away in my mind a bit, then I can start putting it all together. In this post I'll write about representing relationships, and I'll write about splitting into modules once I've figured that out...
representing relationships
requirements:
- ability to represent feeds as being the same, i.e. zero hops between them.
- express nuanced relationships, including following, unfollowing, blocking, following but not replicating thier foafs.
The next step is a data structure to represent the possible relationships:
{
id: <id>, //your id.
follows: {
<id:a>: {<id:b>: <hops> || [<hops:in>, <hops:out>], ...} //a 2 level map, representing A follows A
},
blocked: {
<id:b>: {<id:a>: <boolean>} //not, reverse style: b<-[blocks]-a
}
}
code, and more detailed documentation: ssb-friends#rewrite
the follow graph is separated from the block graph, as it was in the original friends plugin that @paul wrote, and not the rewrite that I did later. Also, I realized it's better to put the graph of blocks in reverse. In the actual algorithms, we want to quickly get everyone who's blocked someone - so it's easier to store it in reverse, on the other hand, we want to see who someone follows not who follows them.
This can represent following someone but not their friends by saying A:{B: [1, 2]}
which means A follows B, B will have a hops of 1, but any one B follows will have hops 3 (unless they are followed more directly by someone else).
Basically, this is a way to make a weighted directed graph, and then the shortest paths are calculated across that graph, and the nodes reachable with a fixed distance (hops
) are replicated.
Additional idea: feeds can publish their hops setting: then you'll be able to reason about wether they probably see your messages (if you are within their hops range).
contact messages, user invites, and same-as should all use different message types to express their meaning. currently, I'm only intending to use whole numbers weights, but decimals will also work. This data structure is just about representing the relationships, not how the are expressed as messages. If you were to implement something like @mix's "actual-friends" proposal, you could apply whatever clever algorithm you liked, it just has to output this datastructure.