From: <tho...@us...> - 2013-05-07 15:09:35
|
Revision: 7113 http://bigdata.svn.sourceforge.net/bigdata/?rev=7113&view=rev Author: thompsonbry Date: 2013-05-07 15:09:24 +0000 (Tue, 07 May 2013) Log Message: ----------- Checkpoint on refactor that will introduce an index over the HALog files to reduce the latency at the commit. This abstracts out a common base class for the SnapshotIndex and the HALogIndex. The HALogIndex is not yet in use. The next step is to see if I can get the test suite to pass with the alt HALogManager class. See https://sourceforge.net/apps/trac/bigdata/ticket/670 (Accumulating HALog files cause latency for HA commit) Modified Paths: -------------- branches/READ_CACHE/bigdata/src/java/com/bigdata/btree/UnisolatedReadWriteIndex.java branches/READ_CACHE/bigdata/src/java/com/bigdata/ha/althalog/HALogFile.java branches/READ_CACHE/bigdata/src/java/com/bigdata/ha/althalog/HALogManager.java branches/READ_CACHE/bigdata/src/java/com/bigdata/ha/althalog/IHALogReader.java branches/READ_CACHE/bigdata/src/java/com/bigdata/ha/halog/HALogWriter.java branches/READ_CACHE/bigdata/src/java/com/bigdata/ha/halog/IHALogReader.java branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/DefaultRestorePolicy.java branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/HAJournal.java branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/HAJournalServer.java branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/HARestore.java branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/SnapshotIndex.java branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/SnapshotManager.java branches/READ_CACHE/bigdata-jini/src/test/com/bigdata/journal/jini/ha/AbstractHA3JournalServerTestCase.java branches/READ_CACHE/bigdata-jini/src/test/com/bigdata/journal/jini/ha/TestAll.java branches/READ_CACHE/bigdata-jini/src/test/com/bigdata/journal/jini/ha/TestHA3JournalServer.java branches/READ_CACHE/bigdata-jini/src/test/com/bigdata/journal/jini/ha/TestHA3SnapshotPolicy2.java branches/READ_CACHE/bigdata-jini/src/test/com/bigdata/journal/jini/ha/TestSnapshotIndex.java branches/READ_CACHE/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/HAStatusServletUtil.java Added Paths: ----------- branches/READ_CACHE/bigdata/src/java/com/bigdata/btree/DelegateBTree.java branches/READ_CACHE/bigdata/src/java/com/bigdata/journal/AbstractCommitTimeIndex.java branches/READ_CACHE/bigdata/src/java/com/bigdata/journal/ICommitTimeEntry.java branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/HALogIndex.java branches/READ_CACHE/bigdata-jini/src/test/com/bigdata/journal/jini/ha/TestHALogIndex.java Added: branches/READ_CACHE/bigdata/src/java/com/bigdata/btree/DelegateBTree.java =================================================================== --- branches/READ_CACHE/bigdata/src/java/com/bigdata/btree/DelegateBTree.java (rev 0) +++ branches/READ_CACHE/bigdata/src/java/com/bigdata/btree/DelegateBTree.java 2013-05-07 15:09:24 UTC (rev 7113) @@ -0,0 +1,77 @@ +/* + +Copyright (C) SYSTAP, LLC 2006-2008. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +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 20, 2008 + */ +package com.bigdata.btree; + +/** + * An object that delegates the {@link IIndex} and {@link ILinearList} + * interfaces. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + */ +public class DelegateBTree extends DelegateIndex implements ILinearList { + + private final ILinearList delegate; + + public DelegateBTree(final ILinearList ndx) { + + super((IIndex) ndx); + + this.delegate = ndx; + + } + + public DelegateBTree(final BTree btree) { + + super(btree); + + this.delegate = btree; + + } + + @Override + public long indexOf(final byte[] key) { + + return delegate.indexOf(key); + + } + + @Override + public byte[] keyAt(final long index) { + + return delegate.keyAt(index); + + } + + @Override + public byte[] valueAt(final long index) { + + return delegate.valueAt(index); + + } + +} Modified: branches/READ_CACHE/bigdata/src/java/com/bigdata/btree/UnisolatedReadWriteIndex.java =================================================================== --- branches/READ_CACHE/bigdata/src/java/com/bigdata/btree/UnisolatedReadWriteIndex.java 2013-05-07 11:25:20 UTC (rev 7112) +++ branches/READ_CACHE/bigdata/src/java/com/bigdata/btree/UnisolatedReadWriteIndex.java 2013-05-07 15:09:24 UTC (rev 7113) @@ -121,7 +121,7 @@ * @version $Id: UnisolatedReadWriteIndex.java 4054 2011-01-05 13:51:25Z * thompsonbry $ */ -public class UnisolatedReadWriteIndex implements IIndex { +public class UnisolatedReadWriteIndex implements IIndex, ILinearList { private static final Logger log = Logger.getLogger(UnisolatedReadWriteIndex.class); @@ -189,7 +189,7 @@ * * @return The acquired lock. */ - protected Lock readLock() { + public Lock readLock() { final Lock readLock = readWriteLock.readLock(); @@ -863,4 +863,34 @@ } + @Override + public long indexOf(final byte[] key) { + final Lock lock = readLock(); + try { + return ndx.indexOf(key); + } finally { + lock.unlock(); + } + } + + @Override + public byte[] keyAt(final long index) { + final Lock lock = readLock(); + try { + return ndx.keyAt(index); + } finally { + lock.unlock(); + } + } + + @Override + public byte[] valueAt(final long index) { + final Lock lock = readLock(); + try { + return ndx.valueAt(index); + } finally { + lock.unlock(); + } + } + } Modified: branches/READ_CACHE/bigdata/src/java/com/bigdata/ha/althalog/HALogFile.java =================================================================== --- branches/READ_CACHE/bigdata/src/java/com/bigdata/ha/althalog/HALogFile.java 2013-05-07 11:25:20 UTC (rev 7112) +++ branches/READ_CACHE/bigdata/src/java/com/bigdata/ha/althalog/HALogFile.java 2013-05-07 15:09:24 UTC (rev 7113) @@ -33,7 +33,6 @@ import java.nio.channels.FileChannel; import java.security.DigestException; import java.security.MessageDigest; -import java.util.Formatter; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; @@ -41,7 +40,6 @@ import org.apache.log4j.Logger; -import com.bigdata.btree.BytesUtil; import com.bigdata.ha.althalog.HALogManager.IHALogManagerCallback; import com.bigdata.ha.msg.IHAWriteMessage; import com.bigdata.io.DirectBufferPool; @@ -53,6 +51,7 @@ import com.bigdata.journal.RootBlockUtility; import com.bigdata.journal.RootBlockView; import com.bigdata.journal.StoreTypeEnum; +import com.bigdata.journal.jini.ha.CommitCounterUtility; import com.bigdata.rawstore.Bytes; import com.bigdata.util.ChecksumError; import com.bigdata.util.ChecksumUtility; @@ -173,9 +172,8 @@ public HALogFile(final IRootBlockView rbv, final IHALogManagerCallback callback) throws IOException { m_callback = callback; - final File hadir = m_callback.getHALogDir(); - m_haLogFile = new File(hadir, getHALogFileName(rbv.getCommitCounter()) - + IHALogReader.HA_LOG_EXT); + m_haLogFile = getHALogFileName(m_callback.getHALogDir(), + rbv.getCommitCounter()); if (m_haLogFile.exists()) throw new IllegalStateException("File already exists: " @@ -659,32 +657,34 @@ * @param commitCounter * @return */ - public static String getHALogFileName(final long commitCounter) { + public static File getHALogFileName(final File dir, final long commitCounter) { - /* - * Format the name of the log file. - * - * Note: The commit counter in the file name should be zero filled to 20 - * digits so we have the files in lexical order in the file system (for - * convenience). - */ - final String logFile; - { + return CommitCounterUtility.getCommitCounterFile(dir, commitCounter, + IHALogReader.HA_LOG_EXT); +// /* +// * Format the name of the log file. +// * +// * Note: The commit counter in the file name should be zero filled to 20 +// * digits so we have the files in lexical order in the file system (for +// * convenience). +// */ +// final String logFile; +// { +// +// final StringBuilder sb = new StringBuilder(); +// +// final Formatter f = new Formatter(sb); +// +// f.format("%020d" + IHALogReader.HA_LOG_EXT, commitCounter); +// f.flush(); +// f.close(); +// +// logFile = sb.toString(); +// +// } +// +// return logFile; - final StringBuilder sb = new StringBuilder(); - - final Formatter f = new Formatter(sb); - - f.format("%020d" + IHALogReader.HA_LOG_EXT, commitCounter); - f.flush(); - f.close(); - - logFile = sb.toString(); - - } - - return logFile; - } private class HALogAccess { Modified: branches/READ_CACHE/bigdata/src/java/com/bigdata/ha/althalog/HALogManager.java =================================================================== --- branches/READ_CACHE/bigdata/src/java/com/bigdata/ha/althalog/HALogManager.java 2013-05-07 11:25:20 UTC (rev 7112) +++ branches/READ_CACHE/bigdata/src/java/com/bigdata/ha/althalog/HALogManager.java 2013-05-07 15:09:24 UTC (rev 7113) @@ -174,7 +174,7 @@ m_currentLock.unlock(); } - final File file = new File(m_halogdir, HALogFile.getHALogFileName(commitCounter)); + final File file = HALogFile.getHALogFileName(m_halogdir, commitCounter); final HALogFile halog = new HALogFile(file); return halog.getReader(); @@ -192,7 +192,7 @@ /* * Check the file exists first */ - final File file = new File(m_halogdir, HALogFile.getHALogFileName(commitCounter)); + final File file = HALogFile.getHALogFileName(m_halogdir, commitCounter); if (!file.exists()) throw new FileNotFoundException(); Modified: branches/READ_CACHE/bigdata/src/java/com/bigdata/ha/althalog/IHALogReader.java =================================================================== --- branches/READ_CACHE/bigdata/src/java/com/bigdata/ha/althalog/IHALogReader.java 2013-05-07 11:25:20 UTC (rev 7112) +++ branches/READ_CACHE/bigdata/src/java/com/bigdata/ha/althalog/IHALogReader.java 2013-05-07 15:09:24 UTC (rev 7113) @@ -23,6 +23,8 @@ */ package com.bigdata.ha.althalog; +import java.io.File; +import java.io.FileFilter; import java.io.IOException; import java.nio.ByteBuffer; import java.security.DigestException; @@ -46,6 +48,29 @@ */ public static final String HA_LOG_EXT = ".ha-log"; + /** + * A {@link FileFilter} that visits all files ending with the + * {@link #HA_LOG_EXT} and the names of all direct child directories. This + * {@link FileFilter} may be used to establish recursive scans of the HALog + * directory. + */ + static public final FileFilter HALOG_FILTER = new FileFilter() { + + @Override + public boolean accept(final File f) { + + if (f.isDirectory()) { + + return true; + + } + + return f.getName().endsWith(HA_LOG_EXT); + + } + + }; + /** * Closes the Reader. * Modified: branches/READ_CACHE/bigdata/src/java/com/bigdata/ha/halog/HALogWriter.java =================================================================== --- branches/READ_CACHE/bigdata/src/java/com/bigdata/ha/halog/HALogWriter.java 2013-05-07 11:25:20 UTC (rev 7112) +++ branches/READ_CACHE/bigdata/src/java/com/bigdata/ha/halog/HALogWriter.java 2013-05-07 15:09:24 UTC (rev 7113) @@ -45,6 +45,7 @@ import com.bigdata.journal.RootBlockUtility; import com.bigdata.journal.RootBlockView; import com.bigdata.journal.StoreTypeEnum; +import com.bigdata.journal.jini.ha.CommitCounterUtility; import com.bigdata.rawstore.Bytes; /** @@ -177,38 +178,45 @@ } - /** - * Return the local name of the HA Log file associated with the - * - * @param commitCounter - * @return - */ - public static String getHALogFileName(final long commitCounter) { + /** + * Return the HA Log file associated with the commit counter. + * + * @param dir + * The HALog directory. + * @param commitCounter + * The commit counter. + * + * @return The HALog {@link File}. + */ + public static File getHALogFileName(final File dir, + final long commitCounter) { - /* - * Format the name of the log file. - * - * Note: The commit counter in the file name should be zero filled to 20 - * digits so we have the files in lexical order in the file system (for - * convenience). - */ - final String logFile; - { + return CommitCounterUtility.getCommitCounterFile(dir, commitCounter, + IHALogReader.HA_LOG_EXT); +// /* +// * Format the name of the log file. +// * +// * Note: The commit counter in the file name should be zero filled to 20 +// * digits so we have the files in lexical order in the file system (for +// * convenience). +// */ +// final String logFile; +// { +// +// final StringBuilder sb = new StringBuilder(); +// +// final Formatter f = new Formatter(sb); +// +// f.format("%020d" + IHALogReader.HA_LOG_EXT, commitCounter); +// f.flush(); +// f.close(); +// +// logFile = sb.toString(); +// +// } +// +// return logFile; - final StringBuilder sb = new StringBuilder(); - - final Formatter f = new Formatter(sb); - - f.format("%020d" + IHALogReader.HA_LOG_EXT, commitCounter); - f.flush(); - f.close(); - - logFile = sb.toString(); - - } - - return logFile; - } public String toString() { @@ -267,9 +275,12 @@ final long commitCounter = rootBlock.getCommitCounter(); - final String logFile = getHALogFileName(commitCounter + 1); +// final String logFile = getHALogFileName(commitCounter + 1); +// +// final File log = new File(m_haLogDir, logFile); + final File log = getHALogFileName(m_haLogDir, commitCounter + 1); - final File log = new File(m_haLogDir, logFile); +// final File log = new File(m_haLogDir, logFile); // Must delete file if it exists. if (log.exists() && !log.delete()) { @@ -678,8 +689,8 @@ public IHALogReader getReader(final long commitCounter) throws FileNotFoundException, IOException { - final File logFile = new File(m_haLogDir, - HALogWriter.getHALogFileName(commitCounter)); + final File logFile = //new File(m_haLogDir, + HALogWriter.getHALogFileName(m_haLogDir, commitCounter); final Lock lock = m_stateLock.readLock(); lock.lock(); Modified: branches/READ_CACHE/bigdata/src/java/com/bigdata/ha/halog/IHALogReader.java =================================================================== --- branches/READ_CACHE/bigdata/src/java/com/bigdata/ha/halog/IHALogReader.java 2013-05-07 11:25:20 UTC (rev 7112) +++ branches/READ_CACHE/bigdata/src/java/com/bigdata/ha/halog/IHALogReader.java 2013-05-07 15:09:24 UTC (rev 7113) @@ -55,7 +55,7 @@ static public final FileFilter HALOG_FILTER = new FileFilter() { @Override - public boolean accept(File f) { + public boolean accept(final File f) { if (f.isDirectory()) { Added: branches/READ_CACHE/bigdata/src/java/com/bigdata/journal/AbstractCommitTimeIndex.java =================================================================== --- branches/READ_CACHE/bigdata/src/java/com/bigdata/journal/AbstractCommitTimeIndex.java (rev 0) +++ branches/READ_CACHE/bigdata/src/java/com/bigdata/journal/AbstractCommitTimeIndex.java 2013-05-07 15:09:24 UTC (rev 7113) @@ -0,0 +1,533 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2007. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +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 +*/ +package com.bigdata.journal; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock; + +import com.bigdata.btree.BTree; +import com.bigdata.btree.DelegateBTree; +import com.bigdata.btree.ILinearList; +import com.bigdata.btree.IRangeQuery; +import com.bigdata.btree.ITuple; +import com.bigdata.btree.ITupleIterator; +import com.bigdata.btree.Tuple; +import com.bigdata.btree.UnisolatedReadWriteIndex; + +/** + * Abstract {@link BTree} mapping <em>commitTime</em> (long integers) to + * {@link ICommitTimeEntry} objects. + * <p> + * This class is thread-safe for concurrent readers and writers. + */ +public class AbstractCommitTimeIndex<T extends ICommitTimeEntry> extends + DelegateBTree implements ILinearList { + + /** + * The underlying index. Access to this is NOT thread safe unless you take + * the appropriate lock on the {@link #readWriteLock}. + */ + private final BTree btree; + + /** + * The {@link ReadWriteLock} used by the {@link UnisolatedReadWriteIndex} to + * make operations on the underlying {@link #btree} thread-safe. + */ + private final ReadWriteLock readWriteLock; + + @SuppressWarnings("unchecked") + private Tuple<T> getLookupTuple() { + + return btree.getLookupTuple(); + + } + +// /** +// * Instance used to encode the timestamp into the key. +// */ +// final private IKeyBuilder keyBuilder = new KeyBuilder(Bytes.SIZEOF_LONG); + + protected AbstractCommitTimeIndex(final BTree ndx) { + + // Wrap B+Tree for read/write thread safety. + super(new UnisolatedReadWriteIndex(ndx)); + + this.btree = ndx; + +// this.delegate = new UnisolatedReadWriteIndex(ndx); + + // Save reference to lock for extended synchronization patterns. + this.readWriteLock = UnisolatedReadWriteIndex.getReadWriteLock(ndx); + + } + + /** + * Encodes the commit time into a key. + * + * @param commitTime + * The commit time. + * + * @return The corresponding key. + */ + public byte[] getKey(final long commitTime) { + + return getIndexMetadata().getKeyBuilder().reset().append(commitTime) + .getKey(); + + } + + /** + * Returns (but does not take) the {@link ReadLock}. + */ + public Lock readLock() { + + return readWriteLock.readLock(); + + } + + /** + * Returns (but does not take) the {@link WriteLock}. + */ + public Lock writeLock() { + + return readWriteLock.writeLock(); + + } + + public long getEntryCount() { + + return super.rangeCount(); + + } + + @SuppressWarnings("unchecked") + public Tuple<T> valueAt(final long index, final Tuple<T> t) { + final Lock lock = readLock(); + lock.lock(); + try { + return btree.valueAt(index, t); + } finally { + lock.unlock(); + } + } + + /** + * Return the {@link IRootBlock} identifying the journal having the largest + * commitTime that is less than or equal to the given timestamp. This is + * used primarily to locate the commit record that will serve as the ground + * state for a transaction having <i>timestamp</i> as its start time. In + * this context the LTE search identifies the most recent commit state that + * not later than the start time of the transaction. + * + * @param timestamp + * The given timestamp. + * + * @return The description of the relevant journal resource -or- + * <code>null</code> iff there are no journals in the index that + * satisify the probe. + * + * @throws IllegalArgumentException + * if <i>timestamp</i> is less than ZERO (0L). + */ + public T find(final long timestamp) { + + if (timestamp < 0L) + throw new IllegalArgumentException(); + + final Lock lock = readLock(); + + lock.lock(); + + try { + + // find (first less than or equal to). + final long index = findIndexOf(timestamp); + + if (index == -1) { + + // No match. + return null; + + } + + return valueAtIndex(index); + + } finally { + + lock.unlock(); + + } + + } + + /** + * Retrieve the entry from the index. + */ + private T valueAtIndex(final long index) { + + return (T) valueAt(index, getLookupTuple()).getObject(); + +// final byte[] val = super.valueAt(index); +// +// assert val != null : "Entry has null value: index=" + index; +// +// final IRootBlockView entry = new RootBlockView(false/* rootBlock0 */, +// ByteBuffer.wrap(val), ChecksumUtility.getCHK()); +// +// return entry; + + } + + /** + * Return the first entry whose <em>commitTime</em> is strictly greater than + * the timestamp. + * + * @param timestamp + * The timestamp. A value of ZERO (0) may be used to find the + * first entry. + * + * @return The root block of that entry -or- <code>null</code> if there is + * no entry whose timestamp is strictly greater than + * <i>timestamp</i>. + * + * @throws IllegalArgumentException + * if <i>timestamp</i> is less than ZERO (0L). + */ + public T findNext(final long timestamp) { + + if (timestamp < 0L) + throw new IllegalArgumentException(); + + final Lock lock = readLock(); + + lock.lock(); + + try { + + // find first strictly greater than. + final long index = findIndexOf(timestamp) + 1; + + if (index == rangeCount()) { + + // No match. + + return null; + + } + + return valueAtIndex(index); + + } finally { + + lock.unlock(); + + } + + } + + /** + * Find the index of the entry associated with the largest commitTime that + * is less than or equal to the given timestamp. + * + * @param commitTime + * The timestamp. + * + * @return The index of the entry associated with the largest commitTime + * that is less than or equal to the given timestamp -or- + * <code>-1</code> iff the index is empty. + * + * @throws IllegalArgumentException + * if <i>timestamp</i> is less than ZERO (0L). + */ + public long findIndexOf(final long commitTime) { + + if (commitTime < 0L) + throw new IllegalArgumentException(); + + /* + * Note: Since this is the sole index access, we don't need to take the + * lock to coordinate a consistent view of the index in this method. + */ + long pos = indexOf(getKey(commitTime)); + + if (pos < 0) { + + /* + * the key lies between the entries in the index, or possible before + * the first entry in the index. [pos] represents the insert + * position. we convert it to an entry index and subtract one to get + * the index of the first commit record less than the given + * timestamp. + */ + + pos = -(pos+1); + + if (pos == 0) { + + // No entry is less than or equal to this timestamp. + return -1; + + } + + pos--; + + return pos; + + } else { + + /* + * exact hit on an entry. + */ + + return pos; + + } + + } + + /** + * Add an entry under the commitTime associated with the entry. + * + * @param entry + * The entry + * + * @exception IllegalArgumentException + * if <i>commitTime</i> is <code>0L</code>. + * @exception IllegalArgumentException + * if <i>rootBLock</i> is <code>null</code>. + * @exception IllegalArgumentException + * if there is already an entry registered under for the + * given timestamp. + */ + public void add(final T entry) { + + if (entry == null) + throw new IllegalArgumentException(); + + final long commitTime = entry.getCommitTime(); + + if (commitTime == 0L) + throw new IllegalArgumentException(); + + final Lock lock = writeLock(); + + lock.lock(); + + try { + + final byte[] key = getKey(commitTime); + + if (super.contains(key)) { + + throw new IllegalArgumentException("entry exists: timestamp=" + + commitTime); + + } + + // add a serialized entry to the persistent index. + super.insert(key, entry); + + } finally { + + lock.unlock(); + + } + + } + + /** + * Find and return the oldest entry (if any). + * + * @return That entry -or- <code>null</code> if there are no entries. + */ + public T getOldestEntry() { + + final Lock lock = readLock(); + + lock.lock(); + + try { + + if (rangeCount() == 0L) { + + // Empty index. + return null; + + } + + // Lookup first tuple in index. + final ITuple<T> t = valueAt(0L, getLookupTuple()); + + final T r = t.getObject(); + + return r; + + } finally { + + lock.unlock(); + + } + + } + + /** + * Find the the most recent entry (if any). + * + * @return That entry -or- <code>null</code> if there are no entries. + */ + public T getNewestEntry() { + + final Lock lock = readLock(); + + lock.lock(); + + try { + + final long entryCount = getEntryCount(); + + if (entryCount == 0L) + return null; + + return valueAt(entryCount - 1, getLookupTuple()).getObject(); + + } finally { + + lock.unlock(); + + } + + } + + /** + * Find the oldest entry whose commit counter is LTE the specified commit + * counter. + * + * @return The entry -or- <code>null</code> if there is no such entry. + * + * @throws IllegalArgumentException + * if <code>commitCounter LT ZERO (0)</code> + */ + public T findByCommitCounter(final long commitCounter) { + + if (commitCounter < 0L) + throw new IllegalArgumentException(); + + final Lock lock = readLock(); + + lock.lock(); + + try { + + // Reverse scan. + @SuppressWarnings("unchecked") + final ITupleIterator<T> itr = rangeIterator( + null/* fromKey */, null/* toKey */, 0/* capacity */, + IRangeQuery.DEFAULT | IRangeQuery.REVERSE/* flags */, null/* filter */); + + while (itr.hasNext()) { + + final ITuple<T> t = itr.next(); + + final T r = t.getObject(); + + final IRootBlockView rb = r.getRootBlock(); + + if (rb.getCommitCounter() <= commitCounter) { + + // First entry LTE that commit counter. + return r; + + } + + } + + return null; + + } finally { + + lock.unlock(); + + } + + } + + /** + * Return the entry that is associated with the specified ordinal index + * (origin ZERO) counting backwards from the most recent entry (0) towards + * the earliest entry (nentries-1). + * <p> + * Note: The effective index is given by <code>(entryCount-1)-index</code>. + * If the effective index is LT ZERO (0) then there is no such entry and + * this method will return <code>null</code>. + * + * @param index + * The index. + * + * @return The entry -or- <code>null</code> if there is no such entry. + * + * @throws IllegalArgumentException + * if <code>index LT ZERO (0)</code> + */ + public T getEntryByReverseIndex(final int index) { + + if (index < 0) + throw new IllegalArgumentException(); + + final Lock lock = readLock(); + + lock.lock(); + + try { + + final long entryCount = rangeCount(); + + if (entryCount > Integer.MAX_VALUE) + throw new AssertionError(); + + final int effectiveIndex = ((int) entryCount - 1) - index; + + if (effectiveIndex < 0) { + + // No such entry. + return null; + + } + + final ITuple<T> t = valueAt(effectiveIndex, + getLookupTuple()); + + final T r = t.getObject(); + + return r; + + } finally { + + lock.unlock(); + + } + + } + +} Added: branches/READ_CACHE/bigdata/src/java/com/bigdata/journal/ICommitTimeEntry.java =================================================================== --- branches/READ_CACHE/bigdata/src/java/com/bigdata/journal/ICommitTimeEntry.java (rev 0) +++ branches/READ_CACHE/bigdata/src/java/com/bigdata/journal/ICommitTimeEntry.java 2013-05-07 15:09:24 UTC (rev 7113) @@ -0,0 +1,244 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2007. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +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 +*/ +package com.bigdata.journal; + + +/** + * Interface for access to the snapshot metadata. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + */ +public interface ICommitTimeEntry { + + /** + * Return the bytes on the disk for the snapshot file. + */ + public long sizeOnDisk(); + + /** + * The commit counter associated with the index entry. + */ + public long getCommitCounter(); + + /** + * The commit time associated with the index entry. + */ + public long getCommitTime(); + + /** + * Return the {@link IRootBlockView} of the snapshot. + */ + public IRootBlockView getRootBlock(); + +//public static class SnapshotRecord implements ISnapshotRecord, +// Externalizable { +// +// private static final int VERSION0 = 0x0; +// +// private static final int currentVersion = VERSION0; +// +// /** +// * Note: This is NOT {@link Serializable}. +// */ +// private IRootBlockView rootBlock; +// +// private long sizeOnDisk; +// +// /** +// * De-serialization constructor. +// */ +// public SnapshotRecord() { +// } +// +// public SnapshotRecord(final IRootBlockView rootBlock, +// final long sizeOnDisk) { +// +// if (rootBlock == null) +// throw new IllegalArgumentException(); +// +// if (sizeOnDisk < 0L) +// throw new IllegalArgumentException(); +// +// this.rootBlock = rootBlock; +// +// this.sizeOnDisk = sizeOnDisk; +// +// } +// +// @Override +// public long sizeOnDisk() { +// return sizeOnDisk; +// } +// +// @Override +// public IRootBlockView getRootBlock() { +// return rootBlock; +// } +// +// @Override +// public boolean equals(final Object o) { +// if (this == o) +// return true; +// if (!(o instanceof ISnapshotRecord)) +// return false; +// final ISnapshotRecord t = (ISnapshotRecord) o; +// if (sizeOnDisk() != t.sizeOnDisk()) +// return false; +// if (!getRootBlock().equals(t.getRootBlock())) +// return false; +// return true; +// } +// +// @Override +// public int hashCode() { +// return getRootBlock().hashCode(); +// } +// +// @Override +// public void writeExternal(final ObjectOutput out) throws IOException { +// +// out.writeInt(currentVersion); +// +// final byte[] a = BytesUtil.getBytes(rootBlock.asReadOnlyBuffer()); +// +// final int sizeOfRootBlock = a.length; +// +// out.writeInt(sizeOfRootBlock); +// +// out.write(a, 0, sizeOfRootBlock); +// +// out.writeLong(sizeOnDisk); +// +// } +// +// @Override +// public void readExternal(final ObjectInput in) throws IOException, +// ClassNotFoundException { +// +// final int version = in.readInt(); +// +// switch (version) { +// case VERSION0: +// break; +// default: +// throw new IOException("Unknown version: " + version); +// } +// +// final int sizeOfRootBlock = in.readInt(); +// +// final byte[] a = new byte[sizeOfRootBlock]; +// +// in.readFully(a, 0, sizeOfRootBlock); +// +// rootBlock = new RootBlockView(false/* rootBlock0 */, +// ByteBuffer.wrap(a), ChecksumUtility.getCHK()); +// +// sizeOnDisk = in.readLong(); +// +// } +// +//} // SnapshotRecord +// +///** +// * Encapsulates key and value formation. +// * +// * @author <a href="mailto:tho...@us...">Bryan Thompson</a> +// */ +//static protected class TupleSerializer extends +// DefaultTupleSerializer<Long, ISnapshotRecord> { +// +// /** +// * +// */ +// private static final long serialVersionUID = -2851852959439807542L; +// +// /** +// * De-serialization ctor. +// */ +// public TupleSerializer() { +// +// super(); +// +// } +// +// /** +// * Ctor when creating a new instance. +// * +// * @param keyBuilderFactory +// */ +// public TupleSerializer(final IKeyBuilderFactory keyBuilderFactory) { +// +// super(keyBuilderFactory); +// +// } +// +// /** +// * Decodes the key as a commit time. +// */ +// @Override +// @SuppressWarnings("rawtypes") +// public Long deserializeKey(final ITuple tuple) { +// +// return KeyBuilder +// .decodeLong(tuple.getKeyBuffer().array(), 0/* offset */); +// +// } +// +// /** +// * The initial version (no additional persistent state). +// */ +// private final static transient byte VERSION0 = 0; +// +// /** +// * The current version. +// */ +// private final static transient byte VERSION = VERSION0; +// +// public void readExternal(final ObjectInput in) throws IOException, +// ClassNotFoundException { +// +// super.readExternal(in); +// +// final byte version = in.readByte(); +// +// switch (version) { +// case VERSION0: +// break; +// default: +// throw new UnsupportedOperationException("Unknown version: " +// + version); +// } +// +// } +// +// public void writeExternal(final ObjectOutput out) throws IOException { +// +// super.writeExternal(out); +// +// out.writeByte(VERSION); +// +// } + +} + Modified: branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/DefaultRestorePolicy.java =================================================================== --- branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/DefaultRestorePolicy.java 2013-05-07 11:25:20 UTC (rev 7112) +++ branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/DefaultRestorePolicy.java 2013-05-07 15:09:24 UTC (rev 7113) @@ -279,7 +279,7 @@ * returns its commit counter. If there is no such snapshot, then this * returns ZERO (0). */ - private long getEarliestRestorableCommitCounterByHALogs( + private long getEarliestRestorableCommitCounterByCommitPoints( final HAJournal jnl, final long commitCounterOnJournal) { // The commit point that is [minRestorePoints] old. @@ -329,7 +329,7 @@ final long commitCounterRetainedBySnapshotCount = getEarliestRestorableCommitCounterBySnapshots( jnl, commitCounterOnJournal); - final long commitCounterRetainedByHALogCount = getEarliestRestorableCommitCounterByHALogs( + final long commitCounterRetainedByHALogCount = getEarliestRestorableCommitCounterByCommitPoints( jnl, commitCounterOnJournal); /* Modified: branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/HAJournal.java =================================================================== --- branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/HAJournal.java 2013-05-07 11:25:20 UTC (rev 7112) +++ branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/HAJournal.java 2013-05-07 15:09:24 UTC (rev 7113) @@ -540,19 +540,8 @@ super.deleteResources(); - recursiveDelete(getHALogDir(), new FileFilter() { - - @Override - public boolean accept(File f) { + recursiveDelete(getHALogDir(), IHALogReader.HALOG_FILTER); - if (f.isDirectory()) - return true; - - return f.getName().endsWith(IHALogReader.HA_LOG_EXT); - } - - }); - recursiveDelete(getSnapshotManager().getSnapshotDir(), SnapshotManager.SNAPSHOT_FILTER); @@ -662,8 +651,8 @@ // The commit counter of the desired closing root block. final long commitCounter = msg.getCommitCounter(); - final File logFile = new File(getHALogDir(), - HALogWriter.getHALogFileName(commitCounter)); + final File logFile = HALogWriter.getHALogFileName( + getHALogDir(), commitCounter); if (!logFile.exists()) { Modified: branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/HAJournalServer.java =================================================================== --- branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/HAJournalServer.java 2013-05-07 11:25:20 UTC (rev 7112) +++ branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/HAJournalServer.java 2013-05-07 15:09:24 UTC (rev 7113) @@ -3342,155 +3342,6 @@ } -// /** -// * Delete snapshots that are no longer required. -// * <p> -// * Note: If ZERO (0) is passed into this method, then no snapshots will -// * be deleted. This is because the first possible commit counter is ONE -// * (1). -// * -// * @param earliestRestorableCommitPoint -// * The earliest commit point that we need to be able to -// * restore from local backups. -// * -// * @return The commitCounter of the earliest retained snapshot. -// */ -// private long deleteSnapshots(final long token, -// final long earliestRestorableCommitPoint) { -// /* -// * List the snapshot files for this service. -// */ -// final File[] files; -// // #of snapshot files found. Set during scan. -// final AtomicLong nfound = new AtomicLong(); -// // Set to the commit counter of the earliest retained snapshot. -// final AtomicLong earliestRetainedSnapshotCommitCounter = new AtomicLong(Long.MAX_VALUE); -// final SnapshotManager snapshotManager = journal -// .getSnapshotManager(); -// { -// -// final File snapshotDir = snapshotManager.getSnapshotDir(); -// -// files = snapshotDir.listFiles(new FilenameFilter() { -// -// /** -// * Return <code>true</code> iff the file is an snapshot file -// * that should be deleted. -// * -// * @param name -// * The name of that file (encodes the -// * commitCounter). -// */ -// @Override -// public boolean accept(final File dir, final String name) { -// -// if (!name.endsWith(SnapshotManager.SNAPSHOT_EXT)) { -// // Not an snapshot file. -// return false; -// } -// -// // Closing commitCounter for snapshot file. -// final long commitCounter = SnapshotManager -// .parseCommitCounterFile(name); -// -// // Count all snapshot files. -// nfound.incrementAndGet(); -// -// // true iff we will delete this snapshot. -// final boolean deleteFile = commitCounter < earliestRestorableCommitPoint; -// -// if (haLog.isInfoEnabled()) -// log.info("snapshotFile=" -// + name// -// + ", deleteFile=" -// + deleteFile// -// + ", commitCounter=" -// + commitCounter// -// + ", earliestRestoreableCommitPoint=" -// + earliestRestorableCommitPoint); -// -// if (!deleteFile -// && commitCounter < earliestRetainedSnapshotCommitCounter -// .get()) { -// -// /* -// * Update the earliest retained snapshot. -// */ -// -// earliestRetainedSnapshotCommitCounter -// .set(commitCounter); -// -// } -// -// return deleteFile; -// -// } -// }); -// -// } -// -// int ndeleted = 0; -// long totalBytes = 0L; -// -// /* -// * If people specify NoSnapshotPolicy then backup is in their hands. -// * HALogs will not be retained beyond a fully met commit unless -// * there is a snapshot against which they can be applied.. -// */ -// -//// if (files.length == 0) { -//// -//// /* -//// * Note: If there are no snapshots then we MUST retain ALL HALog -//// * files. -//// */ -//// earliestRetainedSnapshotCommitCounter.set(0L); -//// -//// } else { -// -// for (File file : files) { -// -// // #of bytes in that file. -// final long len = file.length(); -// -// if (!getQuorum().isQuorumFullyMet(token)) { -// /* -// * Halt operation. -// * -// * Note: This is not an error, but we can not remove -// * snapshots or HALogs if this invariant is violated. -// */ -// break; -// } -// -// if (!snapshotManager.removeSnapshot(file)) { -// -// haLog.warn("COULD NOT DELETE FILE: " + file); -// -// continue; -// -// } -// -// ndeleted++; -// -// totalBytes += len; -// -// } -// -//// } -// -// if (haLog.isInfoEnabled()) -// haLog.info("PURGED SNAPSHOTS: nfound=" + nfound + ", ndeleted=" -// + ndeleted + ", totalBytes=" + totalBytes -// + ", earliestRestorableCommitPoint=" -// + earliestRestorableCommitPoint -// + ", earliestRetainedSnapshotCommitCounter=" -// + earliestRetainedSnapshotCommitCounter.get()); -// -// return earliestRetainedSnapshotCommitCounter.get(); -// -// } - /** * Delete HALogs that are no longer required. * Added: branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/HALogIndex.java =================================================================== --- branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/HALogIndex.java (rev 0) +++ branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/HALogIndex.java 2013-05-07 15:09:24 UTC (rev 7113) @@ -0,0 +1,323 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2007. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +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 +*/ +package com.bigdata.journal.jini.ha; + +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.io.Serializable; +import java.nio.ByteBuffer; +import java.util.UUID; + +import com.bigdata.btree.BTree; +import com.bigdata.btree.BytesUtil; +import com.bigdata.btree.DefaultTupleSerializer; +import com.bigdata.btree.ITuple; +import com.bigdata.btree.IndexMetadata; +import com.bigdata.btree.keys.ASCIIKeyBuilderFactory; +import com.bigdata.btree.keys.IKeyBuilderFactory; +import com.bigdata.btree.keys.KeyBuilder; +import com.bigdata.journal.AbstractCommitTimeIndex; +import com.bigdata.journal.ICommitTimeEntry; +import com.bigdata.journal.IRootBlockView; +import com.bigdata.journal.RootBlockView; +import com.bigdata.journal.jini.ha.HALogIndex.IHALogRecord; +import com.bigdata.rawstore.Bytes; +import com.bigdata.util.ChecksumUtility; + +/** + * {@link BTree} mapping <em>commitTime</em> (long integers) to + * {@link IHALogRecord} records for each closed HALog file. HALog files are + * added to this index when their closing {@link IRootBlockView} is applied. + * Thus, the live HALog is not entered into this index until it the closing + * {@link IRootBlockView} has been applied. + * <p> + * This object is thread-safe for concurrent readers and writers. + * <p> + * Note: This is used as a transient data structure that is populated from the + * file system by the {@link HAJournalServer}. + */ +public class HALogIndex extends AbstractCommitTimeIndex<IHALogRecord> { + + /** + * Create a transient instance. + * + * @return The new instance. + */ + static public HALogIndex createTransient() { + + final IndexMetadata metadata = new IndexMetadata(UUID.randomUUID()); + + metadata.setTupleSerializer(new TupleSerializer( + new ASCIIKeyBuilderFactory(Bytes.SIZEOF_LONG))); + + final BTree ndx = BTree.createTransient(/*store, */metadata); + + return new HALogIndex(ndx); + + } + + private HALogIndex(final BTree ndx) { + + super(ndx); + + } + + /** + * Interface for access to the HALog metadata. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + */ + public static interface IHALogRecord extends ICommitTimeEntry { + +// /** +// * Return the bytes on the disk for the HALog file. +// */ +// public long sizeOnDisk(); + + /** + * Return the closing {@link IRootBlockView} of the HALog file. + */ + @Override + public IRootBlockView getRootBlock(); + + } + + public static class HALogRecord implements IHALogRecord, + Externalizable { + + private static final int VERSION0 = 0x0; + + private static final int currentVersion = VERSION0; + + /** + * Note: This is NOT {@link Serializable}. + */ + private IRootBlockView rootBlock; + + private long sizeOnDisk; + + /** + * De-serialization constructor. + */ + public HALogRecord() { + } + + public HALogRecord(final IRootBlockView rootBlock, + final long sizeOnDisk) { + + if (rootBlock == null) + throw new IllegalArgumentException(); + + if (sizeOnDisk < 0L) + throw new IllegalArgumentException(); + + this.rootBlock = rootBlock; + + this.sizeOnDisk = sizeOnDisk; + + } + + @Override + public long sizeOnDisk() { + return sizeOnDisk; + } + + @Override + public IRootBlockView getRootBlock() { + return rootBlock; + } + + @Override + public boolean equals(final Object o) { + if (this == o) + return true; + if (!(o instanceof IHALogRecord)) + return false; + final IHALogRecord t = (IHALogRecord) o; + if (sizeOnDisk() != t.sizeOnDisk()) + return false; + if (!getRootBlock().equals(t.getRootBlock())) + return false; + return true; + } + + @Override + public int hashCode() { + return getRootBlock().hashCode(); + } + + @Override + public void writeExternal(final ObjectOutput out) throws IOException { + + out.writeInt(currentVersion); + + final byte[] a = BytesUtil.getBytes(rootBlock.asReadOnlyBuffer()); + + final int sizeOfRootBlock = a.length; + + out.writeInt(sizeOfRootBlock); + + out.write(a, 0, sizeOfRootBlock); + + out.writeLong(sizeOnDisk); + + } + + @Override + public void readExternal(final ObjectInput in) throws IOException, + ClassNotFoundException { + + final int version = in.readInt(); + + switch (version) { + case VERSION0: + break; + default: + throw new IOException("Unknown version: " + version); + } + + final int sizeOfRootBlock = in.readInt(); + + final byte[] a = new byte[sizeOfRootBlock]; + + in.readFully(a, 0, sizeOfRootBlock); + + rootBlock = new RootBlockView(false/* rootBlock0 */, + ByteBuffer.wrap(a), ChecksumUtility.getCHK()); + + sizeOnDisk = in.readLong(); + + } + + @Override + public long getCommitCounter() { + return getRootBlock().getCommitCounter(); + } + + @Override + public long getCommitTime() { + return getRootBlock().getLastCommitTime(); + } + + } // HALogRecord + + /** + * Encapsulates key and value formation. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + */ + static protected class TupleSerializer extends + DefaultTupleSerializer<Long, IHALogRecord> { + + /** + * + */ + private static final long serialVersionUID = -2851852959439807542L; + + /** + * De-serialization ctor. + */ + public TupleSerializer() { + + super(); + + } + + /** + * Ctor when creating a new instance. + * + * @param keyBuilderFactory + */ + public TupleSerializer(final IKeyBuilderFactory keyBuilderFactory) { + + super(keyBuilderFactory); + + } + + /** + * Decodes the key as a commit time. + */ + @Override + @SuppressWarnings("rawtypes") + public Long deserializeKey(final ITuple tuple) { + + return KeyBuilder + .decodeLong(tuple.getKeyBuffer().array(), 0/* offset */); + + } + +// /** +// * De-serializes an object from the {@link ITuple#getValue() value} stored +// * in the tuple (ignores the key stored in the tuple). +// */ +// public IHALogRecord deserialize(final ITuple tuple) { +// +// if (tuple == null) +// throw new IllegalArgumentException(); +// +// return (IRootBlockView) new RootBlockView(false/* rootBlock0 */, +// ByteBuffer.wrap(tuple.getValue()), ChecksumUtility.getCHK()); +// +// } + + /** + * The initial version (no additional persistent state). + */ + private final static transient byte VERSION0 = 0; + + /** + * The current version. + */ + private final static transient byte VERSION = VERSION0; + + public void readExternal(final ObjectInput in) throws IOException, + ClassNotFoundException { + + super.readExternal(in); + + final byte version = in.readByte(); + + switch (version) { + case VERSION0: + break; + default: + throw new UnsupportedOperationException("Unknown version: " + + version); + } + + } + + public void writeExternal(final ObjectOutput out) throws IOException { + + super.writeExternal(out); + + out.writeByte(VERSION); + + } + + } + +} Modified: branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/HARestore.java =================================================================== --- branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/HARestore.java 2013-05-07 11:25:20 UTC (rev 7112) +++ branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/HARestore.java 2013-05-07 15:09:24 UTC (rev 7113) @@ -127,8 +127,7 @@ } - final File logFile = new File(haLogDir, - HALogWriter.getHALogFileName(cc)); + final File logFile = HALogWriter.getHALogFileName(haLogDir, cc); if (!logFile.exists()) { Modified: branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/SnapshotIndex.java =================================================================== --- branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/SnapshotIndex.java 2013-05-07 11:25:20 UTC (rev 7112) +++ branches/READ_CACHE/bigdata-jini/src/java/com/bigdata/journal/jini/ha/SnapshotIndex.java 2013-05-07 15:09:24 UTC (rev 7113) @@ -30,25 +30,20 @@ import java.io.Serializable; import java.nio.ByteBuffer; import java.util.UUID; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReadWriteLock; import com.bigdata.btree.BTree; import com.bigdata.btree.BytesUtil; import com.bigdata.btree.DefaultTupleSerializer; -import com.bigdata.btree.DelegateIndex; -import com.bigdata.btree.ILinearList; -import com.bigdata.btree.IRangeQuery; import com.bigdata.btree.ITuple; -import com.bigdata.btree.ITupleIterator; import com.bigdata.btree.IndexMetadata; -import com.bigdata.btree.Tuple; -import com.bigdata.btree.UnisolatedReadWriteIndex; import com.bigdata.btree.keys.ASCIIKeyBuilderFactory; import com.bigdata.btree.keys.IKeyBuilderFactory; import com.bigdata.btree.keys.KeyBuilder; +import com.bigdata.journal.AbstractCommitTimeIndex; +import com.bigdata.journal.ICommitTimeEntry; import com.bigdata.journal.IRootBlockView; import com.bigdata.journal.RootBlockView; +import com.bigdata.journal.jini.ha.SnapshotIndex.ISnapshotRecord; import com.bigdata.rawstore.Bytes; import com.bigdata.util.ChecksumUtility; @@ -61,31 +56,13 @@ * Note: This is used as a transient data structure that is populated from the * file system by the {@link HAJournalServer}. */ -public class SnapshotIndex extends DelegateIndex implements ILinearList { - - /** - * The underlying index. Access to this is NOT thread safe unless you take - * the appropriate lock on the {@link #readWriteLock}. - */ - private final BTree btree; - - /** - * The {@link ReadWriteLock} used by the {@link UnisolatedReadWriteIndex} to - * make operations on the underlying {@link #btree} thread-safe. - */ - private final ReadWriteLock readWriteLock; +public class SnapshotIndex extends AbstractCommitTimeIndex<ISnapshotRecord> { - @SuppressWarnings("unchecked") - private Tuple<ISnapshotRecord> getLookupTuple() { - - return btree.getLookupTuple(); - - } - // /** -// * Instance used to encode the timestamp into the key. +// * The underlying index. Access to this is NOT thread safe unless you take +// * the appropriate lock on the {@link #readWriteLock}. // */ -// final private IKeyBuilder keyBuilder = new KeyBuilder(Bytes.SIZEOF_LONG); +// private final BTree btree; /** * Create a transient instance. @@ -110,15 +87,15 @@ private SnapshotIndex(final BTree ndx) { // Wrap B+Tree for read/write thread safety. - super(new UnisolatedReadWriteIndex(ndx)); + super(ndx); - this.btree = ndx; +// this.btree = ndx; +// +//// this.delegate = new UnisolatedReadWriteIndex(ndx); +// +// // Save reference to lock for extended synchronization patterns. +// this.readWriteLock = Unisola... [truncated message content] |