topic-alias-send.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. 'use strict'
  2. /**
  3. * Module dependencies
  4. */
  5. const LruMap = require('lru-cache')
  6. const NumberAllocator = require('number-allocator').NumberAllocator
  7. /**
  8. * Topic Alias sending manager
  9. * This holds both topic to alias and alias to topic map
  10. * @param {Number} [max] - topic alias maximum entries
  11. */
  12. function TopicAliasSend (max) {
  13. if (!(this instanceof TopicAliasSend)) {
  14. return new TopicAliasSend(max)
  15. }
  16. if (max > 0) {
  17. this.aliasToTopic = new LruMap({ max: max })
  18. this.topicToAlias = {}
  19. this.numberAllocator = new NumberAllocator(1, max)
  20. this.max = max
  21. this.length = 0
  22. }
  23. }
  24. /**
  25. * Insert or update topic - alias entry.
  26. * @param {String} [topic] - topic
  27. * @param {Number} [alias] - topic alias
  28. * @returns {Boolean} - if success return true otherwise false
  29. */
  30. TopicAliasSend.prototype.put = function (topic, alias) {
  31. if (alias === 0 || alias > this.max) {
  32. return false
  33. }
  34. const entry = this.aliasToTopic.get(alias)
  35. if (entry) {
  36. delete this.topicToAlias[entry]
  37. }
  38. this.aliasToTopic.set(alias, topic)
  39. this.topicToAlias[topic] = alias
  40. this.numberAllocator.use(alias)
  41. this.length = this.aliasToTopic.length
  42. return true
  43. }
  44. /**
  45. * Get topic by alias
  46. * @param {Number} [alias] - topic alias
  47. * @returns {String} - if mapped topic exists return topic, otherwise return undefined
  48. */
  49. TopicAliasSend.prototype.getTopicByAlias = function (alias) {
  50. return this.aliasToTopic.get(alias)
  51. }
  52. /**
  53. * Get topic by alias
  54. * @param {String} [topic] - topic
  55. * @returns {Number} - if mapped topic exists return topic alias, otherwise return undefined
  56. */
  57. TopicAliasSend.prototype.getAliasByTopic = function (topic) {
  58. const alias = this.topicToAlias[topic]
  59. if (typeof alias !== 'undefined') {
  60. this.aliasToTopic.get(alias) // LRU update
  61. }
  62. return alias
  63. }
  64. /**
  65. * Clear all entries
  66. */
  67. TopicAliasSend.prototype.clear = function () {
  68. this.aliasToTopic.reset()
  69. this.topicToAlias = {}
  70. this.numberAllocator.clear()
  71. this.length = 0
  72. }
  73. /**
  74. * Get Least Recently Used (LRU) topic alias
  75. * @returns {Number} - if vacant alias exists then return it, otherwise then return LRU alias
  76. */
  77. TopicAliasSend.prototype.getLruAlias = function () {
  78. const alias = this.numberAllocator.firstVacant()
  79. if (alias) return alias
  80. return this.aliasToTopic.keys()[this.aliasToTopic.length - 1]
  81. }
  82. module.exports = TopicAliasSend