92 lines
2.3 KiB
JavaScript
92 lines
2.3 KiB
JavaScript
'use strict'
|
|
|
|
/**
|
|
* Module dependencies
|
|
*/
|
|
const LruMap = require('lru-cache')
|
|
const NumberAllocator = require('number-allocator').NumberAllocator
|
|
|
|
/**
|
|
* Topic Alias sending manager
|
|
* This holds both topic to alias and alias to topic map
|
|
* @param {Number} [max] - topic alias maximum entries
|
|
*/
|
|
function TopicAliasSend (max) {
|
|
if (!(this instanceof TopicAliasSend)) {
|
|
return new TopicAliasSend(max)
|
|
}
|
|
|
|
if (max > 0) {
|
|
this.aliasToTopic = new LruMap({ max: max })
|
|
this.topicToAlias = {}
|
|
this.numberAllocator = new NumberAllocator(1, max)
|
|
this.max = max
|
|
this.length = 0
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Insert or update topic - alias entry.
|
|
* @param {String} [topic] - topic
|
|
* @param {Number} [alias] - topic alias
|
|
* @returns {Boolean} - if success return true otherwise false
|
|
*/
|
|
TopicAliasSend.prototype.put = function (topic, alias) {
|
|
if (alias === 0 || alias > this.max) {
|
|
return false
|
|
}
|
|
const entry = this.aliasToTopic.get(alias)
|
|
if (entry) {
|
|
delete this.topicToAlias[entry]
|
|
}
|
|
this.aliasToTopic.set(alias, topic)
|
|
this.topicToAlias[topic] = alias
|
|
this.numberAllocator.use(alias)
|
|
this.length = this.aliasToTopic.length
|
|
return true
|
|
}
|
|
|
|
/**
|
|
* Get topic by alias
|
|
* @param {Number} [alias] - topic alias
|
|
* @returns {String} - if mapped topic exists return topic, otherwise return undefined
|
|
*/
|
|
TopicAliasSend.prototype.getTopicByAlias = function (alias) {
|
|
return this.aliasToTopic.get(alias)
|
|
}
|
|
|
|
/**
|
|
* Get topic by alias
|
|
* @param {String} [topic] - topic
|
|
* @returns {Number} - if mapped topic exists return topic alias, otherwise return undefined
|
|
*/
|
|
TopicAliasSend.prototype.getAliasByTopic = function (topic) {
|
|
const alias = this.topicToAlias[topic]
|
|
if (typeof alias !== 'undefined') {
|
|
this.aliasToTopic.get(alias) // LRU update
|
|
}
|
|
return alias
|
|
}
|
|
|
|
/**
|
|
* Clear all entries
|
|
*/
|
|
TopicAliasSend.prototype.clear = function () {
|
|
this.aliasToTopic.reset()
|
|
this.topicToAlias = {}
|
|
this.numberAllocator.clear()
|
|
this.length = 0
|
|
}
|
|
|
|
/**
|
|
* Get Least Recently Used (LRU) topic alias
|
|
* @returns {Number} - if vacant alias exists then return it, otherwise then return LRU alias
|
|
*/
|
|
TopicAliasSend.prototype.getLruAlias = function () {
|
|
const alias = this.numberAllocator.firstVacant()
|
|
if (alias) return alias
|
|
return this.aliasToTopic.keys()[this.aliasToTopic.length - 1]
|
|
}
|
|
|
|
module.exports = TopicAliasSend
|