- Fixed a potential bug in the RTree delete that could happen when a deleter latch the root page while it is leaf and when it wants to upgrade the latch to write latch the root is no longer a leaf page.
- Catched BTree key non existence key exception that should not normally occur if we are dealing with good citizens, we only see in the multi-threading tests because we are using random data.
- Made sure all lacthes in the RTree are released in case of a crash.
git-svn-id: https://hyracks.googlecode.com/svn/branches/hyracks_lsm_tree@1196 123451ca-8445-de46-9d55-352943316053
diff --git a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTree.java b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTree.java
index 7bcfd19..55fd444 100644
--- a/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTree.java
+++ b/hyracks-storage-am-lsm-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/impls/LSMRTree.java
@@ -26,6 +26,7 @@
import edu.uci.ics.hyracks.api.io.FileReference;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
import edu.uci.ics.hyracks.storage.am.btree.exceptions.BTreeDuplicateKeyException;
+import edu.uci.ics.hyracks.storage.am.btree.exceptions.BTreeNonExistentKeyException;
import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
import edu.uci.ics.hyracks.storage.am.common.api.IFreePageManager;
@@ -301,7 +302,15 @@
cursor.close();
}
if (foundTupleInMemoryBTree) {
- ctx.memBTreeAccessor.delete(tuple);
+ try {
+ ctx.memBTreeAccessor.delete(tuple);
+ } catch (BTreeNonExistentKeyException e) {
+ // Tuple has been deleted in the meantime. Do nothing.
+ // This normally shouldn't happen if we are dealing with
+ // good citizens since LSMRTree is used as a secondary
+ // index and a tuple shouldn't be deleted twice without
+ // insert between them.
+ }
}
ctx.memRTreeAccessor.insert(tuple);
diff --git a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTree.java b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTree.java
index 800d64f..325cbe5 100644
--- a/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTree.java
+++ b/hyracks-storage-am-rtree/src/main/java/edu/uci/ics/hyracks/storage/am/rtree/impls/RTree.java
@@ -265,7 +265,7 @@
int pageId = rootPage;
boolean writeLatched = false;
boolean readLatched = false;
- boolean succeed = false;
+ boolean succeeded = false;
ICachedPage node = null;
boolean isLeaf = false;
long pageLsn = 0, parentLsn = 0;
@@ -289,9 +289,8 @@
}
} else {
// Be optimistic and grab read latch first. We will swap
- // it
- // to write latch if we need to enlarge the best child
- // tuple.
+ // it to write latch if we need to enlarge the best
+ // child tuple.
node.acquireReadLatch();
readLatched = true;
}
@@ -299,8 +298,7 @@
if (pageId != rootPage && parentLsn < ctx.interiorFrame.getPageNsn()) {
// Concurrent split detected, go back to parent and
- // re-choose
- // the best child
+ // re-choose the best child
if (writeLatched) {
node.releaseWriteLatch();
writeLatched = false;
@@ -327,10 +325,6 @@
boolean enlarementIsNeeded = ctx.interiorFrame.findBestChild(ctx.getTuple(), ctx.cmp);
int childPageId = ctx.interiorFrame.getBestChildPageId();
- // check if enlargement is needed
- // boolean enlarementIsNeeded =
- // ctx.interiorFrame.checkEnlargement(ctx.getTuple(),
- // ctx.cmp);
if (enlarementIsNeeded) {
if (!writeLatched) {
node.releaseReadLatch();
@@ -373,12 +367,12 @@
parentLsn = pageLsn;
} else {
ctx.leafFrame.setPage(node);
- succeed = true;
+ succeeded = true;
return node;
}
}
} finally {
- if (!succeed) {
+ if (!succeeded) {
if (readLatched) {
node.releaseReadLatch();
readLatched = false;
@@ -394,6 +388,7 @@
private void insertTuple(ICachedPage node, int pageId, ITupleReference tuple, RTreeOpContext ctx, boolean isLeaf)
throws HyracksDataException, TreeIndexException {
+ boolean succeeded = false;
FrameOpSpaceStatus spaceStatus;
if (!isLeaf) {
spaceStatus = ctx.interiorFrame.hasSpaceInsert(tuple);
@@ -403,26 +398,48 @@
switch (spaceStatus) {
case SUFFICIENT_CONTIGUOUS_SPACE: {
- if (!isLeaf) {
- ctx.interiorFrame.insert(tuple, -1);
- } else {
- ctx.leafFrame.insert(tuple, -1);
+ try {
+ if (!isLeaf) {
+ ctx.interiorFrame.insert(tuple, -1);
+ } else {
+ ctx.leafFrame.insert(tuple, -1);
+ }
+ succeeded = true;
+ } finally {
+ if (succeeded) {
+ ctx.LSNUpdates.add(node);
+ ctx.splitKey.reset();
+ } else if (isLeaf) {
+ // In case of a crash, we un-latch the interior node
+ // inside updateParentForInsert.
+ node.releaseWriteLatch();
+ bufferCache.unpin(node);
+ }
}
- ctx.LSNUpdates.add(node);
- ctx.splitKey.reset();
break;
}
case SUFFICIENT_SPACE: {
- if (!isLeaf) {
- ctx.interiorFrame.compact();
- ctx.interiorFrame.insert(tuple, -1);
- } else {
- ctx.leafFrame.compact();
- ctx.leafFrame.insert(tuple, -1);
+ try {
+ if (!isLeaf) {
+ ctx.interiorFrame.compact();
+ ctx.interiorFrame.insert(tuple, -1);
+ } else {
+ ctx.leafFrame.compact();
+ ctx.leafFrame.insert(tuple, -1);
+ }
+ succeeded = true;
+ } finally {
+ if (succeeded) {
+ ctx.LSNUpdates.add(node);
+ ctx.splitKey.reset();
+ } else if (isLeaf) {
+ // In case of a crash, we un-latch the interior node
+ // inside updateParentForInsert.
+ node.releaseWriteLatch();
+ bufferCache.unpin(node);
+ }
}
- ctx.LSNUpdates.add(node);
- ctx.splitKey.reset();
break;
}
@@ -431,29 +448,42 @@
ICachedPage rightNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, rightPageId), true);
rightNode.acquireWriteLatch();
- IRTreeFrame rightFrame;
- if (!isLeaf) {
- rightFrame = (IRTreeFrame) interiorFrameFactory.createFrame();
- rightFrame.setPage(rightNode);
- rightFrame.initBuffer((byte) ctx.interiorFrame.getLevel());
- rightFrame.setRightPage(ctx.interiorFrame.getRightPage());
- ctx.interiorFrame.split(rightFrame, tuple, ctx.splitKey);
- ctx.interiorFrame.setRightPage(rightPageId);
- ctx.NSNUpdates.add(rightNode);
- ctx.LSNUpdates.add(rightNode);
- ctx.NSNUpdates.add(node);
- ctx.LSNUpdates.add(node);
- } else {
- rightFrame = (IRTreeFrame) leafFrameFactory.createFrame();
- rightFrame.setPage(rightNode);
- rightFrame.initBuffer((byte) 0);
- rightFrame.setRightPage(ctx.interiorFrame.getRightPage());
- ctx.leafFrame.split(rightFrame, tuple, ctx.splitKey);
- ctx.leafFrame.setRightPage(rightPageId);
- ctx.NSNUpdates.add(rightNode);
- ctx.LSNUpdates.add(rightNode);
- ctx.NSNUpdates.add(node);
- ctx.LSNUpdates.add(node);
+ try {
+ IRTreeFrame rightFrame;
+ if (!isLeaf) {
+ rightFrame = (IRTreeFrame) interiorFrameFactory.createFrame();
+ rightFrame.setPage(rightNode);
+ rightFrame.initBuffer((byte) ctx.interiorFrame.getLevel());
+ rightFrame.setRightPage(ctx.interiorFrame.getRightPage());
+ ctx.interiorFrame.split(rightFrame, tuple, ctx.splitKey);
+ ctx.interiorFrame.setRightPage(rightPageId);
+ } else {
+ rightFrame = (IRTreeFrame) leafFrameFactory.createFrame();
+ rightFrame.setPage(rightNode);
+ rightFrame.initBuffer((byte) 0);
+ rightFrame.setRightPage(ctx.interiorFrame.getRightPage());
+ ctx.leafFrame.split(rightFrame, tuple, ctx.splitKey);
+ ctx.leafFrame.setRightPage(rightPageId);
+ }
+ succeeded = true;
+ } finally {
+ if (succeeded) {
+ ctx.NSNUpdates.add(rightNode);
+ ctx.LSNUpdates.add(rightNode);
+ ctx.NSNUpdates.add(node);
+ ctx.LSNUpdates.add(node);
+ } else if (isLeaf) {
+ // In case of a crash, we un-latch the interior node
+ // inside updateParentForInsert.
+ node.releaseWriteLatch();
+ bufferCache.unpin(node);
+ rightNode.releaseWriteLatch();
+ bufferCache.unpin(rightNode);
+ } else {
+ rightNode.releaseWriteLatch();
+ bufferCache.unpin(rightNode);
+ }
+
}
ctx.splitKey.setPages(pageId, rightPageId);
if (pageId == rootPage) {
@@ -461,29 +491,48 @@
ICachedPage newLeftNode = bufferCache
.pin(BufferedFileHandle.getDiskPageId(fileId, newLeftId), true);
newLeftNode.acquireWriteLatch();
+ succeeded = false;
+ try {
+ // copy left child to new left child
+ System.arraycopy(node.getBuffer().array(), 0, newLeftNode.getBuffer().array(), 0, newLeftNode
+ .getBuffer().capacity());
- // copy left child to new left child
- System.arraycopy(node.getBuffer().array(), 0, newLeftNode.getBuffer().array(), 0, newLeftNode
- .getBuffer().capacity());
+ // initialize new root (leftNode becomes new root)
+ ctx.interiorFrame.setPage(node);
+ ctx.interiorFrame.initBuffer((byte) (ctx.interiorFrame.getLevel() + 1));
- // initialize new root (leftNode becomes new root)
- ctx.interiorFrame.setPage(node);
- ctx.interiorFrame.initBuffer((byte) (ctx.interiorFrame.getLevel() + 1));
+ ctx.splitKey.setLeftPage(newLeftId);
+ ctx.interiorFrame.insert(ctx.splitKey.getLeftTuple(), -1);
+ ctx.interiorFrame.insert(ctx.splitKey.getRightTuple(), -1);
- ctx.splitKey.setLeftPage(newLeftId);
- ctx.interiorFrame.insert(ctx.splitKey.getLeftTuple(), -1);
- ctx.interiorFrame.insert(ctx.splitKey.getRightTuple(), -1);
+ succeeded = true;
+ } finally {
+ if (succeeded) {
+ ctx.NSNUpdates.remove(ctx.NSNUpdates.size() - 1);
+ ctx.LSNUpdates.remove(ctx.LSNUpdates.size() - 1);
- ctx.NSNUpdates.remove(ctx.NSNUpdates.size() - 1);
- ctx.LSNUpdates.remove(ctx.LSNUpdates.size() - 1);
+ ctx.NSNUpdates.add(newLeftNode);
+ ctx.LSNUpdates.add(newLeftNode);
- ctx.NSNUpdates.add(newLeftNode);
- ctx.LSNUpdates.add(newLeftNode);
-
- ctx.NSNUpdates.add(node);
- ctx.LSNUpdates.add(node);
-
- ctx.splitKey.reset();
+ ctx.NSNUpdates.add(node);
+ ctx.LSNUpdates.add(node);
+ ctx.splitKey.reset();
+ } else if (isLeaf) {
+ // In case of a crash, we un-latch the interior node
+ // inside updateParentForInsert.
+ node.releaseWriteLatch();
+ bufferCache.unpin(node);
+ rightNode.releaseWriteLatch();
+ bufferCache.unpin(rightNode);
+ newLeftNode.releaseWriteLatch();
+ bufferCache.unpin(newLeftNode);
+ } else {
+ rightNode.releaseWriteLatch();
+ bufferCache.unpin(rightNode);
+ newLeftNode.releaseWriteLatch();
+ bufferCache.unpin(newLeftNode);
+ }
+ }
}
break;
}
@@ -491,6 +540,7 @@
}
private void updateParentForInsert(RTreeOpContext ctx) throws HyracksDataException, TreeIndexException {
+ boolean succeeded = false;
boolean writeLatched = false;
int parentId = ctx.pathList.getLastPageId();
ICachedPage parentNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, parentId), false);
@@ -499,46 +549,57 @@
ctx.interiorFrame.setPage(parentNode);
boolean foundParent = true;
- if (ctx.interiorFrame.getPageLsn() != ctx.pathList.getLastPageLsn()) {
- foundParent = false;
- while (true) {
- if (ctx.interiorFrame.findTupleByPointer(ctx.splitKey.getLeftTuple(), ctx.cmp) != -1) {
- // found the parent
- foundParent = true;
- break;
- }
- int rightPage = ctx.interiorFrame.getRightPage();
- parentNode.releaseWriteLatch();
- writeLatched = false;
- bufferCache.unpin(parentNode);
+ try {
+ if (ctx.interiorFrame.getPageLsn() != ctx.pathList.getLastPageLsn()) {
+ foundParent = false;
+ while (true) {
+ if (ctx.interiorFrame.findTupleByPointer(ctx.splitKey.getLeftTuple(), ctx.cmp) != -1) {
+ // found the parent
+ foundParent = true;
+ break;
+ }
+ int rightPage = ctx.interiorFrame.getRightPage();
+ parentNode.releaseWriteLatch();
+ writeLatched = false;
+ bufferCache.unpin(parentNode);
- if (rightPage == -1) {
- break;
- }
+ if (rightPage == -1) {
+ break;
+ }
- parentId = rightPage;
- parentNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, parentId), false);
- parentNode.acquireWriteLatch();
- writeLatched = true;
- ctx.interiorFrame.setPage(parentNode);
+ parentId = rightPage;
+ parentNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, parentId), false);
+ parentNode.acquireWriteLatch();
+ writeLatched = true;
+ ctx.interiorFrame.setPage(parentNode);
+ }
}
- }
- if (foundParent) {
- try {
- ctx.interiorFrame.adjustKey(ctx.splitKey.getLeftTuple(), -1, ctx.cmp);
- } catch (TreeIndexException e) {
+ if (foundParent) {
+ try {
+ ctx.interiorFrame.adjustKey(ctx.splitKey.getLeftTuple(), -1, ctx.cmp);
+ } catch (TreeIndexException e) {
+ if (writeLatched) {
+ parentNode.releaseWriteLatch();
+ writeLatched = false;
+ bufferCache.unpin(parentNode);
+ }
+ throw e;
+ }
+ insertTuple(parentNode, parentId, ctx.splitKey.getRightTuple(), ctx, ctx.interiorFrame.isLeaf());
+ ctx.pathList.moveLast();
+ succeeded = true;
+ return;
+
+ }
+ } finally {
+ if (!succeeded) {
if (writeLatched) {
parentNode.releaseWriteLatch();
writeLatched = false;
bufferCache.unpin(parentNode);
}
- throw e;
}
- insertTuple(parentNode, parentId, ctx.splitKey.getRightTuple(), ctx, ctx.interiorFrame.isLeaf());
- ctx.pathList.moveLast();
- return;
-
}
ctx.traverseList.clear();
@@ -616,31 +677,31 @@
ctx.splitKey.reset();
ctx.splitKey.getLeftTuple().setFieldCount(cmpFactories.length);
+ // We delete the first matching tuple (including the payload data.
+ // We don't update the MBRs of the parents after deleting the record.
int tupleIndex = findTupleToDelete(ctx);
if (tupleIndex != -1) {
- int pageId = ctx.pathList.getLastPageId();
- ctx.pathList.moveLast();
- deleteTuple(pageId, tupleIndex, ctx);
-
- ctx.leafFrame.getPage().releaseWriteLatch();
- bufferCache.unpin(ctx.leafFrame.getPage());
+ try {
+ deleteTuple(tupleIndex, ctx);
+ } finally {
+ ctx.leafFrame.getPage().releaseWriteLatch();
+ bufferCache.unpin(ctx.leafFrame.getPage());
+ }
}
}
private int findTupleToDelete(RTreeOpContext ctx) throws HyracksDataException {
boolean writeLatched = false;
boolean readLatched = false;
- boolean succeed = false;
+ boolean succeeded = false;
ICachedPage node = null;
- ctx.traverseList.add(rootPage, -1, -1);
- ctx.pathList.add(rootPage, -1, ctx.traverseList.size() - 1);
+ ctx.pathList.add(rootPage, -1, -1);
try {
while (!ctx.pathList.isEmpty()) {
int pageId = ctx.pathList.getLastPageId();
long parentLsn = ctx.pathList.getLastPageLsn();
- int pageIndex = ctx.pathList.getLastPageIndex();
ctx.pathList.moveLast();
node = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, pageId), false);
node.acquireReadLatch();
@@ -648,16 +709,13 @@
ctx.interiorFrame.setPage(node);
boolean isLeaf = ctx.interiorFrame.isLeaf();
long pageLsn = ctx.interiorFrame.getPageLsn();
- int parentIndex = ctx.traverseList.getPageIndex(pageIndex);
- ctx.traverseList.setPageLsn(pageIndex, pageLsn);
if (pageId != rootPage && parentLsn < ctx.interiorFrame.getPageNsn()) {
// Concurrent split detected, we need to visit the right
// page
int rightPage = ctx.interiorFrame.getRightPage();
if (rightPage != -1) {
- ctx.traverseList.add(rightPage, -1, parentIndex);
- ctx.pathList.add(rightPage, parentLsn, ctx.traverseList.size() - 1);
+ ctx.pathList.add(rightPage, parentLsn, -1);
}
}
@@ -665,8 +723,7 @@
for (int i = 0; i < ctx.interiorFrame.getTupleCount(); i++) {
int childPageId = ctx.interiorFrame.getChildPageIdIfIntersect(ctx.tuple, i, ctx.cmp);
if (childPageId != -1) {
- ctx.traverseList.add(childPageId, -1, pageIndex);
- ctx.pathList.add(childPageId, pageLsn, ctx.traverseList.size() - 1);
+ ctx.pathList.add(childPageId, pageLsn, -1);
}
}
} else {
@@ -683,28 +740,34 @@
writeLatched = true;
ctx.leafFrame.setPage(node);
+ // A rare case only happen when a root is no longer a
+ // leaf page. Simply we restart the search.
+ if (!ctx.leafFrame.isLeaf()) {
+ ctx.pathList.add(pageId, -1, -1);
+
+ node.releaseWriteLatch();
+ writeLatched = false;
+ bufferCache.unpin(node);
+ continue;
+ }
+
if (ctx.leafFrame.getPageLsn() != pageLsn) {
// The page was changed while we unlocked it
tupleIndex = ctx.leafFrame.findTupleIndex(ctx.tuple, ctx.cmp);
if (tupleIndex == -1) {
- ctx.traverseList.add(pageId, -1, parentIndex);
- ctx.pathList.add(pageId, parentLsn, ctx.traverseList.size() - 1);
+ ctx.pathList.add(pageId, parentLsn, -1);
node.releaseWriteLatch();
writeLatched = false;
bufferCache.unpin(node);
continue;
} else {
- ctx.pathList.clear();
- fillPath(ctx, pageIndex);
- succeed = true;
+ succeeded = true;
return tupleIndex;
}
} else {
- ctx.pathList.clear();
- fillPath(ctx, pageIndex);
- succeed = true;
+ succeeded = true;
return tupleIndex;
}
}
@@ -714,7 +777,7 @@
bufferCache.unpin(node);
}
} finally {
- if (!succeed) {
+ if (!succeeded) {
if (readLatched) {
node.releaseReadLatch();
readLatched = false;
@@ -729,7 +792,7 @@
return -1;
}
- private void deleteTuple(int pageId, int tupleIndex, RTreeOpContext ctx) throws HyracksDataException {
+ private void deleteTuple(int tupleIndex, RTreeOpContext ctx) throws HyracksDataException {
ctx.leafFrame.delete(tupleIndex, ctx.cmp);
ctx.leafFrame.setPageLsn(incrementGlobalNsn());
}
diff --git a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/util/LSMRTreeTestHarness.java b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/util/LSMRTreeTestHarness.java
index 23ad438..bdde7ee 100644
--- a/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/util/LSMRTreeTestHarness.java
+++ b/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/lsm/rtree/util/LSMRTreeTestHarness.java
@@ -46,8 +46,7 @@
private static final int DEFAULT_DISK_NUM_PAGES = 1000;
private static final int DEFAULT_DISK_MAX_OPEN_FILES = 2000;
private static final int DEFAULT_MEM_PAGE_SIZE = 256;
- private static final int DEFAULT_MEM_NUM_PAGES = 100;
- // private static final int DEFAULT_MEM_NUM_PAGES = 10;
+ private static final int DEFAULT_MEM_NUM_PAGES = 1000;
private static final int DEFAULT_HYRACKS_FRAME_SIZE = 128;
private static final int DUMMY_FILE_ID = -1;
@@ -103,7 +102,7 @@
public void tearDown() throws HyracksDataException {
diskBufferCache.close();
- for(IODeviceHandle dev : ioManager.getIODevices()) {
+ for (IODeviceHandle dev : ioManager.getIODevices()) {
File dir = new File(dev.getPath(), onDiskDir);
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String name) {
@@ -112,10 +111,10 @@
};
String[] files = dir.list(filter);
if (files != null) {
- for (String fileName : files) {
- File file = new File(dir.getPath() + File.separator + fileName);
- file.delete();
- }
+ for (String fileName : files) {
+ File file = new File(dir.getPath() + File.separator + fileName);
+ file.delete();
+ }
}
dir.delete();
}
@@ -150,9 +149,9 @@
}
public IOManager getIOManager() {
- return ioManager;
+ return ioManager;
}
-
+
public IBufferCache getDiskBufferCache() {
return diskBufferCache;
}
diff --git a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/utils/RTreeTestHarness.java b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/utils/RTreeTestHarness.java
index d8e9eab..c0cec35 100644
--- a/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/utils/RTreeTestHarness.java
+++ b/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/edu/uci/ics/hyracks/storage/am/rtree/utils/RTreeTestHarness.java
@@ -32,7 +32,7 @@
private static final long RANDOM_SEED = 50;
private static final int DEFAULT_PAGE_SIZE = 256;
- private static final int DEFAULT_NUM_PAGES = 100;
+ private static final int DEFAULT_NUM_PAGES = 1000;
private static final int DEFAULT_MAX_OPEN_FILES = 10;
private static final int DEFAULT_HYRACKS_FRAME_SIZE = 128;