/* * Copyright 2009-2016 Tilmann Zaeschke. All rights reserved. * * This file is part of ZooDB. * * ZooDB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ZooDB 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ZooDB. If not, see <http://www.gnu.org/licenses/>. * * See the README and COPYING files for further information. */ package org.zoodb.test.index2; import static org.junit.Assert.assertNotNull; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Scanner; import org.junit.Test; import org.zoodb.internal.server.StorageChannel; import org.zoodb.internal.server.StorageRootInMemory; import org.zoodb.internal.server.index.PagedOidIndex; import org.zoodb.tools.ZooConfig; /** * Test harness for a rare problem when adding OIDs out of order to the OID index during commit. * The problem occurred when adding over ~25000 object to a database. The OIDs are taken from the * cache (HashMap/Set), which is probably the reason why they are out of order. * * The adding causes at some point the splitting of a leaf which causes incorrect creation of a * new inner page. The page that contains the particular key (21128) still exists, but cannot be * found anymore. * * This occurred with PageSize = 1024. * * The problem occurred when a new leaf-page was added such that its root-inner-page had an * overflow. The overflow was handled correctly and a new inner page was created. However, * the algorithm added the new leaf-page always to the 2nd (new) inner page, instead of adding it * to the 1st page, if applicable. * * @author Tilmann Zaeschke * */ public class TestOidIndex_002 { @Test public void testIndex() { StorageChannel paf = new StorageRootInMemory(ZooConfig.getFilePageSize()); PagedOidIndex ind = new PagedOidIndex(paf); boolean wasAdded = false; long[] I = loadData(); for (int i = 0; i < I.length; i++) { long x = I[i]; long oid = x; // if (x==-1) { // //remove // i++; // long k = I[i]; // try { // ind.removeLong(k); // } catch (Exception e) { // System.out.println("key in map: " + map.containsKey(k)); // System.out.println("R i=" + i + " k=" + k); // throw new RuntimeException(e); // } // if (!map.containsKey(k)) { // fail("i=" + i + " k=" + k); // } // map.remove(k); // } else if (x==1) { //add i++; long k = I[i]; i++; int v = (int) I[i]; try { ind.insertLong(k, v, 32 + i); } catch (Exception e) { System.out.println("I i=" + i + " k=" + k + "/" + v); throw new RuntimeException(e); } if (oid == 21128) { wasAdded = true; } if (wasAdded) { assertNotNull( ind.findOid(21128) ); } } else { throw new IllegalStateException("i=" + x); } } // System.out.println("Index size: nInner=" + ind.statsGetInnerN() + " nLeaf=" + // ind.statsGetLeavesN()); assertNotNull( ind.findOid(21128) ); } private long[] loadData() { //return I; InputStream is = TestOidIndex_007_NoSuchElement.class.getResourceAsStream("index-002.log"); if (is==null) { throw new NullPointerException(); } Scanner s = new Scanner(is); s.useDelimiter(","); ArrayList<Long> ret = new ArrayList<Long>(); while (s.hasNext()) { ret.add(s.nextLong()); } s.close(); try { is.close(); } catch (IOException e) { throw new RuntimeException(e); } System.out.println("reading: " + ret.size()); long[] ret2 = new long[ret.size()]; for (int i = 0; i < ret.size(); i++) { ret2[i] = ret.get(i); } return ret2; } }