UNPKG

antlr4ts

Version:

ANTLR 4 runtime for JavaScript written in Typescript

366 lines 12 kB
"use strict"; /*! * Copyright 2016 The ANTLR Project. All rights reserved. * Licensed under the BSD-3-Clause license. See LICENSE file in the project root for license information. */ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Array2DHashSet = void 0; // ConvertTo-TS run at 2016-10-03T02:09:41.7434086-07:00 const assert = require("assert"); const DefaultEqualityComparator_1 = require("./DefaultEqualityComparator"); const Decorators_1 = require("../Decorators"); const MurmurHash_1 = require("./MurmurHash"); /** {@link Set} implementation with closed hashing (open addressing). */ // NOTE: JavaScript's Set interface has on significant different diffrence from Java's: // e.g. the return type of add() differs! // For this reason I've commented tweaked the implements clause const INITAL_CAPACITY = 16; // must be power of 2 const LOAD_FACTOR = 0.75; class Array2DHashSet { constructor(comparatorOrSet, initialCapacity = INITAL_CAPACITY) { /** How many elements in set */ this.n = 0; this.threshold = Math.floor(INITAL_CAPACITY * LOAD_FACTOR); // when to expand if (comparatorOrSet instanceof Array2DHashSet) { this.comparator = comparatorOrSet.comparator; this.buckets = comparatorOrSet.buckets.slice(0); for (let i = 0; i < this.buckets.length; i++) { let bucket = this.buckets[i]; if (bucket) { this.buckets[i] = bucket.slice(0); } } this.n = comparatorOrSet.n; this.threshold = comparatorOrSet.threshold; } else { this.comparator = comparatorOrSet || DefaultEqualityComparator_1.DefaultEqualityComparator.INSTANCE; this.buckets = this.createBuckets(initialCapacity); } } /** * Add `o` to set if not there; return existing value if already * there. This method performs the same operation as {@link #add} aside from * the return value. */ getOrAdd(o) { if (this.n > this.threshold) { this.expand(); } return this.getOrAddImpl(o); } getOrAddImpl(o) { let b = this.getBucket(o); let bucket = this.buckets[b]; // NEW BUCKET if (!bucket) { bucket = [o]; this.buckets[b] = bucket; this.n++; return o; } // LOOK FOR IT IN BUCKET for (let existing of bucket) { if (this.comparator.equals(existing, o)) { return existing; // found existing, quit } } // FULL BUCKET, expand and add to end bucket.push(o); this.n++; return o; } get(o) { if (o == null) { return o; } let b = this.getBucket(o); let bucket = this.buckets[b]; if (!bucket) { // no bucket return undefined; } for (let e of bucket) { if (this.comparator.equals(e, o)) { return e; } } return undefined; } getBucket(o) { let hash = this.comparator.hashCode(o); let b = hash & (this.buckets.length - 1); // assumes len is power of 2 return b; } hashCode() { let hash = MurmurHash_1.MurmurHash.initialize(); for (let bucket of this.buckets) { if (bucket == null) { continue; } for (let o of bucket) { if (o == null) { break; } hash = MurmurHash_1.MurmurHash.update(hash, this.comparator.hashCode(o)); } } hash = MurmurHash_1.MurmurHash.finish(hash, this.size); return hash; } equals(o) { if (o === this) { return true; } if (!(o instanceof Array2DHashSet)) { return false; } if (o.size !== this.size) { return false; } let same = this.containsAll(o); return same; } expand() { let old = this.buckets; let newCapacity = this.buckets.length * 2; let newTable = this.createBuckets(newCapacity); this.buckets = newTable; this.threshold = Math.floor(newCapacity * LOAD_FACTOR); // System.out.println("new size="+newCapacity+", thres="+threshold); // rehash all existing entries let oldSize = this.size; for (let bucket of old) { if (!bucket) { continue; } for (let o of bucket) { let b = this.getBucket(o); let newBucket = this.buckets[b]; if (!newBucket) { newBucket = []; this.buckets[b] = newBucket; } newBucket.push(o); } } assert(this.n === oldSize); } add(t) { let existing = this.getOrAdd(t); return existing === t; } get size() { return this.n; } get isEmpty() { return this.n === 0; } contains(o) { return this.containsFast(this.asElementType(o)); } containsFast(obj) { if (obj == null) { return false; } return this.get(obj) != null; } *[Symbol.iterator]() { yield* this.toArray(); } toArray() { const a = new Array(this.size); // Copy elements from the nested arrays into the destination array let i = 0; // Position within destination array for (let bucket of this.buckets) { if (bucket == null) { continue; } for (let o of bucket) { if (o == null) { break; } a[i++] = o; } } return a; } containsAll(collection) { if (collection instanceof Array2DHashSet) { let s = collection; for (let bucket of s.buckets) { if (bucket == null) { continue; } for (let o of bucket) { if (o == null) { break; } if (!this.containsFast(this.asElementType(o))) { return false; } } } } else { for (let o of collection) { if (!this.containsFast(this.asElementType(o))) { return false; } } } return true; } addAll(c) { let changed = false; for (let o of c) { let existing = this.getOrAdd(o); if (existing !== o) { changed = true; } } return changed; } clear() { this.buckets = this.createBuckets(INITAL_CAPACITY); this.n = 0; this.threshold = Math.floor(INITAL_CAPACITY * LOAD_FACTOR); } toString() { if (this.size === 0) { return "{}"; } let buf = "{"; let first = true; for (let bucket of this.buckets) { if (bucket == null) { continue; } for (let o of bucket) { if (o == null) { break; } if (first) { first = false; } else { buf += ", "; } buf += o.toString(); } } buf += "}"; return buf; } toTableString() { let buf = ""; for (let bucket of this.buckets) { if (bucket == null) { buf += "null\n"; continue; } buf += "["; let first = true; for (let o of bucket) { if (first) { first = false; } else { buf += " "; } if (o == null) { buf += "_"; } else { buf += o.toString(); } } buf += "]\n"; } return buf; } /** * Return `o` as an instance of the element type `T`. If * `o` is non-undefined but known to not be an instance of `T`, this * method returns `undefined`. The base implementation does not perform any * type checks; override this method to provide strong type checks for the * {@link #contains} and {@link #remove} methods to ensure the arguments to * the {@link EqualityComparator} for the set always have the expected * types. * * @param o the object to try and cast to the element type of the set * @returns `o` if it could be an instance of `T`, otherwise * `undefined`. */ asElementType(o) { return o; } /** * Return an array of `T[]` with length `capacity`. * * @param capacity the length of the array to return * @returns the newly constructed array */ createBuckets(capacity) { return new Array(capacity); } } __decorate([ Decorators_1.NotNull ], Array2DHashSet.prototype, "comparator", void 0); __decorate([ Decorators_1.Override ], Array2DHashSet.prototype, "hashCode", null); __decorate([ Decorators_1.Override ], Array2DHashSet.prototype, "equals", null); __decorate([ Decorators_1.Override ], Array2DHashSet.prototype, "add", null); __decorate([ Decorators_1.Override ], Array2DHashSet.prototype, "size", null); __decorate([ Decorators_1.Override ], Array2DHashSet.prototype, "isEmpty", null); __decorate([ Decorators_1.Override ], Array2DHashSet.prototype, "contains", null); __decorate([ __param(0, Decorators_1.Nullable) ], Array2DHashSet.prototype, "containsFast", null); __decorate([ Decorators_1.Override ], Array2DHashSet.prototype, Symbol.iterator, null); __decorate([ Decorators_1.Override ], Array2DHashSet.prototype, "toArray", null); __decorate([ Decorators_1.Override ], Array2DHashSet.prototype, "containsAll", null); __decorate([ Decorators_1.Override ], Array2DHashSet.prototype, "addAll", null); __decorate([ Decorators_1.Override ], Array2DHashSet.prototype, "clear", null); __decorate([ Decorators_1.Override ], Array2DHashSet.prototype, "toString", null); __decorate([ Decorators_1.SuppressWarnings("unchecked") ], Array2DHashSet.prototype, "asElementType", null); __decorate([ Decorators_1.SuppressWarnings("unchecked") ], Array2DHashSet.prototype, "createBuckets", null); exports.Array2DHashSet = Array2DHashSet; //# sourceMappingURL=Array2DHashSet.js.map