/* * 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.jdo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.util.Collection; import java.util.Iterator; import javax.jdo.Extent; import javax.jdo.PersistenceManager; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.zoodb.test.testutil.TestTools; public class Test_061_ExtentDeletion { @BeforeClass public static void setUp() { TestTools.createDb(); TestTools.defineSchema(TestClass.class, TestClassTiny.class, TestClassTiny2.class); } @AfterClass public static void tearDown() { TestTools.removeDb(); } @Before public void beforeTest() { PersistenceManager pm = TestTools.openPM(); pm.currentTransaction().begin(); pm.newQuery(pm.getExtent(TestClass.class)).deletePersistentAll(); pm.newQuery(pm.getExtent(TestClassTiny.class)).deletePersistentAll(); pm.newQuery(pm.getExtent(TestClassTiny2.class)).deletePersistentAll(); pm.currentTransaction().commit(); TestTools.closePM(); } @After public void afterTest() { TestTools.closePM(); } private void count(PersistenceManager pm, Class<?> cls, int nExp) { int nExt = 0; for (Object o: pm.getExtent(cls, false)) { assertNotNull(o); nExt++; } int nQ = 0; Collection<?> c = (Collection<?>) pm.newQuery(pm.getExtent(cls, false)).execute(); for (Object o: c) { assertNotNull(o); nQ++; } assertEquals(nExp, nExt); assertEquals(nExp, nQ); } private void checkCount(PersistenceManager pm, int nTC, int nTCT, int nTCT2) { count( pm, TestClass.class, nTC); count( pm, TestClassTiny.class, nTCT); count( pm, TestClassTiny2.class, nTCT2); } @Test public void testExtentDeletionNoHierarchyNoFilter() { test(false, false); } @Test public void testExtentDeletionHierarchyNoFilter() { test(true, false); } @Test public void testExtentDeletionNoHierarchyFilter() { test(false, true); } @Test public void testExtentDeletionHierarchyFilter() { test(true, true); } private void test(boolean hierarchy, boolean filter) { int nTC2 = hierarchy ? 0 : 1; PersistenceManager pm = TestTools.openPM(); pm.setIgnoreCache(false); pm.currentTransaction().begin(); //create pm.makePersistent(new TestClass()); pm.makePersistent(new TestClassTiny()); pm.makePersistent(new TestClassTiny2()); checkCount(pm, 1, 1, 1); pm.currentTransaction().commit(); pm.currentTransaction().begin(); checkCount(pm, 1, 1, 1); //delete Extent<?> ext = pm.getExtent(TestClassTiny.class, hierarchy); if (filter) { pm.newQuery(ext, "_int < 1000000").deletePersistentAll(); } else { pm.newQuery(ext).deletePersistentAll(); } checkCount(pm, 1, 0, nTC2); pm.currentTransaction().rollback(); pm.currentTransaction().begin(); //check successful rollback checkCount(pm, 1, 1, 1); //delete again ext = pm.getExtent(TestClassTiny.class, hierarchy); if (filter) { pm.newQuery(ext, "_int < 1000000").deletePersistentAll(); } else { pm.newQuery(ext).deletePersistentAll(); } checkCount(pm, 1, 0, nTC2); pm.currentTransaction().commit(); pm.currentTransaction().begin(); checkCount(pm, 1, 0, nTC2); pm.currentTransaction().commit(); TestTools.closePM(); } /** * Test batched deletion of objects while iterating over an extent. * This failed in one test program for 100.000 objects, in which case * it read garbage (invalid position) after ~50.000 objects. */ @Test public void testExtentDeletionBatched() { //TODO System.err.println("COW on index-level has been disabled."); System.err.println("Reenabled test once multi-session is available?"); // int N = 100000; // PersistenceManager pm = TestTools.openPM(); // //pm.setIgnoreCache(false); // pm.currentTransaction().begin(); // // for (int i = 0; i < N; i++) { // TestClass tc = new TestClass(); // tc.setInt(i); // pm.makePersistent(tc); // if (i%5000 == 0) { // pm.currentTransaction().commit(); // pm.currentTransaction().begin(); // } // } // // pm.currentTransaction().commit(); // TestTools.closePM(); // // // //deletion // pm = TestTools.openPM(); // pm.currentTransaction().begin(); // int i = 0; // Extent<TestClass> extent = pm.getExtent(TestClass.class, false); // Iterator<TestClass> it = extent.iterator(); // Object oid = null; // while (it.hasNext()) { // try { // TestClass tc = it.next(); // oid = pm.getObjectId(tc); // pm.deletePersistent(tc); // // //re-use emptied pages // pm.makePersistent(new TestClassTiny2()); // pm.makePersistent(new TestClassTiny2()); // // if (++i%100 == 0) { // pm.currentTransaction().commit(); // pm.currentTransaction().begin(); // } // // //save some time: Usually it breaks before 900 // if (i>=1000) break; // } catch (RuntimeException e) { // System.out.println("i="+i); // System.out.println(" oid=" + oid); // throw e; // } // } // extent.closeAll(); // pm.currentTransaction().commit(); // TestTools.closePM(); } /** * Test batched deletion of objects while iterating over an extent. * This failed in one test program for 100.000 objects, in which case * it read garbage (invalid position) after ~50.000 objects. * * Same as above, but w/o overwriting old pages. */ @Test public void testExtentDeletionBatched2() { //TODO System.err.println("COW on index-level has been disabled."); System.err.println("Reenabled test once multi-session is available?"); // int N = 100000; // PersistenceManager pm = TestTools.openPM(); // //pm.setIgnoreCache(false); // pm.currentTransaction().begin(); // // for (int i = 0; i < N; i++) { // TestClass tc = new TestClass(); // tc.setInt(i); // pm.makePersistent(tc); // if (i%5000 == 0) { // pm.currentTransaction().commit(); // pm.currentTransaction().begin(); // } // } // // pm.currentTransaction().commit(); // TestTools.closePM(); // // // //deletion // pm = TestTools.openPM(); // pm.currentTransaction().begin(); // int i = 0; // Extent<TestClass> extent = pm.getExtent(TestClass.class, false); // Iterator<TestClass> it = extent.iterator(); // Object oid = null; // while (it.hasNext()) { // try { // TestClass tc = it.next(); // oid = pm.getObjectId(tc); // pm.deletePersistent(tc); // if (++i%20 == 0) { // pm.currentTransaction().commit(); // pm.currentTransaction().begin(); // } // // //save some time: Usually it breaks before 900 // if (i>=1000) break; // } catch (RuntimeException e) { // System.out.println("i="+i); // System.out.println(" oid=" + oid); // throw e; // } // } // extent.closeAll(); // pm.currentTransaction().commit(); // TestTools.closePM(); } }