/** 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 Feb 16, 2007 */ package com.bigdata.journal; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Set; import java.util.UUID; import com.bigdata.btree.HTreeIndexMetadata; import com.bigdata.btree.IIndex; import com.bigdata.btree.ITupleSerializer; import com.bigdata.btree.keys.IKeyBuilder; import com.bigdata.htree.HTree; import com.bigdata.util.BytesUtil; /** * Test suite for the {@link Name2Addr index} used to name index names to the * named indices. * * @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a> * @version $Id$ */ public class TestName2Addr extends ProxyTestCase<Journal> { /** * */ public TestName2Addr() { } /** * @param arg0 */ public TestName2Addr(String arg0) { super(arg0); } /* * Note: You have to do this in Name2Addr since it explicitly DOES NOT use * any properties from the configuration file or the environment. */ // @Override // public Properties getProperties() { // // final Properties p = new Properties(super.getProperties()); // // p.setProperty(KeyBuilder.Options.COLLATOR,CollatorEnum.ASCII.name()); // // return p; // } public void test_name2Addr_keyEncoding() { final String sharedPrefix = "kb"; final String name1 = "kb.red"; final String name2 = "kb.blue"; Journal journal = new Journal(getProperties()); try { final IIndex n2a = journal.getName2Addr(); assertKeyEncoding(sharedPrefix, n2a); assertKeyEncoding(name1, n2a); assertKeyEncoding(name2, n2a); } finally { journal.destroy(); } } private void assertKeyEncoding(final String name, final IIndex n2a) { @SuppressWarnings("rawtypes") final ITupleSerializer tupleSer = n2a.getIndexMetadata() .getTupleSerializer(); final IKeyBuilder keyBuilder = tupleSer.getKeyBuilder(); final IKeyBuilder keyBuilder2 = n2a.getIndexMetadata().getKeyBuilder(); // The same key builder. assertTrue(keyBuilder == keyBuilder2); final byte[] a = keyBuilder.reset().append(name).getKey(); final byte[] b = tupleSer.serializeKey(name); assertTrue(BytesUtil.compareBytes(a, b) == 0); if (log.isInfoEnabled()) log.info("name=" + name + ", key=" + BytesUtil.toString(a)); } /** * Test the ability to register and use named index, including whether the * named index is restart safe. */ public void test_namedIndexScan() { final String sharedPrefix = "kb"; final String name1 = "kb.red"; final String name2 = "kb.blue"; Journal journal = new Journal(getProperties()); try { assertEquals(0L, journal.getLastCommitTime()); assertEquals( 0, getIndexNames(journal, null/* prefix */, journal.getLastCommitTime()).size()); assertEquals( 0, getIndexNames(journal, ""/* prefix */, journal.getLastCommitTime()).size()); assertEquals( 0, getIndexNames(journal, sharedPrefix/* prefix */, journal.getLastCommitTime()).size()); assertEquals( 0, getIndexNames(journal, name1/* prefix */, journal.getLastCommitTime()).size()); assertEquals( 0, getIndexNames(journal, name2/* prefix */, journal.getLastCommitTime()).size()); assertEquals( 0, getIndexNames(journal, name1/* prefix */, ITx.READ_COMMITTED).size()); assertEquals( 0, getIndexNames(journal, name2/* prefix */, ITx.READ_COMMITTED).size()); final UUID indexUUID = UUID.randomUUID(); assertNull(journal.getIndex(name1)); assertNull(journal.getIndex(name2)); final HTreeIndexMetadata md1 = new HTreeIndexMetadata( name1, indexUUID); final HTreeIndexMetadata md2 = new HTreeIndexMetadata( name2, indexUUID); journal.register(name1, md1); assertNotNull(journal.getUnisolatedIndex(name1)); assertNull(journal.getUnisolatedIndex(name2)); journal.register(name2, md2); assertNotNull(journal.getUnisolatedIndex(name1)); assertNotNull(journal.getUnisolatedIndex(name2)); HTree htree1 = (HTree) journal.getUnisolatedIndex(name1); HTree htree2 = (HTree) journal.getUnisolatedIndex(name2); // different reference. assertTrue(htree1 != htree2); // Did not commit. assertEquals(0L, journal.getLastCommitTime()); // Visible in unisolated view. assertEquals( 2, getIndexNames(journal, null/* prefix */, journal.getLastCommitTime()).size()); assertEquals( 2, getIndexNames(journal, ""/* prefix */, journal.getLastCommitTime()).size()); assertEquals( 2, getIndexNames(journal, sharedPrefix/* prefix */, journal.getLastCommitTime()).size()); assertEquals( 1, getIndexNames(journal, name1/* prefix */, journal.getLastCommitTime()).size()); assertEquals( 1, getIndexNames(journal, name2/* prefix */, journal.getLastCommitTime()).size()); // Not visible in the read-committed view. assertEquals( 0, getIndexNames(journal, name1/* prefix */, ITx.READ_COMMITTED).size()); assertEquals( 0, getIndexNames(journal, name2/* prefix */, ITx.READ_COMMITTED).size()); /* * commit the journal */ final long commitTime1 = journal.commit(); final long lastCommitTime1 = journal.getLastCommitTime(); assertEquals(commitTime1, lastCommitTime1); assertNotSame(0L, commitTime1); // Visible in committed view. assertEquals(2, getIndexNames(journal, null/* prefix */, commitTime1) .size()); assertEquals(2, getIndexNames(journal, ""/* prefix */, commitTime1) .size()); assertEquals( 2, getIndexNames(journal, sharedPrefix/* prefix */, commitTime1).size()); // Visible in the read-committed view. assertEquals( 1, getIndexNames(journal, name1/* prefix */, ITx.READ_COMMITTED).size()); assertEquals( 1, getIndexNames(journal, name2/* prefix */, ITx.READ_COMMITTED).size()); // Visible in read-historical committed view. assertEquals( 1, getIndexNames(journal, name1/* prefix */, commitTime1).size()); assertEquals( 1, getIndexNames(journal, name2/* prefix */, commitTime1).size()); if (journal.isStable()) { /* * re-open the journal and test restart safety. */ journal = reopenStore(journal); htree1 = (HTree) journal.getUnisolatedIndex(name1); htree2 = (HTree) journal.getUnisolatedIndex(name2); assertNotNull("htree", htree1); assertNotNull("htree", htree2); // different reference. assertTrue(htree1 != htree2); } } finally { journal.destroy(); } } /** * Return a set of all named indices on the journal. * * @param jnl * The journal. * @param prefix * The prefix for those named indices (may be <code>null</code> * or empty). * @param timestamp * A timestamp which represents either a possible commit time on * the store or a read-only transaction identifier. * * @return The matching index names. The names will be reported in the * returned set in the same order in which they are reported by the * Journal. */ private static Set<String> getIndexNames(final Journal jnl, final String prefix, final long timestamp) { if (log.isInfoEnabled()) log.info("prefix=" + prefix + ", timestamp=" + TimestampUtility.toString(timestamp)); final Set<String> names = new LinkedHashSet<String>(); final Iterator<String> itr = jnl.indexNameScan(prefix, timestamp); while (itr.hasNext()) { final String name = itr.next(); names.add(name); } return names; } }