"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