From 1c1702cb52bc5304d0b248d98c0e5b3f01118f65 Mon Sep 17 00:00:00 2001 From: Anton Persson Date: Thu, 11 Jan 2018 10:49:36 +0100 Subject: [PATCH] Better javadoc for DynamicSizeUtil --- .../internal/gbptree/DynamicSizeUtil.java | 82 ++++++++++--------- .../internal/gbptree/TreeNodeDynamicSize.java | 22 ++--- 2 files changed, 56 insertions(+), 48 deletions(-) diff --git a/community/index/src/main/java/org/neo4j/index/internal/gbptree/DynamicSizeUtil.java b/community/index/src/main/java/org/neo4j/index/internal/gbptree/DynamicSizeUtil.java index d84653476a9d1..f35830f254a1e 100644 --- a/community/index/src/main/java/org/neo4j/index/internal/gbptree/DynamicSizeUtil.java +++ b/community/index/src/main/java/org/neo4j/index/internal/gbptree/DynamicSizeUtil.java @@ -25,31 +25,52 @@ import static org.neo4j.index.internal.gbptree.PageCursorUtil.putUnsignedShort; /** - * keySize and valueSize indicate size of key and value in number of bytes. + * Gather utility methods for reading and writing individual dynamic sized + * keys. It thus define the layout for: + * - Key pointer in offset array (K*), 2B + * - Key size, 2B + * - Value size, 2B + * - Key tombstone, first bit in key size * - * In LEAF: - * [keySize 2B|valueSize 2B|actualKey|actualValue] - * - * In INTERNAL: - * [keySize 2B|actualKey] + * Relative layout of key and key_value + * KeyOffset points to the exact offset where key entry or key_value entry + * can be read. + * key entry - [keySize 2B|actualKey] + * key_value entry - [keySize 2B|valueSize 2B|actualKey|actualValue] * + * Tombstone * First bit in keySize is used as a tombstone, set to 1 if key is dead. * This leaves 15 bits for actual size -> max possible key size is 32768 bytes * which is more than page size and therefore be enough. */ class DynamicSizeUtil { - static final int BYTE_SIZE_OFFSET = 2; - static final int BYTE_SIZE_KEY_SIZE = 2; - static final int BYTE_SIZE_VALUE_SIZE = 2; - static final int BYTE_SIZE_TOTAL_OVERHEAD = BYTE_SIZE_OFFSET + BYTE_SIZE_KEY_SIZE + BYTE_SIZE_VALUE_SIZE; - static final int FLAG_TOMBSTONE = 0x8000; + static final int SIZE_OFFSET = 2; + static final int SIZE_KEY_SIZE = 2; + static final int SIZE_VALUE_SIZE = 2; + static final int SIZE_TOTAL_OVERHEAD = SIZE_OFFSET + SIZE_KEY_SIZE + SIZE_VALUE_SIZE; + private static final int FLAG_TOMBSTONE = 0x8000; + + static void putKeyOffset( PageCursor cursor, int keyOffset ) + { + putUnsignedShort( cursor, keyOffset ); + } static int readKeyOffset( PageCursor cursor ) { return getUnsignedShort( cursor ); } + static void putKeySize( PageCursor cursor, int keySize ) + { + putUnsignedShort( cursor, keySize ); + } + + static void putValueSize( PageCursor cursor, int valueSize ) + { + putUnsignedShort( cursor, valueSize ); + } + /** * Read key size including possible tombstone. * Check for tombstone with {@link #hasTombstone(int)}. @@ -61,35 +82,11 @@ static int readKeySize( PageCursor cursor ) return getUnsignedShort( cursor ); } - /** - * Check read key size for tombstone. - * @return True if read key size has tombstone. - */ - static boolean hasTombstone( int readKeySize ) - { - return (readKeySize & FLAG_TOMBSTONE) != 0; - } - static int readValueSize( PageCursor cursor ) { return getUnsignedShort( cursor ); } - static void putKeyOffset( PageCursor cursor, int keyOffset ) - { - putUnsignedShort( cursor, keyOffset ); - } - - static void putKeySize( PageCursor cursor, int keySize ) - { - putUnsignedShort( cursor, keySize ); - } - - static void putValueSize( PageCursor cursor, int valueSize ) - { - putUnsignedShort( cursor, valueSize ); - } - /** * Put a tombstone into key size. * @param cursor on offset to key size where tombstone should be put. @@ -103,14 +100,23 @@ static void putTombstone( PageCursor cursor ) putKeySize( cursor, keySize ); } - private static int withTombstoneFlag( int keySize ) + /** + * Check read key size for tombstone. + * @return True if read key size has tombstone. + */ + static boolean hasTombstone( int readKeySize ) { - assert (keySize & FLAG_TOMBSTONE) == 0 : "Key size " + keySize + " is to large to fit tombstone."; - return keySize | FLAG_TOMBSTONE; + return (readKeySize & FLAG_TOMBSTONE) != 0; } static int stripTombstone( int keySize ) { return keySize & ~FLAG_TOMBSTONE; } + + private static int withTombstoneFlag( int keySize ) + { + assert (keySize & FLAG_TOMBSTONE) == 0 : "Key size " + keySize + " is to large to fit tombstone."; + return keySize | FLAG_TOMBSTONE; + } } diff --git a/community/index/src/main/java/org/neo4j/index/internal/gbptree/TreeNodeDynamicSize.java b/community/index/src/main/java/org/neo4j/index/internal/gbptree/TreeNodeDynamicSize.java index 6474494fa9fdb..2c97cd4bdc671 100644 --- a/community/index/src/main/java/org/neo4j/index/internal/gbptree/TreeNodeDynamicSize.java +++ b/community/index/src/main/java/org/neo4j/index/internal/gbptree/TreeNodeDynamicSize.java @@ -26,10 +26,10 @@ import org.neo4j.io.pagecache.PageCursor; import static java.lang.String.format; -import static org.neo4j.index.internal.gbptree.DynamicSizeUtil.BYTE_SIZE_KEY_SIZE; -import static org.neo4j.index.internal.gbptree.DynamicSizeUtil.BYTE_SIZE_OFFSET; -import static org.neo4j.index.internal.gbptree.DynamicSizeUtil.BYTE_SIZE_TOTAL_OVERHEAD; -import static org.neo4j.index.internal.gbptree.DynamicSizeUtil.BYTE_SIZE_VALUE_SIZE; +import static org.neo4j.index.internal.gbptree.DynamicSizeUtil.SIZE_KEY_SIZE; +import static org.neo4j.index.internal.gbptree.DynamicSizeUtil.SIZE_OFFSET; +import static org.neo4j.index.internal.gbptree.DynamicSizeUtil.SIZE_TOTAL_OVERHEAD; +import static org.neo4j.index.internal.gbptree.DynamicSizeUtil.SIZE_VALUE_SIZE; import static org.neo4j.index.internal.gbptree.DynamicSizeUtil.hasTombstone; import static org.neo4j.index.internal.gbptree.DynamicSizeUtil.putKeyOffset; import static org.neo4j.index.internal.gbptree.DynamicSizeUtil.putKeySize; @@ -56,6 +56,8 @@ * [ HEADER 86B ]|[ KEY_OFFSET_CHILDREN ]######[ KEYS ] * [NODETYPE][TYPE][GENERATION][KEYCOUNT][RIGHTSIBLING][LEFTSIBLING][SUCCESSOR][ALLOCOFFSET][DEADSPACE]|[C0,K0*,C1,K1*,C2,K2*,C3]-> <-[K2,K0,K1] * 0 1 2 6 10 34 58 82 84 86 + * + * See {@link DynamicSizeUtil} for more detailed layout for individual offset array entries and key / key_value entries. */ public class TreeNodeDynamicSize extends TreeNode { @@ -76,7 +78,7 @@ public class TreeNodeDynamicSize extends TreeNode { super( pageSize, layout ); - keyValueSizeCap = totalSpace( pageSize ) / LEAST_NUMBER_OF_ENTRIES_PER_PAGE - BYTE_SIZE_TOTAL_OVERHEAD; + keyValueSizeCap = totalSpace( pageSize ) / LEAST_NUMBER_OF_ENTRIES_PER_PAGE - SIZE_TOTAL_OVERHEAD; if ( keyValueSizeCap < MINIMUM_ENTRY_SIZE_CAP ) { @@ -326,7 +328,7 @@ void setChildAt( PageCursor cursor, long child, int pos, long stableGeneration, @Override boolean reasonableKeyCount( int keyCount ) { - return keyCount >= 0 && keyCount <= totalSpace( pageSize ) / BYTE_SIZE_TOTAL_OVERHEAD; + return keyCount >= 0 && keyCount <= totalSpace( pageSize ) / SIZE_TOTAL_OVERHEAD; } @Override @@ -1118,22 +1120,22 @@ private int childSize() private static int bytesKeySize() { - return BYTE_SIZE_KEY_SIZE; + return SIZE_KEY_SIZE; } private static int bytesValueSize() { - return BYTE_SIZE_VALUE_SIZE; + return SIZE_VALUE_SIZE; } private static int bytesKeyOffset() { - return BYTE_SIZE_OFFSET; + return SIZE_OFFSET; } private static int bytesPageOffset() { - return BYTE_SIZE_OFFSET; + return SIZE_OFFSET; } @Override