/** Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. Contact: SYSTAP, LLC DBA Blazegraph 2501 Calvert ST NW #106 Washington, DC 20008 licenses@blazegraph.com This program 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; version 2 of the License. This program 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 this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Created on May 17, 2007 */ package com.bigdata.htree; import com.bigdata.btree.ICounter; import com.bigdata.btree.IIndex; import com.bigdata.rawstore.IRawStore; import com.bigdata.rawstore.SimpleMemoryRawStore; /** * Test suite for the {@link IIndex#getCounter()} interface. * * @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a> * @version $Id$ */ public class TestIndexCounter extends AbstractHTreeTestCase { /** * */ public TestIndexCounter() { } /** * @param name */ public TestIndexCounter(String name) { super(name); } /** * Unit test for {@link Counter} to verify basic increment behavior. */ public void test_counter() { final IRawStore store = new SimpleMemoryRawStore(); try { final HTree btree = getHTree(store, 3); final ICounter counter = btree.getCounter(); // initial value is zero for an unpartitioned index assertEquals(0, counter.get()); // get() does not have a side-effect on the counter. assertEquals(0, counter.get()); // inc() increments the value and _then_ returns the counter. assertEquals(1, counter.incrementAndGet()); assertEquals(1, counter.get()); assertEquals(2, counter.incrementAndGet()); } finally { store.destroy(); } } /** * Unit test for overflow conditions at the int32 and int64 boundary for * {@link Counter}. */ public void test_counter_overflow() { final IRawStore store = new SimpleMemoryRawStore(); try { final HTree btree = getHTree(store, 3/* addressBits */); final ICounter counter = btree.getCounter(); final long maxSignedInt = (long) Integer.MAX_VALUE; final long minSignedInt = 0xFFFFFFFFL & (long) Integer.MIN_VALUE; final long minusOneInt = 0xFFFFFFFFL & (long) -1; final long int32Overflow = 1L << 32;// bit 33 is on. /* * First explore when the counter crosses from max signed int to min * signed int. */ // Artificially set the counter to max signed int. btree.counter.set(maxSignedInt); // Verify current value. assertEquals(maxSignedInt, counter.get()); // Increment. Should now be min signed int. assertEquals(minSignedInt, counter.incrementAndGet()); // Increment. Should now be moving towards zero. assertEquals(minSignedInt + 1L, counter.incrementAndGet()); // Increment. Should now be moving towards zero. assertEquals(minSignedInt + 2L, counter.incrementAndGet()); /* * Now explore when the counter approaches a value which can only be * expressed in 33 bits (bigger than an unsigned int). */ btree.counter.set(minusOneInt - 1); // Verify current value. assertEquals(minusOneInt - 1, counter.get()); // Increment. Should now be a long whose lower word is minus one signed // int. assertEquals(minusOneInt, counter.incrementAndGet()); // Increment. Should now be a long whose lower word is ZERO and whose // upper word as the low bit set. assertEquals(int32Overflow, counter.incrementAndGet()); /* * Now explore when the counter approaches -1L and 0L. */ btree.counter.set(-2L); // Verify current value. assertEquals(-2L, counter.get()); // Increment to -1L. assertEquals(-1L, counter.incrementAndGet()); // Increment to 0L fails (counter overflow). try { counter.incrementAndGet(); fail("Expecting counter overflow"); } catch (RuntimeException ex) { if (log.isInfoEnabled()) log.info("Ignoring expected exception: " + ex); } } finally { store.destroy(); } } }