Files
2023-08-01 13:49:46 +02:00

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