src/network/rps/cyclon/partialview.js
class PartialView extends Map {
/**
* Get the oldest peer in the partial view.
* @returns {string} The oldest peer in the array.
*/
get oldest () {
if (this.size <= 0) { throw new Error('oldest peer not found') };
let oldestPeer = null
let oldestAge = 0
this.forEach((ages, peerId) => {
if (oldestAge <= ages[ages.length - 1]) {
oldestPeer = peerId
oldestAge = ages[ages.length - 1]
};
})
return oldestPeer
};
/**
* Increment the age of the whole partial view
*/
increment () {
this.forEach((ages, peerId) => {
this.set(peerId, ages.map((age) => { return age + 1 }))
})
};
/**
* Add the peer to the partial view with an age of 0.
* @param {string} peerId The identifier of the peer added to the partial
* view.
*/
add (peerId) {
(!this.has(peerId)) && this.set(peerId, [])
this.get(peerId).unshift(0) // add 0 in front of the array
};
/**
* Remove the newest entry of the peer from the partial view.
* @param {string} peerId The identifier of the peer to remove from the
* partial view.
*/
removeYoungest (peerId) {
if (!this.has(peerId)) {
throw new Error('removeYoungest, peer not found' + peerId)
};
this.get(peerId).shift();
(this.get(peerId).length === 0) && this.delete(peerId)
};
/**
* Remove the oldest entry of the peer from the partial view.
* @param {string} peerId The identifier of the peer to remove from the
* partial view.
*/
removeOldest (peerId) {
if (!this.has(peerId)) {
throw new Error('removeOldest, peer not found:' + peerId)
};
this.get(peerId).pop();
(this.get(peerId).length === 0) && this.delete(peerId)
};
/**
* Remove all entries of the peer from the partial view.
* @param {string} peerId The identifier of the peer to remove from the
* partial view.
* @returns {number} The number of occurrences of peerId removed.
*/
removeAll (peerId) {
if (!this.has(peerId)) {
throw new Error('removeAll, peer not found: ' + peerId)
};
const occ = this.get(peerId).length
this.delete(peerId)
return occ
};
/**
* Get the least frequent peer. If multiple peers have the same number of
* occurrences, it chooses one among them at random.
* @returns {string} The identifier of a least frequent peer.
*/
get leastFrequent () {
let leastFrequent = []
let frequency = Infinity
this.forEach((ages, peerId) => {
if (ages.length < frequency) {
leastFrequent = []
frequency = ages.length
};
(ages.length === frequency) && leastFrequent.push(peerId)
})
return leastFrequent[Math.floor(Math.random() * leastFrequent.length)]
};
}
module.exports = PartialView