Skip to content

Instantly share code, notes, and snippets.

@Cfeusier
Last active May 14, 2018 20:47
Show Gist options
  • Save Cfeusier/5e9c963823a4c2c7567e to your computer and use it in GitHub Desktop.
Save Cfeusier/5e9c963823a4c2c7567e to your computer and use it in GitHub Desktop.
Hash Table implementation in JavaScript
var HashTable = function() {
this._limit = 8; // choose any size of hash table bucket limit
this._count = 0;
this._storage = [];
};
HashTable.prototype.insert = function(k, v) {
var i = this._getHashIndex(k, this._limit);
this._checkLimit(i); // make sure hashidx is in bounds
var bucket = this._storage[i];
if (!bucket) {
this._storage[i] = [];
}
var found = false;
for (var i = 0; i < bucket.length; i++) {
var tuple = bucket[i];
// found matching key
if (tuple[0] === k) {
// update key with new value
tuple[1] = v;
found = true;
break;
}
}
// no matching key found
if (!found) {
bucket.push([k,v]);
this._count++;
if (this._count > this._limit * 0.75) {
this._resize(this._limit * 2);
}
}
};
HashTable.prototype.retrieve = function(k) {
var i = this._getHashIndex(k, this._limit);
this._checkLimit(i);
var bucket = this._storage[i];
if (!bucket) {
return null;
}
for (var j = 0; j < bucket.length; j++) {
var tuple = bucket[j];
if (tuple[0] === k) {
return tuple[1];
}
}
return null;
};
HashTable.prototype.remove = function(k) {
var i = this._getHashIndex(k, this._limit);
this._checkLimit(i);
var bucket = this._storage[i];
if (!bucket) {
return null;
}
for (var j = 0; j < bucket.length; j++) {
var tuple = bucket[j];
if (tuple[0] === k) {
bucket.splice(j, 1);
this._count--;
if (this._count < this._limit * 0.25) {
this._resize(this._limit / 2);
}
return tuple[1];
}
}
return null;
};
// private methods _
HashTable.prototype._resize = function(newLimit) {
var oldStorage = this._storage;
this._storage = [];
this._limit = newLimit;
this._count = 0;
for (var j = 0; j < oldStorage.length; j++) {
var bucket = oldStorage[j];
if (!bucket) break;
for (var i = 0; i < bucket.length; i++) {
var tuple = bucket[i];
this.insert(tuple[0], tuple[1]);
}
}
};
HashTable.prototype._getHashIndex = function(str, max) {
var hash = 0;
for (var i = 0; i < str.length; i++) {
hash = (hash<<5) + hash + str.charCodeAt(i);
hash = hash & hash;
hash = Math.abs(hash);
}
return hash % max;
};
HashTable.prototype._checkLimit = function(index) {
if (typeof index !== 'number') {
throw new Error('first argument of setter must be a numeric index');
}
if (limit <= index) {
throw new Error('out-of-bounds index cannot be accessed');
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment