File Explorer

/var/runtime/node_modules/@aws-sdk/node_modules/mnemonist

This explorer reads the filesystem of the server it runs on, so /workspace/user isn't present here. Browsing and the terminal still work against this server's own disk from /.

2 dirs
86 files
semi-dynamic-trie.js4.9 KB · 252 lines
/* eslint no-constant-condition: 0 *//** * Mnemonist SemiDynamicTrie * ========================== * * Lowlevel Trie working at character level, storing information in typed * array and organizing its children in linked lists. * * This implementation also uses a "fat node" strategy to boost access to some * bloated node's children when the number of children rises above a certain * threshold. */var Vector = require('./vector.js'); // TODO: rename => ternary search tree /** * Constants. */const MAX_LINKED = 7; /** * SemiDynamicTrie. * * @constructor */function SemiDynamicTrie() {   // Properties   // TODO: make it 16 bits  this.characters = new Vector.Uint8Vector(256);  this.nextPointers = new Vector.Int32Vector(256);  this.childPointers = new Vector.Uint32Vector(256);  this.maps = new Vector.Uint32Vector(256);} /** * Method used to clear the structure. * * @return {undefined} */SemiDynamicTrie.prototype.clear = function() {   // Properties}; SemiDynamicTrie.prototype.ensureSibling = function(block, character) {  var nextCharacter,      nextBlock,      newBlock;   // Do we have a root?  if (this.characters.length === 0) {     this.nextPointers.push(0);    this.childPointers.push(0);    this.characters.push(character);     return block;  }   // Are we traversing a fat node?  var fatNode = this.nextPointers.array[block];   if (fatNode < 0) {    var mapIndex = -fatNode + character;     nextBlock = this.maps.array[mapIndex];     if (nextBlock !== 0)      return nextBlock;     newBlock = this.characters.length;     this.nextPointers.push(0);    this.childPointers.push(0);    this.characters.push(character);     this.maps.set(mapIndex, newBlock);     return newBlock;  }   var listLength = 1,      startingBlock = block;   while (true) {    nextCharacter = this.characters.array[block];     if (nextCharacter === character)      return block;     nextBlock = this.nextPointers.array[block];     if (nextBlock === 0)      break;     listLength++;    block = nextBlock;  }   // If the list is too long, we create a fat node  if (listLength > MAX_LINKED) {    block = startingBlock;     var offset = this.maps.length;     this.maps.resize(offset + 255);    this.maps.set(offset + 255, 0);     while (true) {      nextBlock = this.nextPointers.array[block];       if (nextBlock === 0)        break;       nextCharacter = this.characters.array[nextBlock];      this.maps.set(offset + nextCharacter, nextBlock);       block = nextBlock;    }     this.nextPointers.set(startingBlock, -offset);     newBlock = this.characters.length;     this.nextPointers.push(0);    this.childPointers.push(0);    this.characters.push(character);     this.maps.set(offset + character, newBlock);     return newBlock;  }   // Else, we append the character to the list  newBlock = this.characters.length;   this.nextPointers.push(0);  this.childPointers.push(0);  this.nextPointers.set(block, newBlock);  this.characters.push(character);   return newBlock;}; SemiDynamicTrie.prototype.findSibling = function(block, character) {  var nextCharacter;   // Do we have a fat node?  var fatNode = this.nextPointers.array[block];   if (fatNode < 0) {    var mapIndex = -fatNode + character;     var nextBlock = this.maps.array[mapIndex];     if (nextBlock === 0)      return -1;     return nextBlock;  }   while (true) {    nextCharacter = this.characters.array[block];     if (nextCharacter === character)      return block;     block = this.nextPointers.array[block];     if (block === 0)      return -1;  }}; SemiDynamicTrie.prototype.add = function(key) {  var keyCharacter,      childBlock,      block = 0;   var i = 0, l = key.length;   // Going as far as possible  while (i < l) {    keyCharacter = key.charCodeAt(i);     // Ensuring a correct sibling exists    block = this.ensureSibling(block, keyCharacter);     i++;     if (i < l) {       // Descending      childBlock = this.childPointers.array[block];       if (childBlock === 0)        break;       block = childBlock;    }  }   // Adding as many blocks as necessary  while (i < l) {     childBlock = this.characters.length;    this.characters.push(key.charCodeAt(i));     this.childPointers.push(0);    this.nextPointers.push(0);    this.childPointers.set(block, childBlock);     block = childBlock;     i++;  }}; SemiDynamicTrie.prototype.has = function(key) {  var i, l;   var block = 0,      siblingBlock;   for (i = 0, l = key.length; i < l; i++) {    siblingBlock = this.findSibling(block, key.charCodeAt(i));     if (siblingBlock === -1)      return false;     // TODO: be sure    if (i === l - 1)      return true;     block = this.childPointers.array[siblingBlock];     if (block === 0)      return false;  }   // TODO: fix, should have a leaf pointer somehow  return true;}; /** * Exporting. */module.exports = SemiDynamicTrie;