private void updateRecord(PropertyRecord record, PersistenceWindow window) { long id = record.getId(); registerIdFromUpdateRecord(id); Buffer buffer = window.getOffsettedBuffer(id); if (record.inUse()) { // Set up the record header short prevModifier = record.getPrevProp() == Record.NO_NEXT_RELATIONSHIP.intValue() ? 0 : (short) ((record.getPrevProp() & 0xF00000000L) >> 28); short nextModifier = record.getNextProp() == Record.NO_NEXT_RELATIONSHIP.intValue() ? 0 : (short) ((record.getNextProp() & 0xF00000000L) >> 32); byte modifiers = (byte) (prevModifier | nextModifier); /* * [pppp,nnnn] previous, next high bits */ buffer.put(modifiers); buffer.putInt((int) record.getPrevProp()).putInt((int) record.getNextProp()); // Then go through the blocks int longsAppended = 0; // For marking the end of blocks for (PropertyBlock block : record.getPropertyBlocks()) { long[] propBlockValues = block.getValueBlocks(); for (long propBlockValue : propBlockValues) { buffer.putLong(propBlockValue); } longsAppended += propBlockValues.length; /* * For each block we need to update its dynamic record chain if * it is just created. Deleted dynamic records are in the property * record and dynamic records are never modified. Also, they are * assigned as a whole, so just checking the first should be enough. */ if (!block.isLight() && block.getValueRecords().get(0).isCreated()) { updateDynamicRecords(block.getValueRecords()); } } if (longsAppended < PropertyType.getPayloadSizeLongs()) { buffer.putLong(0); } } else { if (!isInRecoveryMode()) { freeId(id); } // skip over the record header, nothing useful there buffer.setOffset(buffer.getOffset() + 9); buffer.putLong(0); } updateDynamicRecords(record.getDeletedRecords()); }
public static Object decode(PropertyBlock block) { Bits bits = Bits.bitsFromLongs(Arrays.copyOf(block.getValueBlocks(), block.getValueBlocks().length)); // [][][ ,bbbb][bbll,llll][yyyy,tttt][kkkk,kkkk][kkkk,kkkk][kkkk,kkkk] bits.getInt(24); // Get rid of key bits.getByte(4); // Get rid of short array type int typeId = bits.getByte(4); int arrayLength = bits.getByte(6); int requiredBits = bits.getByte(6); /* * So, it can be the case that values require 64 bits to store. However, you cannot encode this * value with 6 bits. calculateRequiredBitsForArray never returns 0, because even for an array of * all 0s one bit is required for every value. So when writing, we let it overflow and write out * 0. When we are reading back, we just have to make sure that reading in 0 means 64. */ if (requiredBits == 0) { requiredBits = 64; } ShortArray type = typeOf((byte) typeId); return type.createArray(arrayLength, bits, requiredBits); }