public void put(KvSource kv, int keyHashCode) throws SerDeException { if (resizeThreshold <= keysAssigned) { expandAndRehash(); } // Reserve 4 bytes for the hash (don't just reserve, there may be junk there) writeBuffers.write(FOUR_ZEROES); // Write key to buffer to compute hashcode and compare; if it's a new key, it will // become part of the record; otherwise, we will just write over it later. long keyOffset = writeBuffers.getWritePoint(); kv.writeKey(writeBuffers); int keyLength = (int) (writeBuffers.getWritePoint() - keyOffset); int hashCode = (keyHashCode == -1) ? writeBuffers.hashCode(keyOffset, keyLength) : keyHashCode; int slot = findKeySlotToWrite(keyOffset, keyLength, hashCode); // LOG.info("Write hash code is " + Integer.toBinaryString(hashCode) + " - " + slot); long ref = refs[slot]; if (ref == 0) { // This is a new key, keep writing the first record. long tailOffset = writeFirstValueRecord(kv, keyOffset, keyLength, hashCode); byte stateByte = kv.updateStateByte(null); refs[slot] = Ref.makeFirstRef(tailOffset, stateByte, hashCode, startingHashBitCount); ++keysAssigned; } else { // This is not a new key; we'll overwrite the key and hash bytes - not needed anymore. writeBuffers.setWritePoint(keyOffset - 4); long lrPtrOffset = createOrGetListRecord(ref); long tailOffset = writeValueAndLength(kv); addRecordToList(lrPtrOffset, tailOffset); byte oldStateByte = Ref.getStateByte(ref); byte stateByte = kv.updateStateByte(oldStateByte); if (oldStateByte != stateByte) { ref = Ref.setStateByte(ref, stateByte); } refs[slot] = Ref.setListFlag(ref); } ++numValues; }