/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: BTreeTest.java * * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. * * Electric(tm) is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Electric(tm) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Electric(tm); see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */ package com.sun.electric.database.geometry.btree; import java.io.*; import java.util.*; import com.sun.electric.database.geometry.btree.unboxed.*; import com.sun.electric.database.geometry.btree.CachingPageStorage.CachedPage; /** * A simple regression test for the BTree. */ public class BTreeTest { public static void main(String[] s) throws Exception { if (s.length != 4) { System.err.println(""); System.err.println("usage: java " + BTree.class.getName() + " <maxsize> <numops> <cachesize> <seed>"); System.err.println(""); System.err.println(" Creates a BTree and runs random operations on both it and an in-memory TreeMap."); System.err.println(" Reports any disagreements."); System.err.println(""); System.err.println(" <maxsize> maximum number of entries in the tree, or 0 for no limit"); System.err.println(" <numops> number of operations to perform, or 0 for no limit"); System.err.println(" <cachesize> number of pages to cache in memory, or 0 for no cache"); System.err.println(" <seed> seed for random number generator, in hex"); System.err.println(""); System.exit(-1); } if (!BTree.class.desiredAssertionStatus()) throw new RuntimeException("You need to run this test with assertions enabled!"); Random rand = new Random(Integer.parseInt(s[3], 16)); int cachesize = Integer.parseInt(s[2]); int numops = Integer.parseInt(s[1]); int maxsize = Integer.parseInt(s[0]); int size = 0; CachingPageStorage ps = new CachingPageStorageWrapper(FilePageStorage.create(), cachesize, false); BTree<Integer,Integer,Pair<Integer,Integer>> btree = new BTree<Integer,Integer,Pair<Integer,Integer>>(ps, UnboxedInt.instance, UnboxedInt.instance, null); TreeMap<Integer,Integer> tm = new TreeMap<Integer,Integer>(); int puts=0, gets=0, deletes=0, misses=0, inserts=0; long lastprint=0; // you can switch one of these off to gather crude performance measurements and compare them to TreeMap boolean do_tm = true; boolean do_bt = true; for(int i=0; numops==0 || i<numops; i++) { if (System.currentTimeMillis()-lastprint > 200) { lastprint = System.currentTimeMillis(); System.out.print("\r puts="+puts+" gets="+(gets-misses)+"/"+gets+" deletes="+deletes); } int key = rand.nextInt() % 1000000; switch(rand.nextInt() % 3) { case 0: { // get Integer tget = do_tm ? tm.get(key) : null; Integer bget = do_bt ? btree.getValFromKey(key) : null; gets++; if (do_tm && do_bt) { if (tget==null && bget==null) { misses++; break; } if (tget!=null && bget!=null && tget.equals(bget)) break; System.out.print("\r puts="+puts+" gets="+(gets-misses)+"/"+gets+" deletes="+deletes); System.out.println(); System.out.println(); throw new RuntimeException(" disagreement on key " + key + ": btree="+bget+", treemap="+tget); } break; } case 1: { // get ordinal int sz = do_bt ? btree.size() : tm.size(); int ord = sz==0 ? 0 : Math.abs(rand.nextInt()) % sz; Integer tget = do_tm ? (sz==0 ? null : tm.values().toArray(new Integer[0])[ord]) : null; Integer bget = do_bt ? btree.getValFromOrd(ord) : null; gets++; if (do_tm && do_bt) { if (tget==null && bget==null) break; if (tget!=null && bget!=null && tget.equals(bget)) break; System.out.print("\r puts="+puts+" gets="+(gets-misses)+"/"+gets+" deletes="+deletes); System.out.println(); System.out.println(); System.out.println("dump:"); throw new RuntimeException(" disagreement on ordinal " + ord + ": btree="+bget+", treemap="+tget); } break; } case 2: { // put int val = rand.nextInt(); boolean already_there = false; boolean should_delete = false; if (do_bt) already_there = do_tm ? tm.get(key)!=null : btree.getValFromKey(key)!=null; if (already_there) should_delete = Math.abs(rand.nextInt()) % 10 < 5; if (do_tm) { if (should_delete) tm.remove(key); else tm.put(key, val); } if (do_bt) { if (should_delete) btree.remove(key); else if (already_there) btree.replace(key, val); else btree.insert(key, val); } if (should_delete) deletes++; else puts++; break; } } } } }