All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bigdata.btree.ReadCommittedView Maven / Gradle / Ivy

/*

Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016.  All rights reserved.

Contact:
     SYSTAP, LLC DBA Blazegraph
     2501 Calvert ST NW #106
     Washington, DC 20008
     [email protected]

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 Oct 3, 2008
 */

package com.bigdata.btree;

import com.bigdata.btree.proc.AbstractKeyArrayIndexProcedureConstructor;
import com.bigdata.btree.proc.IKeyRangeIndexProcedure;
import com.bigdata.btree.proc.IResultHandler;
import com.bigdata.btree.proc.ISimpleIndexProcedure;
import com.bigdata.counters.CounterSet;
import com.bigdata.journal.AbstractJournal;
import com.bigdata.journal.ICommitRecord;
import com.bigdata.journal.IResourceManager;
import com.bigdata.journal.Journal;
import com.bigdata.mdi.IResourceMetadata;
import com.bigdata.resources.IndexManager;
import com.bigdata.resources.StoreManager.ManagedJournal;

import cutthecrap.utils.striterators.IFilter;

/**
 * A view of a named index that replaces its view for each high-level request if
 * there has been an intervening commit on the backing store. Each request,
 * including each iterator request, will be read-consistent as
 * of the commit point resolved for that request. However, subsequent requests
 * will, of course, be read-consistent against then then current lastCommitTime.
 * 

* This class is designed to work both with a {@link Journal} and with an * {@link IndexManager}. For the latter, the live {@link ManagedJournal} will * periodically be replaced by another {@link ManagedJournal}. This means that * we need two levels of indirection. First, we need to be able to identify the * current journal and read the lastCommitTime off of the current root block for * that journal. Second, we need to replace the view of the {@link BTree} for * the named index with the canonical read-only {@link BTree} instance loaded * from the commit record corresponding to the lastCommitTime. *

* Note: We are not required to obtain a lock on the live journal since it will * not be closed if it overflows, just closed for writes. Therefore this class * will provide a read-committed view as of (a) the moment that it obtains the * then current journal; and (b) checks the lastCommitTime on that journal. If * there are intervening commits or an overflow event then the data will be * "only slightly stale". *

* Note: This class has very little state of its own. The bulk of the state is * on the {@link BTree} objects corresponding to the lastCommitTime. Those are * thread-safe for readers and are shared across instances of this class. *

* Note: At any given moment, two instances of this class for the same named * index MAY have a different view. However, the views will always reflect the * lastCommitTime for each instance that is resolved when a method is invoked on * its public API. * * @author Bryan Thompson */ public class ReadCommittedView implements ILocalBTreeView { /** * Class encapsulates the state that provides the basis for the current * view. A new instance is allocated if (a) the live journal is changed; or * (b) the lastCommitTime on the journal is changed. * * @author Bryan Thompson */ private static class Basis { final AbstractJournal journal; final ICommitRecord commitRecord; final BTree btree; /** * * @param journal * The live journal. * @param name * The name of the index. */ public Basis(final AbstractJournal journal, final String name) { // the live journal. this.journal = journal; // the most current commit point. this.commitRecord = journal.getCommitRecord(); // the read-only view of the index as of that commit point. this.btree = (BTree) journal.getIndexWithCommitRecord(name, commitRecord); } } private final IResourceManager resourceManager; private final String name; private volatile Basis basis; /** * Return the read-committed view. * * @return the index */ synchronized private BTree getIndex() { final AbstractJournal journal = resourceManager.getLiveJournal(); if (journal != basis.journal || journal.getLastCommitTime() != basis.commitRecord .getTimestamp()) { basis = new Basis(journal, name); } /* * Note: We rely on the BTree returned here to enforce the read-only * contract for this view. */ assert basis.btree.isReadOnly(); return basis.btree; } /** * * @param resourceManager * The object that will report to us the live journal. * @param name * The name of the index. */ public ReadCommittedView(IResourceManager resourceManager, String name) { if (resourceManager == null) throw new IllegalArgumentException(); if (name == null) throw new IllegalArgumentException(); this.resourceManager = resourceManager; this.name = name; this.basis = new Basis(resourceManager.getLiveJournal(), name); } @Override public ICounter getCounter() { return getIndex().getCounter(); } @Override public CounterSet getCounters() { return getIndex().getCounters(); } @Override public IndexMetadata getIndexMetadata() { return getIndex().getIndexMetadata(); } @Override public IResourceMetadata[] getResourceMetadata() { return getIndex().getResourceMetadata(); } @Override public boolean contains(byte[] key) { return getIndex().contains(key); } @Override public boolean contains(Object key) { return getIndex().contains(key); } @Override public byte[] lookup(byte[] key) { return getIndex().lookup(key); } @Override public Object lookup(Object key) { return getIndex().lookup(key); } @Override public byte[] remove(byte[] key) { throw new UnsupportedOperationException(); } @Override public Object remove(Object key) { throw new UnsupportedOperationException(); } @Override public byte[] insert(byte[] key, byte[] value) { throw new UnsupportedOperationException(); } @Override public byte[] putIfAbsent(byte[] key, byte[] value) { throw new UnsupportedOperationException(); } @Override public Object insert(Object key, Object value) { throw new UnsupportedOperationException(); } @Override public long rangeCount() { return getIndex().rangeCount(); } @Override public long rangeCount(byte[] fromKey, byte[] toKey) { return getIndex().rangeCount(fromKey, toKey); } @Override public long rangeCountExact(byte[] fromKey, byte[] toKey) { return getIndex().rangeCountExact(fromKey, toKey); } @Override public long rangeCountExactWithDeleted(byte[] fromKey, byte[] toKey) { return getIndex().rangeCountExactWithDeleted(fromKey, toKey); } /* * Note: We rely on the BTree returned by getIndex() to enforce the * read-only contract for the iterators exposed by this class. */ /** * Note: The iterators returned by this view will be * read-consistent as of the lastCommitTime when they are * created. In order for newly committed state to be visible you must * request a new iterator. */ @Override public ITupleIterator rangeIterator() { return getIndex().rangeIterator(); } @Override public ITupleIterator rangeIterator(byte[] fromKey, byte[] toKey, int capacity, int flags, IFilter filterCtor) { return getIndex().rangeIterator(fromKey, toKey, capacity, flags, filterCtor); } @Override public ITupleIterator rangeIterator(byte[] fromKey, byte[] toKey) { return getIndex().rangeIterator(fromKey, toKey); } /* * Note: We rely on the BTree returned by getIndex() to enforce the * read-only contract for the procedures processed by this class. */ @Override public void submit(byte[] fromKey, byte[] toKey, IKeyRangeIndexProcedure proc, IResultHandler handler) { getIndex().submit(fromKey, toKey, proc, handler); } @Override public Object submit(byte[] key, ISimpleIndexProcedure proc) { return getIndex().submit(key, proc); } @Override public void submit(int fromIndex, int toIndex, byte[][] keys, byte[][] vals, AbstractKeyArrayIndexProcedureConstructor ctor, IResultHandler resultHandler) { getIndex().submit(fromIndex, toIndex, keys, vals, ctor, resultHandler); } // public final BTreeCounters getBTreeCounters() { // // return getIndex().getBtreeCounters(); // // } @Override public IBloomFilter getBloomFilter() { return getIndex().getBloomFilter(); } @Override public BTree getMutableBTree() { return getIndex().getMutableBTree(); } @Override public int getSourceCount() { return getIndex().getSourceCount(); } @Override public AbstractBTree[] getSources() { return getIndex().getSources(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy