From 5cbcda073c857f9eaeebb048bee83bb4f9cf3ba3 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Fri, 26 May 2017 16:16:22 +0200 Subject: [PATCH] [startup performance] lazy loading of ByteBuffer containing root --- .../com/intellij/util/io/IntToIntBtree.java | 70 ++++++++++++------- 1 file changed, 45 insertions(+), 25 deletions(-) diff --git a/platform/util/src/com/intellij/util/io/IntToIntBtree.java b/platform/util/src/com/intellij/util/io/IntToIntBtree.java index 81ae90b578ee..5d5d5f7b5b28 100644 --- a/platform/util/src/com/intellij/util/io/IntToIntBtree.java +++ b/platform/util/src/com/intellij/util/io/IntToIntBtree.java @@ -38,7 +38,7 @@ public class IntToIntBtree { private final short maxInteriorNodes; private final short maxLeafNodes; private final short maxLeafNodesInHash; - final BtreeIndexNodeView root; + final BtreeRootNode root; private int height; private int maxStepsSearchedInHash; private int totalHashStepsSearched; @@ -69,12 +69,12 @@ public class IntToIntBtree { } storage = new ResizeableMappedFile(file, pageSize, storageLockContext, 1024 * 1024, true, IOUtil.ourByteBuffersUseNativeByteOrder); - root = new BtreeIndexNodeView(this); + root = new BtreeRootNode(this); if (initial) { nextPage(); // allocate root root.setAddress(0); - root.setIndexLeaf(true); + root.getNodeView().setIndexLeaf(true); } int i = (this.pageSize - BtreePage.RESERVED_META_PAGE_LEN) / BtreeIndexNodeView.INTERIOR_SIZE - 1; @@ -133,6 +133,31 @@ public class IntToIntBtree { int persistInt(int offset, int value, boolean toDisk); } + static class BtreeRootNode { + int address; + final BtreeIndexNodeView nodeView; + boolean initialized; + + BtreeRootNode(IntToIntBtree btree) { + nodeView = new BtreeIndexNodeView(btree); + } + + void setAddress(int _address) { + address = _address; + initialized = false; + } + + protected void syncWithStore() { + nodeView.setAddress(address); + initialized = true; + } + + public BtreeIndexNodeView getNodeView() { + if (!initialized) syncWithStore(); + return nodeView; + } + } + private static boolean isPrime(int val) { if (val % 2 == 0) return false; int maxDivisor = (int)Math.sqrt(val); @@ -226,7 +251,7 @@ public class IntToIntBtree { } void dumpStatistics() { - int leafPages = height == 3 ? pagesCount - (1 + root.getChildrenCount() + 1):height == 2 ? pagesCount - 1:1; + int leafPages = height == 3 ? pagesCount - (1 + root.getNodeView().getChildrenCount() + 1):height == 2 ? pagesCount - 1:1; long leafNodesCapacity = hashedPagesCount * maxLeafNodesInHash + (leafPages - hashedPagesCount)* maxLeafNodes; long leafNodesCapacity2 = leafPages * maxLeafNodes; int usedPercent = (int)((count * 100L) / leafNodesCapacity); @@ -291,12 +316,16 @@ public class IntToIntBtree { } void setAddress(int _address) { - if (doSanityCheck) myAssert(_address % btree.pageSize == 0); - address = _address; + setAddressInternal(_address); syncWithStore(); } + private final void setAddressInternal(int _address) { + if (doSanityCheck) myAssert(_address % btree.pageSize == 0); + address = _address; + } + protected void syncWithStore() { PagedFileStorage pagedFileStorage = btree.storage.getPagedFileStorage(); myAddressInBuffer = pagedFileStorage.getOffsetInPage(address); @@ -731,7 +760,7 @@ public class IntToIntBtree { } } else { if (doSanityCheck) { - btree.root.dump("Splitting root:"+medianKey); + btree.root.getNodeView().dump("Splitting root:"+medianKey); } int newRootAddress = btree.nextPage(); @@ -744,13 +773,14 @@ public class IntToIntBtree { btree.root.setAddress(newRootAddress); parentAddress = newRootAddress; - btree.root.setChildrenCount((short)1); // btree.root becomes dirty - btree.root.setKeyAt(0, medianKey); - btree.root.setAddressAt(0, -address); - btree.root.setAddressAt(1, -newIndexNode.address); + BtreeIndexNodeView rootNodeView = btree.root.getNodeView(); + rootNodeView.setChildrenCount((short)1); // btree.root becomes dirty + rootNodeView.setKeyAt(0, medianKey); + rootNodeView.setAddressAt(0, -address); + rootNodeView.setAddressAt(1, -newIndexNode.address); if (doSanityCheck) { - btree.root.dump("New root"); + rootNodeView.dump("New root"); dump("First child"); newIndexNode.dump("Second child"); } @@ -941,7 +971,7 @@ public class IntToIntBtree { } } - private void dump(String s) { + protected void dump(String s) { if (doDump) { immediateDump(s); } @@ -1124,9 +1154,9 @@ public class IntToIntBtree { root.syncWithStore(); if (hasZeroKey) { - if(!processor.process(0, zeroKeyValue)) return false; + if (!processor.process(0, zeroKeyValue)) return false; } - return processLeafPages(root, processor); + return processLeafPages(root.getNodeView(), processor); } private boolean processLeafPages(@NotNull BtreeIndexNodeView node, @NotNull KeyValueProcessor processor) throws IOException { @@ -1151,14 +1181,4 @@ public class IntToIntBtree { } return true; } - - public void withStorageLock(@NotNull Runnable runnable) { - storage.getPagedFileStorage().lock(); - try { - runnable.run(); - } - finally { - storage.getPagedFileStorage().unlock(); - } - } }