185 lines
5.7 KiB
JavaScript
185 lines
5.7 KiB
JavaScript
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.HashSet = undefined;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
exports.hashBinary = hashBinary;
|
|
exports.hashCall = hashCall;
|
|
exports.hashTernary = hashTernary;
|
|
exports.hashString = hashString;
|
|
exports.hashUnary = hashUnary;
|
|
|
|
var _invariant = require("../invariant.js");
|
|
|
|
var _invariant2 = _interopRequireDefault(_invariant);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* Copyright (c) 2017-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
|
|
function hashBinary(op, x, y) {
|
|
var xHash = x.getHash();
|
|
var yHash = y.getHash();
|
|
if (yHash < xHash) {
|
|
// Check if the operation is commutative so that we can normalize the arguments on hash value order.
|
|
var commutative = void 0;
|
|
switch (op) {
|
|
case "*":
|
|
case "==":
|
|
case "!=":
|
|
case "===":
|
|
case "!==":
|
|
// If both operands might be objects, the operation does not commute because of the possibility
|
|
// that arbitrary code can run on both operands while converting them, in which case the order of the
|
|
// operands must be maintained to make sure any side-effects happen in the right order.
|
|
commutative = !(x.mightBeObject() && y.mightBeObject());
|
|
break;
|
|
case "+":
|
|
// As above, but in addition, if one of the operands might be a string the operation does not commute
|
|
commutative = !(x.mightBeObject() && y.mightBeObject()) && !(x.mightBeString() || y.mightBeString());
|
|
break;
|
|
default:
|
|
// The operation itself is not commutative
|
|
commutative = false;
|
|
break;
|
|
}
|
|
if (commutative) {
|
|
var _ref = [y, x];
|
|
x = _ref[0];
|
|
y = _ref[1];
|
|
var _ref2 = [yHash, xHash];
|
|
xHash = _ref2[0];
|
|
yHash = _ref2[1];
|
|
}
|
|
}
|
|
var hash = (hashString(op) * 13 ^ xHash) * 13 ^ yHash;
|
|
return [hash, [x, y]];
|
|
}
|
|
|
|
function hashCall(calleeName) {
|
|
var hash = hashString(calleeName);
|
|
|
|
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
args[_key - 1] = arguments[_key];
|
|
}
|
|
|
|
var _iteratorNormalCompletion = true;
|
|
var _didIteratorError = false;
|
|
var _iteratorError = undefined;
|
|
|
|
try {
|
|
for (var _iterator = args[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
var a = _step.value;
|
|
hash = hash * 13 ^ a.getHash();
|
|
}
|
|
} catch (err) {
|
|
_didIteratorError = true;
|
|
_iteratorError = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion && _iterator.return) {
|
|
_iterator.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError) {
|
|
throw _iteratorError;
|
|
}
|
|
}
|
|
}
|
|
|
|
return [hash, args];
|
|
}
|
|
|
|
function hashTernary(x, y, z) {
|
|
var hash = (x.getHash() * 13 ^ y.getHash()) * 13 ^ z.getHash();
|
|
return [hash, [x, y, z]];
|
|
}
|
|
|
|
function hashString(value) {
|
|
var hash = 5381;
|
|
for (var i = value.length - 1; i >= 0; i--) {
|
|
hash = hash * 33 ^ value.charCodeAt(i);
|
|
}
|
|
return hash;
|
|
}
|
|
|
|
function hashUnary(op, x) {
|
|
return hashString(op) * 13 ^ x.getHash();
|
|
}
|
|
|
|
var HashSet = exports.HashSet = function () {
|
|
function HashSet() {
|
|
var expectedEntries = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 32 * 1024;
|
|
|
|
_classCallCheck(this, HashSet);
|
|
|
|
var initialSize = 16;
|
|
expectedEntries *= 2;
|
|
while (initialSize < expectedEntries) {
|
|
initialSize *= 2;
|
|
}this._entries = new Array(initialSize);
|
|
this._count = 0;
|
|
}
|
|
|
|
_createClass(HashSet, [{
|
|
key: "add",
|
|
value: function add(e) {
|
|
var entries = this._entries;
|
|
var n = entries.length;
|
|
var key = e.getHash();
|
|
var i = key & n - 1;
|
|
while (true) {
|
|
var entry = entries[i];
|
|
if (entry === undefined) {
|
|
entries[i] = e;
|
|
if (++this._count > n / 2) this.expand();
|
|
return e;
|
|
} else if (e.equals(entry)) {
|
|
return entry;
|
|
}
|
|
if (++i >= n) i = 0;
|
|
}
|
|
(0, _invariant2.default)(false); // otherwise Flow thinks this method can return undefined
|
|
}
|
|
}, {
|
|
key: "expand",
|
|
value: function expand() {
|
|
var oldEntries = this._entries;
|
|
var n = oldEntries.length;
|
|
var m = n * 2;
|
|
if (m <= 0) return;
|
|
var entries = new Array(m);
|
|
for (var i = 0; i < n; i++) {
|
|
var oldEntry = oldEntries[i];
|
|
if (oldEntry === undefined) continue;
|
|
var key = oldEntry.getHash();
|
|
var j = key & m - 1;
|
|
while (true) {
|
|
var entry = entries[j];
|
|
if (entry === undefined) {
|
|
entries[j] = oldEntry;
|
|
break;
|
|
}
|
|
if (++j >= m) j = 0;
|
|
}
|
|
}
|
|
this._entries = entries;
|
|
}
|
|
}]);
|
|
|
|
return HashSet;
|
|
}();
|
|
//# sourceMappingURL=hash.js.map
|