@Override protected int writeData(final Data value, int hashCode) { int id = super.writeData(value, hashCode); ++valuesCount; if (IOStatistics.DEBUG && (valuesCount & IOStatistics.KEYS_FACTOR_MASK) == 0) { IOStatistics.dump( "Index " + myFile + ", values " + valuesCount + ", storage size:" + myStorage.length()); } return id; }
protected int enumerateImpl( final Data value, final boolean onlyCheckForExisting, boolean saveNewValue) throws IOException { try { lockStorage(); if (IntToIntBtree.doDump) System.out.println(value); final int valueHC = myDataDescriptor.getHashCode(value); final boolean hasMapping = btree.get(valueHC, myResultBuf); if (!hasMapping && onlyCheckForExisting) { return NULL_ID; } final int indexNodeValueAddress = hasMapping ? myResultBuf[0] : 0; int collisionAddress = NULL_ID; boolean hasExistingData = false; if (!myInlineKeysNoMapping) { collisionAddress = NULL_ID; if (indexNodeValueAddress > 0) { // we found reference to no dupe key if (isKeyAtIndex(value, indexNodeValueAddress)) { if (!saveNewValue) { ++myExistingKeysEnumerated; return indexNodeValueAddress; } hasExistingData = true; } collisionAddress = indexNodeValueAddress; } else if (indexNodeValueAddress < 0) { // indexNodeValueAddress points to duplicates list collisionAddress = -indexNodeValueAddress; while (true) { final int address = myStorage.getInt(collisionAddress); if (isKeyAtIndex(value, address)) { if (!saveNewValue) return address; hasExistingData = true; break; } int newCollisionAddress = myStorage.getInt(collisionAddress + COLLISION_OFFSET); if (newCollisionAddress == 0) break; collisionAddress = newCollisionAddress; } } if (onlyCheckForExisting) return NULL_ID; } else { if (hasMapping) { if (!saveNewValue) return indexNodeValueAddress; hasExistingData = true; } } int newValueId = writeData(value, valueHC); ++myValuesCount; if (IOStatistics.DEBUG && (myValuesCount & IOStatistics.KEYS_FACTOR_MASK) == 0) { IOStatistics.dump( "Index " + myFile + ", values " + myValuesCount + ", existing keys enumerated:" + myExistingKeysEnumerated + ", storage size:" + myStorage.length()); btree.dumpStatistics(); } if (collisionAddress != NULL_ID) { if (hasExistingData) { if (indexNodeValueAddress > 0) { btree.put(valueHC, newValueId); } else { myStorage.putInt(collisionAddress, newValueId); } } else { if (indexNodeValueAddress > 0) { // organize collision type reference int duplicatedValueOff = nextDuplicatedValueRecord(); btree.put(valueHC, -duplicatedValueOff); myStorage.putInt( duplicatedValueOff, indexNodeValueAddress); // we will set collision offset in next if collisionAddress = duplicatedValueOff; ++myCollisions; } ++myCollisions; int duplicatedValueOff = nextDuplicatedValueRecord(); myStorage.putInt(collisionAddress + COLLISION_OFFSET, duplicatedValueOff); myStorage.putInt(duplicatedValueOff, newValueId); myStorage.putInt(duplicatedValueOff + COLLISION_OFFSET, 0); } } else { btree.put(valueHC, newValueId); } if (IntToIntBtree.doSanityCheck) { if (!myInlineKeysNoMapping) { Data data = valueOf(newValueId); IntToIntBtree.myAssert(myDataDescriptor.isEqual(value, data)); } } return newValueId; } catch (IllegalStateException e) { CorruptedException exception = new CorruptedException(myFile); exception.initCause(e); throw exception; } finally { unlockStorage(); } }