public ByteBasedPName find(int hash, int firstQuad, int secondQuad) { if (mName.hashCode() == hash) { if (mName.equals(firstQuad, secondQuad)) { return mName; } } for (Bucket curr = mNext; curr != null; curr = curr.mNext) { ByteBasedPName currName = curr.mName; if (currName.hashCode() == hash) { if (currName.equals(firstQuad, secondQuad)) { return currName; } } } return null; }
public ByteBasedPName find(int hash, int[] quads, int qlen) { if (mName.hashCode() == hash) { if (mName.equals(quads, qlen)) { return mName; } } for (Bucket curr = mNext; curr != null; curr = curr.mNext) { ByteBasedPName currName = curr.mName; if (currName.hashCode() == hash) { if (currName.equals(quads, qlen)) { return currName; } } } return null; }
private void rehash() { /* System.err.println("DEBUG: Rehashing!!!"); System.err.println("DEBUG: before rehash, "+toString()); System.err.println("-> ["); System.err.println(toDebugString()); System.err.println("DEBUG: ]"); */ mNeedRehash = false; // Note: since we'll make copies, no need to unshare, can just mark as such: mMainNamesShared = false; /* And then we can first deal with the main hash area. Since we * are expanding linearly (double up), we know there'll be no * collisions during this phase. */ int symbolsSeen = 0; // let's do a sanity check int[] oldMainHash = mMainHash; int len = oldMainHash.length; mMainHash = new int[len + len]; mMainHashMask = (len + len - 1); ByteBasedPName[] oldNames = mMainNames; mMainNames = new ByteBasedPName[len + len]; for (int i = 0; i < len; ++i) { ByteBasedPName symbol = oldNames[i]; if (symbol != null) { ++symbolsSeen; int hash = symbol.hashCode(); int ix = (hash & mMainHashMask); mMainNames[ix] = symbol; mMainHash[ix] = hash << 8; // will clear spill index } } /* And then the spill area. This may cause collisions, although * not necessarily as many as there were earlier. Let's allocate * same amount of space, however */ int oldEnd = mCollEnd; if (oldEnd == 0) { // no prior collisions... return; } mCollCount = 0; mCollEnd = 0; mCollListShared = false; Bucket[] oldBuckets = mCollList; mCollList = new Bucket[oldBuckets.length]; for (int i = 0; i < oldEnd; ++i) { for (Bucket curr = oldBuckets[i]; curr != null; curr = curr.mNext) { ++symbolsSeen; ByteBasedPName symbol = curr.mName; int hash = symbol.hashCode(); int ix = (hash & mMainHashMask); int val = mMainHash[ix]; if (mMainNames[ix] == null) { // no primary entry? mMainHash[ix] = (hash << 8); mMainNames[ix] = symbol; } else { // nope, it's a collision, need to spill over ++mCollCount; int bucket = val & 0xFF; if (bucket == 0) { // first spill over? if (mCollEnd <= LAST_VALID_BUCKET) { // yup, still unshared bucket bucket = mCollEnd; ++mCollEnd; // need to expand? if (bucket >= mCollList.length) { expandCollision(); } } else { // nope, have to share... let's find shortest? bucket = findBestBucket(); } // Need to mark the entry... and the spill index is 1-based mMainHash[ix] = (val & ~0xFF) | (bucket + 1); } else { --bucket; // 1-based index in value } // And then just need to link the new bucket entry in mCollList[bucket] = new Bucket(symbol, mCollList[bucket]); } } // for (... buckets in the chain ...) } // for (... list of bucket heads ... ) if (symbolsSeen != mCount) { // sanity check throw new Error( "Internal error: count after rehash " + symbolsSeen + "; should be " + mCount); } /* System.err.println("DEBUG: after rehash == ["); System.err.println(toDebugString()); System.err.println("DEBUG: ]"); */ }