File Explorer

/proc/self/root/proc/self/root/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 /.

bit-set.js7.5 KB · 380 lines
/** * Mnemonist BitSet * ================= * * JavaScript implementation of a fixed-size BitSet based upon a Uint32Array. * * Notes: *   - (i >> 5) is the same as ((i / 32) | 0) *   - (i & 0x0000001f) is the same as (i % 32) *   - I could use a Float64Array to store more in less blocks but I would lose *     the benefits of byte comparison to keep track of size without popcounts. */var Iterator = require('obliterator/iterator'),    bitwise = require('./utils/bitwise.js'); /** * BitSet. * * @constructor */function BitSet(length) {   // Properties  this.length = length;  this.clear();   // Methods   // Statics} /** * Method used to clear the bit set. * * @return {undefined} */BitSet.prototype.clear = function() {   // Properties  this.size = 0;  this.array = new Uint32Array(Math.ceil(this.length / 32));}; /** * Method used to set the given bit's value. * * @param  {number} index - Target bit index. * @param  {number} value - Value to set. * @return {BitSet} */BitSet.prototype.set = function(index, value) {  var byteIndex = index >> 5,      pos = index & 0x0000001f,      oldBytes = this.array[byteIndex],      newBytes;   if (value === 0 || value === false)    newBytes = this.array[byteIndex] &= ~(1 << pos);  else    newBytes = this.array[byteIndex] |= (1 << pos);   // The operands of all bitwise operators are converted to *signed* 32-bit integers.  // Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Signed_32-bit_integers  // Shifting by 31 changes the sign (i.e. 1 << 31 = -2147483648).  // Therefore, get unsigned representation by applying '>>> 0'.  newBytes = newBytes >>> 0;   // Updating size  if (newBytes > oldBytes)    this.size++;  else if (newBytes < oldBytes)    this.size--;   return this;}; /*** Method used to reset the given bit's value.** @param  {number} index - Target bit index.* @return {BitSet}*/BitSet.prototype.reset = function(index) {  var byteIndex = index >> 5,      pos = index & 0x0000001f,      oldBytes = this.array[byteIndex],      newBytes;   newBytes = this.array[byteIndex] &= ~(1 << pos);   // Updating size  if (newBytes < oldBytes)    this.size--;   return this;}; /** * Method used to flip the value of the given bit. * * @param  {number} index - Target bit index. * @return {BitSet} */BitSet.prototype.flip = function(index) {  var byteIndex = index >> 5,      pos = index & 0x0000001f,      oldBytes = this.array[byteIndex];   var newBytes = this.array[byteIndex] ^= (1 << pos);   // Get unsigned representation.  newBytes = newBytes >>> 0;   // Updating size  if (newBytes > oldBytes)    this.size++;  else if (newBytes < oldBytes)    this.size--;   return this;}; /** * Method used to get the given bit's value. * * @param  {number} index - Target bit index. * @return {number} */BitSet.prototype.get = function(index) {  var byteIndex = index >> 5,      pos = index & 0x0000001f;   return (this.array[byteIndex] >> pos) & 1;}; /** * Method used to test the given bit's value. * * @param  {number} index - Target bit index. * @return {BitSet} */BitSet.prototype.test = function(index) {  return Boolean(this.get(index));}; /** * Method used to return the number of 1 from the beginning of the set up to * the ith index. * * @param  {number} i - Ith index (cannot be > length). * @return {number} */BitSet.prototype.rank = function(i) {  if (this.size === 0)    return 0;   var byteIndex = i >> 5,      pos = i & 0x0000001f,      r = 0;   // Accessing the bytes before the last one  for (var j = 0; j < byteIndex; j++)    r += bitwise.table8Popcount(this.array[j]);   // Handling masked last byte  var maskedByte = this.array[byteIndex] & ((1 << pos) - 1);   r += bitwise.table8Popcount(maskedByte);   return r;}; /** * Method used to return the position of the rth 1 in the set or -1 if the * set is empty. * * Note: usually select is implemented using binary search over rank but I * tend to think the following linear implementation is faster since here * rank is O(n) anyway. * * @param  {number} r - Rth 1 to select (should be < length). * @return {number} */BitSet.prototype.select = function(r) {  if (this.size === 0)    return -1;   // TODO: throw?  if (r >= this.length)    return -1;   var byte,      b = 32,      p = 0,      c = 0;   for (var i = 0, l = this.array.length; i < l; i++) {    byte = this.array[i];     // The byte is empty, let's continue    if (byte === 0)      continue;     // TODO: This branching might not be useful here    if (i === l - 1)      b = this.length % 32 || 32;     // TODO: popcount should speed things up here     for (var j = 0; j < b; j++, p++) {      c += (byte >> j) & 1;       if (c === r)        return p;    }  }}; /** * Method used to iterate over the bit set's values. * * @param  {function}  callback - Function to call for each item. * @param  {object}    scope    - Optional scope. * @return {undefined} */BitSet.prototype.forEach = function(callback, scope) {  scope = arguments.length > 1 ? scope : this;   var length = this.length,      byte,      bit,      b = 32;   for (var i = 0, l = this.array.length; i < l; i++) {    byte = this.array[i];     if (i === l - 1)      b = length % 32 || 32;     for (var j = 0; j < b; j++) {      bit = (byte >> j) & 1;       callback.call(scope, bit, i * 32 + j);    }  }}; /** * Method used to create an iterator over a set's values. * * @return {Iterator} */BitSet.prototype.values = function() {  var length = this.length,      inner = false,      byte,      bit,      array = this.array,      l = array.length,      i = 0,      j = -1,      b = 32;   return new Iterator(function next() {    if (!inner) {       if (i >= l)        return {          done: true        };       if (i === l - 1)        b = length % 32 || 32;       byte = array[i++];      inner = true;      j = -1;    }     j++;     if (j >= b) {      inner = false;      return next();    }     bit = (byte >> j) & 1;     return {      value: bit    };  });}; /** * Method used to create an iterator over a set's entries. * * @return {Iterator} */BitSet.prototype.entries = function() {  var length = this.length,      inner = false,      byte,      bit,      array = this.array,      index,      l = array.length,      i = 0,      j = -1,      b = 32;   return new Iterator(function next() {    if (!inner) {       if (i >= l)        return {          done: true        };       if (i === l - 1)        b = length % 32 || 32;       byte = array[i++];      inner = true;      j = -1;    }     j++;    index = (~-i) * 32 + j;     if (j >= b) {      inner = false;      return next();    }     bit = (byte >> j) & 1;     return {      value: [index, bit]    };  });}; /** * Attaching the #.values method to Symbol.iterator if possible. */if (typeof Symbol !== 'undefined')  BitSet.prototype[Symbol.iterator] = BitSet.prototype.values; /** * Convenience known methods. */BitSet.prototype.inspect = function() {  var proxy = new Uint8Array(this.length);   this.forEach(function(bit, i) {    proxy[i] = bit;  });   // Trick so that node displays the name of the constructor  Object.defineProperty(proxy, 'constructor', {    value: BitSet,    enumerable: false  });   return proxy;}; if (typeof Symbol !== 'undefined')  BitSet.prototype[Symbol.for('nodejs.util.inspect.custom')] = BitSet.prototype.inspect; BitSet.prototype.toJSON = function() {  return Array.from(this.array);}; /** * Exporting. */module.exports = BitSet;