private CharsToNameCanonicalizer makeOrphan(int seed) { return new CharsToNameCanonicalizer(null, true, true, _symbols, _buckets, _size, seed, _longestCollisionList); }
private void initTables(int initialSize) { _symbols = new String[initialSize]; _buckets = new Bucket[initialSize >> 1]; // Mask is easy to calc for powers of two. _indexMask = initialSize - 1; _size = 0; _longestCollisionList = 0; // Hard-coded fill factor is 75% _sizeThreshold = _thresholdSize(initialSize); }
private static Name constructName(int hash, String name, int[] quads, int qlen) { if (qlen < 4) { // Need to check for 3 quad one, can do others too switch (qlen) { case 1: return new Name1(name, hash, quads[0]); case 2: return new Name2(name, hash, quads[0], quads[1]); case 3: return new Name3(name, hash, quads[0], quads[1], quads[2]); default: } } // Otherwise, need to copy the incoming buffer int[] buf = new int[qlen]; for (int i = 0; i < qlen; ++i) { buf[i] = quads[i]; } return new NameN(name, hash, buf, qlen); }
public Name addName(String symbolStr, int q1, int q2) { if (_intern) { symbolStr = InternCache.instance.intern(symbolStr); } int hash = (q2 == 0) ? calcHash(q1) : calcHash(q1, q2); Name symbol = constructName(hash, symbolStr, q1, q2); _addSymbol(hash, symbol); return symbol; }
public Name find(int hash, int[] quads, int qlen) { if (_name.hashCode() == hash) { if (_name.equals(quads, qlen)) { return _name; } } for (Bucket curr = _next; curr != null; curr = curr._next) { Name currName = curr._name; if (currName.hashCode() == hash) { if (currName.equals(quads, qlen)) { return currName; } } } return null; } }
/** * Method called by the using code to indicate it is done * with this instance. This lets instance merge accumulated * changes into parent (if need be), safely and efficiently, * and without calling code having to know about parent * information */ public void release() { // we will try to merge if child table has new entries if (_parent != null && maybeDirty()) { _parent.mergeChild(new TableInfo(this)); /* Let's also mark this instance as dirty, so that just in * case release was too early, there's no corruption of possibly shared data. */ _mainHashShared = true; _mainNamesShared = true; _collListShared = true; } }
public void release() { // If nothing has been added, nothing to do if (!maybeDirty()) { return; } if (_parent != null) { _parent.mergeChild(this); /* Let's also mark this instance as dirty, so that just in * case release was too early, there's no corruption * of possibly shared data. */ _dirty = false; } }
private final Name findName(int q1, int lastQuadBytes) throws JsonParseException { // Usually we'll find it from the canonical symbol table already Name name = _symbols.findName(q1); if (name != null) { return name; } // If not, more work. We'll need add stuff to buffer _quadBuffer[0] = q1; return addName(_quadBuffer, 1, lastQuadBytes); }
public static Name getEmptyName() { return Name1.getEmptyName(); }
/** * Factory method that should only be called from unit tests, where seed * value should remain the same. */ protected static BytesToNameCanonicalizer createRoot(int hashSeed) { return new BytesToNameCanonicalizer(DEFAULT_TABLE_SIZE, true, hashSeed); }
@Override public void close() throws IOException { super.close(); // Merge found symbols, if any: _symbols.release(); }
protected static CharsToNameCanonicalizer createRoot(int hashSeed) { return sBootstrapSymbolTable.makeOrphan(hashSeed); }
/** * Main method for constructing a master symbol table instance. * * @param initialSize Minimum initial size for bucket array; internally * will always use a power of two equal to or bigger than this value. */ private CharsToNameCanonicalizer() { // these settings don't really matter for the bootstrap instance _canonicalize = true; _intern = true; // And we'll also set flags so no copying of buckets is needed: _dirty = true; _hashSeed = 0; _longestCollisionList = 0; initTables(DEFAULT_TABLE_SIZE); }
@Override public void close() throws IOException { super.close(); _symbols.release(); }
private TableInfo initTableInfo(int hashSize) { return new TableInfo(0, // count hashSize - 1, // mainHashMask new int[hashSize], // mainHash new Name[hashSize], // mainNames null, // collList 0, // collCount, 0, // collEnd 0 // longestCollisionList ); }
/** * Method mostly needed by unit tests; calculates number of * entries that are in collision list. Value can be at most * ({@link #size} - 1), but should usually be much lower, ideally 0. * * @since 1.9.9 */ public int collisionCount() { int count = 0; for (Bucket bucket : _buckets) { if (bucket != null) { count += bucket.length(); } } return count; }
public Name find(int hash, int firstQuad, int secondQuad) { if (_name.hashCode() == hash) { if (_name.equals(firstQuad, secondQuad)) { return _name; } } for (Bucket curr = _next; curr != null; curr = curr._next) { Name currName = curr._name; if (currName.hashCode() == hash) { if (currName.equals(firstQuad, secondQuad)) { return currName; } } } return null; }
private final Name findName(int q1, int q2, int lastQuadBytes) throws JsonParseException { // Usually we'll find it from the canonical symbol table already Name name = _symbols.findName(q1, q2); if (name != null) { return name; } // If not, more work. We'll need add stuff to buffer _quadBuffer[0] = q1; _quadBuffer[1] = q2; return addName(_quadBuffer, 2, lastQuadBytes); }
/** * Factory method used to create actual symbol table instance to * use for parsing. * * @param intern Whether canonical symbol Strings should be interned * or not */ public BytesToNameCanonicalizer makeChild(boolean canonicalize, boolean intern) { return new BytesToNameCanonicalizer(this, intern, _hashSeed, _tableInfo.get()); }