Merge lp:~pbeaman/akiban-persistit/better_4hour_tpcc_3 into lp:akiban-persistit

Proposed by Peter Beaman
Status: Merged
Approved by: Nathan Williams
Approved revision: 374
Merged at revision: 359
Proposed branch: lp:~pbeaman/akiban-persistit/better_4hour_tpcc_3
Merge into: lp:akiban-persistit
Diff against target: 2717 lines (+700/-360)
109 files modified
src/main/java/com/persistit/Buffer.java (+96/-62)
src/main/java/com/persistit/CLI.java (+1/-1)
src/main/java/com/persistit/CleanupManager.java (+10/-0)
src/main/java/com/persistit/Exchange.java (+4/-0)
src/main/java/com/persistit/IOMeter.java (+16/-9)
src/main/java/com/persistit/JournalManager.java (+69/-33)
src/main/java/com/persistit/JournalManagerBench.java (+186/-0)
src/main/java/com/persistit/JournalTool.java (+5/-8)
src/main/java/com/persistit/MVV.java (+33/-1)
src/main/java/com/persistit/Transaction.java (+10/-4)
src/main/java/com/persistit/TransactionIndex.java (+1/-1)
src/main/java/com/persistit/mxbeans/IOMeterMXBean.java (+6/-6)
src/main/java/com/persistit/mxbeans/JournalManagerMXBean.java (+6/-0)
src/test/java/com/persistit/AccumulatorMemoryTest.java (+0/-2)
src/test/java/com/persistit/AccumulatorRecoveryTest.java (+0/-1)
src/test/java/com/persistit/AccumulatorTest.java (+0/-1)
src/test/java/com/persistit/AlertMonitorTest.java (+0/-1)
src/test/java/com/persistit/BackupTaskTest.java (+0/-1)
src/test/java/com/persistit/BufferMaxPack.java (+0/-1)
src/test/java/com/persistit/BufferPoolTest.java (+0/-1)
src/test/java/com/persistit/BufferTest.java (+0/-1)
src/test/java/com/persistit/BufferTest2.java (+0/-1)
src/test/java/com/persistit/Bug1003578Test.java (+0/-1)
src/test/java/com/persistit/Bug1017957Test.java (+0/-1)
src/test/java/com/persistit/Bug1018526Test.java (+0/-1)
src/test/java/com/persistit/Bug706132Test.java (+0/-1)
src/test/java/com/persistit/Bug708592Test.java (+0/-1)
src/test/java/com/persistit/Bug739533Test.java (+0/-2)
src/test/java/com/persistit/Bug777918Test.java (+0/-1)
src/test/java/com/persistit/Bug790709Test.java (+0/-2)
src/test/java/com/persistit/Bug870352Test.java (+0/-2)
src/test/java/com/persistit/Bug877656Test.java (+0/-2)
src/test/java/com/persistit/Bug882219Test.java (+0/-1)
src/test/java/com/persistit/Bug885477Test.java (+0/-2)
src/test/java/com/persistit/Bug889850Test.java (+0/-2)
src/test/java/com/persistit/Bug911849Test.java (+0/-1)
src/test/java/com/persistit/Bug912514Test.java (+0/-2)
src/test/java/com/persistit/Bug915594Test.java (+0/-2)
src/test/java/com/persistit/Bug918909Test.java (+0/-2)
src/test/java/com/persistit/Bug920754Test.java (+0/-2)
src/test/java/com/persistit/Bug923790Test.java (+0/-1)
src/test/java/com/persistit/Bug927701Test.java (+1/-3)
src/test/java/com/persistit/Bug932097Test.java (+0/-2)
src/test/java/com/persistit/Bug937877Test.java (+0/-1)
src/test/java/com/persistit/Bug942669Test.java (+0/-2)
src/test/java/com/persistit/Bug947182Test.java (+0/-1)
src/test/java/com/persistit/Bug974589Test.java (+0/-1)
src/test/java/com/persistit/Bug980292Test.java (+0/-1)
src/test/java/com/persistit/Bug989202Test.java (+0/-2)
src/test/java/com/persistit/Bug992801Test.java (+0/-2)
src/test/java/com/persistit/Bug996241Test.java (+0/-1)
src/test/java/com/persistit/ClassIndexTest.java (+0/-1)
src/test/java/com/persistit/CleanupManagerTest.java (+0/-1)
src/test/java/com/persistit/CommandLineTest.java (+0/-1)
src/test/java/com/persistit/ConfigurationTest.java (+0/-1)
src/test/java/com/persistit/CorruptVolumeTest.java (+0/-1)
src/test/java/com/persistit/DumpTaskTest.java (+0/-1)
src/test/java/com/persistit/FastIndexTest.java (+0/-1)
src/test/java/com/persistit/FatalErrorExceptionTest.java (+0/-1)
src/test/java/com/persistit/IOFailureTest.java (+0/-1)
src/test/java/com/persistit/IOMeterChargeBenchmark.java (+0/-2)
src/test/java/com/persistit/InsertSequenceTest.java (+0/-1)
src/test/java/com/persistit/IntegrityCheckTest.java (+5/-7)
src/test/java/com/persistit/JournalManagerTest.java (+4/-1)
src/test/java/com/persistit/KeyHistogramTest.java (+0/-2)
src/test/java/com/persistit/MVCCPruneBufferTest.java (+25/-4)
src/test/java/com/persistit/MVCCTestBase.java (+0/-1)
src/test/java/com/persistit/PersistitUnitTestCase.java (+136/-0)
src/test/java/com/persistit/RecoveryTest.java (+2/-1)
src/test/java/com/persistit/SplitPolicyTest.java (+0/-1)
src/test/java/com/persistit/StatisticsTaskTest.java (+0/-1)
src/test/java/com/persistit/TransactionLifetimeTest.java (+4/-1)
src/test/java/com/persistit/TransactionTest2.java (+0/-1)
src/test/java/com/persistit/TreeLifetimeTest.java (+0/-1)
src/test/java/com/persistit/TreeTest2.java (+0/-2)
src/test/java/com/persistit/ValueTest7.java (+0/-1)
src/test/java/com/persistit/VolumeTest.java (+0/-1)
src/test/java/com/persistit/WarmupTest.java (+0/-2)
src/test/java/com/persistit/stress/unit/CommitBench.java (+51/-7)
src/test/java/com/persistit/stress/unit/TestSamePageOptimization.java (+1/-1)
src/test/java/com/persistit/unit/BufferPoolMemConfigurationTest.java (+1/-0)
src/test/java/com/persistit/unit/DefaultCoderManagerTest.java (+1/-0)
src/test/java/com/persistit/unit/ExchangeTest.java (+1/-0)
src/test/java/com/persistit/unit/FileLockTest.java (+1/-0)
src/test/java/com/persistit/unit/JoinTest1.java (+1/-0)
src/test/java/com/persistit/unit/KeyCoderTest1.java (+1/-0)
src/test/java/com/persistit/unit/KeyFilterTest1.java (+1/-0)
src/test/java/com/persistit/unit/KeyFilterTest2.java (+1/-0)
src/test/java/com/persistit/unit/KeyParserTest1.java (+1/-0)
src/test/java/com/persistit/unit/KeyParserTest2.java (+1/-0)
src/test/java/com/persistit/unit/KeyTest1.java (+1/-0)
src/test/java/com/persistit/unit/Log4JLoggerTest.java (+1/-0)
src/test/java/com/persistit/unit/LongRecordTest1.java (+1/-0)
src/test/java/com/persistit/unit/LotsaSmallKeys.java (+1/-0)
src/test/java/com/persistit/unit/PersistitMapTest.java (+1/-0)
src/test/java/com/persistit/unit/PersistitUnitTestCase.java (+0/-133)
src/test/java/com/persistit/unit/SaveLoadTest1.java (+1/-0)
src/test/java/com/persistit/unit/SimpleTest1.java (+1/-0)
src/test/java/com/persistit/unit/TemporaryVolumeTest1.java (+1/-0)
src/test/java/com/persistit/unit/TransactionTest1.java (+1/-0)
src/test/java/com/persistit/unit/TransactionTest3.java (+1/-0)
src/test/java/com/persistit/unit/TreeTest1.java (+1/-0)
src/test/java/com/persistit/unit/ValueCoderTest1.java (+1/-0)
src/test/java/com/persistit/unit/ValueCoderTest2.java (+1/-0)
src/test/java/com/persistit/unit/ValueTest1.java (+1/-0)
src/test/java/com/persistit/unit/ValueTest2.java (+1/-0)
src/test/java/com/persistit/unit/ValueTest3.java (+1/-0)
src/test/java/com/persistit/unit/ValueTest4.java (+1/-0)
src/test/java/com/persistit/unit/ValueTest5.java (+1/-0)
To merge this branch: bzr merge lp:~pbeaman/akiban-persistit/better_4hour_tpcc_3
Reviewer Review Type Date Requested Status
Akiban Build User Needs Fixing
Nathan Williams Approve
Review via email: mp+121631@code.launchpad.net

Description of the change

This branch solves several problems relating to Journal I/O, pruning and performance.
Specifically, when running the 4-hour TPCC test on a particular server, perf02, the "terminal" threads outrun the ability of the JOURNAL_COPIER thread to remove obsolete journal files. The result is an ever-growing collection of journal files that eventually overflow the disk. The distinguishing feature of perf02 is that it has 12 fast cores (x2 with hyper-threading) but just a single disk drive.

This branch keeps the number of journal files under control during the test (never exceeding 16) and allows the test to complete. The test arrives at a stable configuration after a couple of hours and there's no reason to believe it would fail if run for much longer periods of time. However, a longer test run has not yet been completed.

Major changes:

1) The Transaction#commit() method now includes a call to new method JournalManager#throttle() which imposes a voluntary delay if the JournalCopier#urgency() value becomes large. The delay adjusts upward when urgency becomes extreme.

2) The order in which commit() completes its actions has changed to:
   flush()
   notifyComplete();
   throttle();
   waitForDurability();

Further, durability is measured from a timestamp taken immediately after the call to flush().
It is safe to call notifyComplete() and allow other concurrent transactions to continue (thereby hopefully allowing more transactions to join a GROUP commit). It is safe because no other transaction released by notifyComplete() can commit and become durable unless this one is also durable.

3) Pruning is accelerated, preventing old aborted transactions from holding up the JOURNAL_COPIER cleanup process. There are two main changes to support faster pruning:

3a) Scheduling: the CLEANUP_MANAGER normally polls once per second, but when the queue becomes more than half full it now runs continuously until the queue is no longer half full.

3b) Prune on write: when a dirty page thats needs pruning is being written to disk, a new optional code path prunes it before writing it. This reduces the likelihood that a page that is read back in from disk will need to be pruned.
Other changes made while analyzing test runs include updates in the IOMeter log function, and small fixes in the CLI.

One source a many lines of diff output is that to enable a new test the PersistitUnitTestCase class was moved from com.persistit.unit to com.persistit. In a future proposal I intend to move all of the unit tests to the correct package (same package as the class they are testing) and get rid of TestShim.

This branch is the same as the previously proposed better_4hour_tpcc_2 plus changes suggested by review comments. That branch and its merge proposal were deleted because of persistent problems with the diff containing phantom conflicts (which were probably induced by a complicate history of pre-requisite changes). All of the branches on which this code previously depended have been merged, so this new proposal is simply a clean new merge against trunk.

For the record the following review comments were written for the former proposal and corresponding changes are incorporated in this proposal:

--------------------

LP still showing conflicts, but trying it locally works just fine. Maybe a resubmit with no pre-req? Either way, line references below are on the current version (with "conflicts").

The description makes sense and the change are consistent with it, I think. Delicate change area, but everything running successfully with this is good to hear.

Minor stuff:

Diff line 162, 180, and 888 has TODO about debugging. Maybe belongs in if(Debug.ENABLED)?

Diff line 967, can we put the unit in the variable name instead of the comment? Slightly clearer to me, but it's OK if not for you.

Diff line 1065, there is a helper in JounalManager for computing journal count, getJournalFileCount(). It returns 1 greater than here. Can/should we use that here to be consistent?

Diff line 1086, can we add a new variable for the DELAY / 4?

Diff line 1801, re-throw is commented out. Should it be removed or was that temporary?
PersistitUnitTestCase was deleted/added instead of being 'bzr mv'ed. A plugin that I've been using recently is http://doc.bazaar.canonical.com/plugins/en/automv-plugin.html, which will

To post a comment you must log in.
Revision history for this message
Nathan Williams (nwilliams) wrote :

Thanks for the tweaks! Just a few more questions.

The MVV.verify() is now invoked inline to the call to Debug.$assert0.t(). assert0 is disabled by default so we expect it to get optimized away, but do we expect that to happy for verify() as well?

Diff line 420, the urgency call subtracts HALF_URGENT from journal file count. In the scenario where we go from 1-16 journal files, the urgency sequence would be: 1..5,0..10,10... right? Is that what we want?

It was like that in the last proposal, and I missed it, but the TransactionIndex polling was sped up by 5x. Is this required for passing on perf02? We are also adding throttling and pruning on write. Do we have any quantification for their individual contributions?

review: Needs Information
Revision history for this message
Peter Beaman (pbeaman) wrote :

Good questions.

To the best of my ability to tell from timing, Debug.$assert0.t(_anything_) gets optimized away with the Debug enabled flag is false. That is, unless _anything_ has a side-effect that could be used to detect that it has executed in which case of course the optimizer won't remove it. Therefore it's difficult to be certain.

Urgency calculation -- yes that looks wrong, will fix. I don't think the change will make much of a difference, but the intention is to provide a monotonically increasing function.

Yes, I increased the polling frequency to try to keep a tighter bound on the number of active transactions in the ATCache. The increase does not seem to have imposed any measurable increase in CPU consumption, and the benefit is that completed transactions can be recognized sooner as non-concurrent. I do not know if this one change is needed to help pass the test. What I have observed is that with the combination of changes, the CLEANUP_MANAGER now keeps up - with these changes I've never seen a refused CleanupManager.Action.

Revision history for this message
Nathan Williams (nwilliams) wrote :

Tweak looks good and other fixes responses make sense. So all good by me.

review: Approve
Revision history for this message
Akiban Build User (build-akiban) wrote :

There were 2 failures during build/test:

* job persistit-build failed at build number 413: http://172.16.20.104:8080/job/persistit-build/413/

* view must-pass failed: persistit-build is yellow

review: Needs Fixing
Revision history for this message
Nathan Williams (nwilliams) wrote :

Appears to be another instance of bug1019001 (intermittent failure). Going again.

Revision history for this message
Timothy Wegner (timmwegner) wrote :

Seems we should raise the priority of that bug? Or at the least
prioritize it :)

On Tue, Aug 28, 2012 at 5:31 PM, Nathan Williams <email address hidden>wrote:

> Appears to be another instance of bug1019001 (intermittent failure). Going
> again.
> --
>
> https://code.launchpad.net/~pbeaman/akiban-persistit/better_4hour_tpcc_3/+merge/121631
> Your team Akiban Technologies is subscribed to branch lp:akiban-persistit.
>

--
Akiban Technologies | Tim Wegner | VP of Engineering
skype: timmwegner | <email address hidden> | 508.735.6290

Revision history for this message
Peter Beaman (pbeaman) wrote :

Done. To High not Critical because so far we believe this is a test
problem no an underlying bug in the system. But we should look at it
soon to make sure that's correct.

On Tue, Aug 28, 2012 at 5:40 PM, Timothy Wegner <email address hidden> wrote:
> Seems we should raise the priority of that bug? Or at the least
> prioritize it :)
>
> On Tue, Aug 28, 2012 at 5:31 PM, Nathan Williams <email address hidden>wrote:
>
>> Appears to be another instance of bug1019001 (intermittent failure). Going
>> again.
>> --
>>
>> https://code.launchpad.net/~pbeaman/akiban-persistit/better_4hour_tpcc_3/+merge/121631
>> Your team Akiban Technologies is subscribed to branch lp:akiban-persistit.
>>
>
>
>
> --
> Akiban Technologies | Tim Wegner | VP of Engineering
> skype: timmwegner | <email address hidden> | 508.735.6290
>
> https://code.launchpad.net/~pbeaman/akiban-persistit/better_4hour_tpcc_3/+merge/121631
> Your team Akiban Technologies is subscribed to branch lp:akiban-persistit.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/main/java/com/persistit/Buffer.java'
2--- src/main/java/com/persistit/Buffer.java 2012-08-15 16:11:36 +0000
3+++ src/main/java/com/persistit/Buffer.java 2012-08-28 16:17:18 +0000
4@@ -264,6 +264,9 @@
5
6 private final static int BINARY_SEARCH_THRESHOLD = 6;
7
8+ private final static int PRUNE_MVV_HELPER_CHANGED = 1;
9+ private final static int PRUNE_MVV_HELPER_HAS_LONG = 2;
10+
11 abstract static class VerifyVisitor {
12
13 protected void visitPage(final long timestamp, final Volume volume, final long page, final int type,
14@@ -502,15 +505,23 @@
15 Debug.$assert0.t(isMine());
16 final long checkpointTimestamp = _persistit.getTimestampAllocator().getProposedCheckpointTimestamp();
17 if (isDirty() && !isTemporary() && getTimestamp() < checkpointTimestamp && timestamp > checkpointTimestamp) {
18- writePage();
19+ writePage(false);
20 _pool.bumpForcedCheckpointWrites();
21 }
22 }
23
24 void writePage() throws PersistitException {
25+ writePage(_persistit.getJournalManager().isWritePagePruningEnabled());
26+ }
27+
28+ private void writePage(final boolean prune) throws PersistitException {
29+ assert isMine();
30 _persistit.checkFatal();
31 final Volume volume = getVolume();
32 if (volume != null) {
33+ if (prune) {
34+ pruneMvvValues(null, false);
35+ }
36 clearSlack();
37 save();
38 _vol.getStorage().writePage(this);
39@@ -1501,9 +1512,13 @@
40 Debug.$assert0.t(p + KEYBLOCK_LENGTH < _keyBlockEnd ? pointer > 0 : true);
41 putInt(newTail + TAILBLOCK_POINTER, pointer);
42 } else {
43- final int storedLength = valueHelper.storeVersion(_bytes, newTail + _tailHeaderSize + klength, -1,
44- _bytes.length); // TODO limit
45- incCountIfMvv(_bytes, newTail + _tailHeaderSize + klength, storedLength & MVV.STORE_LENGTH_MASK);
46+ final int offset = newTail + _tailHeaderSize + klength;
47+ final int storedLength = valueHelper.storeVersion(_bytes, offset, -1, _bytes.length); // TODO
48+ // limit
49+ incCountIfMvv(_bytes, offset, storedLength & MVV.STORE_LENGTH_MASK);
50+
51+ Debug.$assert0.t(MVV.verify(_persistit.getTransactionIndex(), _bytes, offset, storedLength
52+ & MVV.STORE_LENGTH_MASK));
53 }
54 //
55 // Correct not to call getFastIndex()
56@@ -1629,9 +1644,14 @@
57 Debug.$assert0.t(p + KEYBLOCK_LENGTH < _keyBlockEnd ? pointer > 0 : pointer == -1);
58 putInt(newTail + TAILBLOCK_POINTER, (int) pointer);
59 } else {
60- final int storedLength = valueHelper.storeVersion(_bytes, newTail + _tailHeaderSize + klength, oldTailSize
61- - _tailHeaderSize - klength, _bytes.length); // TODO - limit
62- isMVV = isValueMVV(_bytes, newTail + _tailHeaderSize + klength, storedLength & MVV.STORE_LENGTH_MASK);
63+ final int offset = newTail + _tailHeaderSize + klength;
64+ final int storedLength = valueHelper.storeVersion(_bytes, offset, oldTailSize - _tailHeaderSize - klength,
65+ _bytes.length); // TODO - limit
66+ isMVV = isValueMVV(_bytes, offset, storedLength & MVV.STORE_LENGTH_MASK);
67+
68+ Debug.$assert0.t(MVV.verify(_persistit.getTransactionIndex(), _bytes, offset, storedLength
69+ & MVV.STORE_LENGTH_MASK));
70+
71 }
72 if (!wasMVV && isMVV) {
73 _mvvCount++;
74@@ -3466,7 +3486,12 @@
75 if (visitor != null) {
76 visitor.visitDataRecord(key, p, tail, klength, offset, length, getBytes());
77 }
78- Debug.$assert1.t(MVV.verify(_bytes, offset, length));
79+
80+ if (!MVV.verify(_bytes, offset, length)) {
81+ throw new InvalidPageStructureException("invalid MVV record at offset/length=" + offset + "/"
82+ + length);
83+ }
84+
85 }
86
87 if (_pool != null && getKeyCount() > _pool.getMaxKeys()) {
88@@ -3546,63 +3571,15 @@
89 final long timestamp = _persistit.getTimestampAllocator().updateTimestamp();
90 _mvvCount = 0;
91 writePageOnCheckpoint(timestamp);
92- final List<PrunedVersion> prunedVersions = new ArrayList<PrunedVersion>();
93- for (int p = KEY_BLOCK_START; p < _keyBlockEnd; p += KEYBLOCK_LENGTH) {
94- final int kbData = getInt(p);
95- final int tail = decodeKeyBlockTail(kbData);
96- final int tbData = getInt(tail);
97- final int klength = decodeTailBlockKLength(tbData);
98- final int oldTailSize = decodeTailBlockSize(tbData);
99- final int offset = tail + _tailHeaderSize + klength;
100- final int oldSize = oldTailSize - klength - _tailHeaderSize;
101-
102- if (oldSize > 0) {
103- int valueByte = _bytes[offset] & 0xFF;
104- if (isLongMVV(_bytes, offset, oldSize)) {
105- /*
106- * Can't prune in this pass because of long record
107- * timestamp management. Simply remember that there
108- * are long records to prune, then prune them in a
109- * copy of the buffer.
110- */
111- hasLongMvvRecords = true;
112- }
113- if (valueByte == MVV.TYPE_MVV) {
114- final int newSize = MVV.prune(_bytes, offset, oldSize, _persistit.getTransactionIndex(),
115- true, prunedVersions);
116- if (newSize != oldSize) {
117- changed = true;
118- final int newTailSize = klength + newSize + _tailHeaderSize;
119- final int oldNext = (tail + oldTailSize + ~TAILBLOCK_MASK) & TAILBLOCK_MASK;
120- final int newNext = (tail + newTailSize + ~TAILBLOCK_MASK) & TAILBLOCK_MASK;
121- if (newNext < oldNext) {
122- // Free the remainder of the old tail block
123- deallocTail(newNext, oldNext - newNext);
124- } else {
125- Debug.$assert0.t(newNext == oldNext);
126- }
127- // Rewrite the tail block header
128- putInt(tail, encodeTailBlock(newTailSize, klength));
129- if (Debug.ENABLED) {
130- MVV.verify(_bytes, offset, newSize);
131- }
132- }
133- valueByte = newSize > 0 ? _bytes[offset] & 0xFF : -1;
134- incCountIfMvv(_bytes, offset, newSize);
135- }
136-
137- if (pruneAntiValue(valueByte, p, tree)) {
138- changed = true;
139- p -= KEYBLOCK_LENGTH;
140- }
141- }
142- }
143+ final int flags = pruneMvvValuesHelper(tree);
144+ changed = (flags & PRUNE_MVV_HELPER_CHANGED) != 0;
145+ hasLongMvvRecords = (flags & PRUNE_MVV_HELPER_HAS_LONG) != 0;
146+
147 if (changed) {
148 setDirtyAtTimestamp(timestamp);
149 }
150
151- deallocatePrunedVersions(_persistit, _vol, prunedVersions);
152- prunedVersions.clear();
153+ final List<PrunedVersion> prunedVersions = new ArrayList<PrunedVersion>();
154
155 if (pruneLongMVVs && hasLongMvvRecords) {
156 final List<PersistitException> deferredExceptions = new ArrayList<PersistitException>();
157@@ -3645,6 +3622,63 @@
158 return changed;
159 }
160
161+ private int pruneMvvValuesHelper(final Tree tree) throws PersistitException {
162+ boolean changed = false;
163+ boolean hasLongMvvRecords = false;
164+ final List<PrunedVersion> prunedVersions = new ArrayList<PrunedVersion>();
165+
166+ for (int p = KEY_BLOCK_START; p < _keyBlockEnd; p += KEYBLOCK_LENGTH) {
167+ final int kbData = getInt(p);
168+ final int tail = decodeKeyBlockTail(kbData);
169+ final int tbData = getInt(tail);
170+ final int klength = decodeTailBlockKLength(tbData);
171+ final int oldTailSize = decodeTailBlockSize(tbData);
172+ final int offset = tail + _tailHeaderSize + klength;
173+ final int oldSize = oldTailSize - klength - _tailHeaderSize;
174+
175+ if (oldSize > 0) {
176+ int valueByte = _bytes[offset] & 0xFF;
177+ if (isLongMVV(_bytes, offset, oldSize)) {
178+ /*
179+ * Can't prune in this pass because of long record timestamp
180+ * management. Simply remember that there are long records
181+ * to prune, then prune them in a copy of the buffer.
182+ */
183+ hasLongMvvRecords = true;
184+ }
185+ if (valueByte == MVV.TYPE_MVV) {
186+ final int newSize = MVV.prune(_bytes, offset, oldSize, _persistit.getTransactionIndex(), true,
187+ prunedVersions);
188+ if (newSize != oldSize) {
189+ changed = true;
190+ final int newTailSize = klength + newSize + _tailHeaderSize;
191+ final int oldNext = (tail + oldTailSize + ~TAILBLOCK_MASK) & TAILBLOCK_MASK;
192+ final int newNext = (tail + newTailSize + ~TAILBLOCK_MASK) & TAILBLOCK_MASK;
193+ if (newNext < oldNext) {
194+ // Free the remainder of the old tail block
195+ deallocTail(newNext, oldNext - newNext);
196+ } else {
197+ Debug.$assert0.t(newNext == oldNext);
198+ }
199+ // Rewrite the tail block header
200+ putInt(tail, encodeTailBlock(newTailSize, klength));
201+ Debug.$assert0.t(MVV.verify(_bytes, offset, newSize));
202+ }
203+ valueByte = newSize > 0 ? _bytes[offset] & 0xFF : -1;
204+ incCountIfMvv(_bytes, offset, newSize);
205+ }
206+
207+ if (pruneAntiValue(valueByte, p, tree)) {
208+ changed = true;
209+ p -= KEYBLOCK_LENGTH;
210+ }
211+ }
212+ }
213+ deallocatePrunedVersions(_persistit, _vol, prunedVersions);
214+ prunedVersions.clear();
215+ return (changed ? PRUNE_MVV_HELPER_CHANGED : 0) | (hasLongMvvRecords ? PRUNE_MVV_HELPER_HAS_LONG : 0);
216+ }
217+
218 /**
219 * This method attempts to prune each LongRecord MVVs found in the page.
220 * This method is performed on a _copy_ of the original Buffer being pruned;
221@@ -3745,7 +3779,7 @@
222 final byte[] rawBytes = value.getEncodedBytes();
223 final int oldLongSize = value.getEncodedSize();
224 // TODO - perhaps remove. Done as a precaution for now.
225- MVV.verify(rawBytes, 0, oldLongSize);
226+ Debug.$assert0.t(MVV.verify(rawBytes, 0, oldLongSize));
227 final List<PrunedVersion> provisionalPrunedVersions = new ArrayList<PrunedVersion>();
228 final int newLongSize = MVV.prune(rawBytes, 0, oldLongSize, _persistit.getTransactionIndex(), true,
229 provisionalPrunedVersions);
230
231=== modified file 'src/main/java/com/persistit/CLI.java'
232--- src/main/java/com/persistit/CLI.java 2012-08-15 16:11:36 +0000
233+++ src/main/java/com/persistit/CLI.java 2012-08-28 16:17:18 +0000
234@@ -747,7 +747,7 @@
235 }
236 }
237 if (sysvol != null) {
238- properties.put(Persistit.SYSTEM_VOLUME_PROPERTY, sysvol.getName());
239+ persistit.getConfiguration().setSysVolume(sysvol.getName());
240 }
241
242 _persistit = persistit;
243
244=== modified file 'src/main/java/com/persistit/CleanupManager.java'
245--- src/main/java/com/persistit/CleanupManager.java 2012-08-15 16:11:36 +0000
246+++ src/main/java/com/persistit/CleanupManager.java 2012-08-28 16:17:18 +0000
247@@ -87,6 +87,7 @@
248 _accepted.incrementAndGet();
249 } else {
250 _refused.incrementAndGet();
251+ kick();
252 }
253 return accepted;
254 }
255@@ -127,6 +128,15 @@
256 }
257
258 @Override
259+ public long getPollInterval() {
260+ if (_cleanupActionQueue.size() < DEFAULT_QUEUE_SIZE / 2) {
261+ return super.getPollInterval();
262+ } else {
263+ return 0;
264+ }
265+ }
266+
267+ @Override
268 public void poll() throws Exception {
269 _persistit.getIOMeter().poll();
270 _persistit.cleanup();
271
272=== modified file 'src/main/java/com/persistit/Exchange.java'
273--- src/main/java/com/persistit/Exchange.java 2012-08-15 16:11:36 +0000
274+++ src/main/java/com/persistit/Exchange.java 2012-08-28 16:17:18 +0000
275@@ -1529,6 +1529,8 @@
276 storedLength &= MVV.STORE_LENGTH_MASK;
277 spareValue.setEncodedSize(storedLength);
278
279+ Debug.$assert0.t(MVV.verify(_persistit.getTransactionIndex(), spareBytes, 0, storedLength));
280+
281 if (spareValue.getEncodedSize() > maxSimpleValueSize) {
282 newLongRecordPointerMVV = getLongRecordHelper().storeLongRecord(spareValue,
283 _transaction.isActive());
284@@ -3698,6 +3700,8 @@
285 buffer.nextKey(_spareKey2, buffer.toKeyBlock(0));
286 _value.setPointerValue(page);
287 _value.setPointerPageType(buffer.getPageType());
288+ buffer.release();
289+ buffer = null;
290 storeInternal(_spareKey2, _value, level + 1, Exchange.StoreOptions.NONE);
291 return true;
292 } finally {
293
294=== modified file 'src/main/java/com/persistit/IOMeter.java'
295--- src/main/java/com/persistit/IOMeter.java 2012-08-15 16:11:36 +0000
296+++ src/main/java/com/persistit/IOMeter.java 2012-08-28 16:17:18 +0000
297@@ -61,15 +61,16 @@
298
299 private final static int READ_PAGE_FROM_VOLUME = 1;
300 private final static int READ_PAGE_FROM_JOURNAL = 2;
301- private final static int COPY_PAGE_TO_VOLUME = 3;
302- private final static int WRITE_PAGE_TO_JOURNAL = 4;
303- private final static int WRITE_TX_TO_JOURNAL = 5;
304- private final static int WRITE_OTHER_TO_JOURNAL = 6;
305- private final static int EVICT_PAGE_FROM_POOL = 7;
306- private final static int FLUSH_JOURNAL = 8;
307- private final static int GET_PAGE = 9;
308+ private final static int COPY_PAGE_FROM_JOURNAL = 3;
309+ private final static int COPY_PAGE_TO_VOLUME = 4;
310+ private final static int WRITE_PAGE_TO_JOURNAL = 5;
311+ private final static int WRITE_TX_TO_JOURNAL = 6;
312+ private final static int WRITE_OTHER_TO_JOURNAL = 7;
313+ private final static int EVICT_PAGE_FROM_POOL = 8;
314+ private final static int FLUSH_JOURNAL = 9;
315+ private final static int GET_PAGE = 10;
316
317- private final static int ITEM_COUNT = 10;
318+ private final static int ITEM_COUNT = 11;
319
320 private long _quiescentIOthreshold = DEFAULT_QUIESCENT_IO_THRESHOLD;
321
322@@ -266,7 +267,7 @@
323
324 if (analyzePages
325 && (op == WRITE_PAGE_TO_JOURNAL || op == READ_PAGE_FROM_JOURNAL || op == READ_PAGE_FROM_VOLUME
326- || op == COPY_PAGE_TO_VOLUME || op == EVICT_PAGE_FROM_POOL)) {
327+ || op == COPY_PAGE_FROM_JOURNAL || op == COPY_PAGE_TO_VOLUME || op == EVICT_PAGE_FROM_POOL)) {
328 final long handle = (volumeHandle << 48) + pageAddress;
329 List<Event> list = events.get(handle);
330 if (list == null) {
331@@ -291,6 +292,12 @@
332 }
333 }
334
335+ public void chargeCopyPageFromJournal(final Volume volume, final long pageAddress, final int size,
336+ final long journalAddress, final int urgency) {
337+ charge(size, COPY_PAGE_FROM_JOURNAL);
338+ log(COPY_PAGE_FROM_JOURNAL, volume, pageAddress, size, journalAddress, 0);
339+ }
340+
341 public void chargeCopyPageToVolume(final Volume volume, final long pageAddress, final int size,
342 final long journalAddress, final int urgency) {
343 charge(size, COPY_PAGE_TO_VOLUME);
344
345=== modified file 'src/main/java/com/persistit/JournalManager.java'
346--- src/main/java/com/persistit/JournalManager.java 2012-08-23 15:31:26 +0000
347+++ src/main/java/com/persistit/JournalManager.java 2012-08-28 16:17:18 +0000
348@@ -77,6 +77,8 @@
349 final static int URGENT = 10;
350 final static int ALMOST_URGENT = 8;
351 final static int HALF_URGENT = 5;
352+ final static int URGENT_COMMIT_DELAY_MILLIS = 50;
353+ final static int GENTLE_COMMIT_DELAY_MILLIS = 12;
354 private final static long NS_PER_MS = 1000000L;
355 private final static int IO_MEASUREMENT_CYCLES = 8;
356
357@@ -140,13 +142,13 @@
358 * requires more space than is available in the current journal file, it
359 * will advance to the start of the next journal file.
360 */
361- private long _currentAddress;
362+ private volatile long _currentAddress;
363
364 /**
365 * Smallest journal address at which a record still needed is located.
366 * Initially zero, increases as journal files are consumed and deleted.
367 */
368- private long _baseAddress;
369+ private volatile long _baseAddress;
370
371 private final Map<Long, FileChannel> _journalFileChannels = new HashMap<Long, FileChannel>();
372
373@@ -191,6 +193,8 @@
374
375 private final TransactionPlayerListener _listener = new ProactiveRollbackListener();
376
377+ private final AtomicBoolean _writePagePruning = new AtomicBoolean(true);
378+
379 private final AtomicBoolean _rollbackPruning = new AtomicBoolean(true);
380
381 /*
382@@ -202,8 +206,6 @@
383
384 private volatile int _copiesPerCycle = DEFAULT_COPIES_PER_CYCLE;
385
386- private volatile int _pageListSizeBase = DEFAULT_PAGE_MAP_SIZE_BASE;
387-
388 private volatile long _copierTimestampLimit = Long.MAX_VALUE;
389
390 private volatile long _earliestCommittedTimestamp = Long.MAX_VALUE;
391@@ -423,6 +425,11 @@
392 _rollbackPruning.set(rollbackPruning);
393 }
394
395+ @Override
396+ public void setWritePagePruningEnabled(final boolean writePruning) {
397+ _writePagePruning.set(writePruning);
398+ }
399+
400 public JournalManager(final Persistit persistit) {
401 _persistit = persistit;
402 }
403@@ -443,6 +450,11 @@
404 }
405
406 @Override
407+ public boolean isWritePagePruningEnabled() {
408+ return _writePagePruning.get();
409+ }
410+
411+ @Override
412 public String getJournalFilePath() {
413 return _journalFilePath;
414 }
415@@ -539,16 +551,31 @@
416 * @return the JOURNAL_COPIER urgency on a scale of 0 to 10
417 */
418 @Override
419- public synchronized int urgency() {
420+ public int urgency() {
421 if (_copyFast.get()) {
422 return URGENT;
423 }
424- int urgency = _pageList.size() / _pageListSizeBase;
425- final int journalFileCount = (int) (_currentAddress / _blockSize - _baseAddress / _blockSize);
426- if (!_appendOnly.get() && journalFileCount > 1) {
427- urgency += journalFileCount - 1;
428+ final int journalFileCount = getJournalFileCount();
429+ return Math.min(URGENT, journalFileCount);
430+ }
431+
432+ /**
433+ * Introduce delay into an application thread when JOURNAL_COPIER thread is
434+ * behind. The amount of delay depends on the value returned by
435+ * {@link #urgency()}. When that value is {@value #URGENT} then the delay is
436+ * {@value #URGENT_COMMIT_DELAY_MILLIS} milliseconds.
437+ *
438+ * @throws PersistitInterruptedException
439+ */
440+ public void throttle() throws PersistitInterruptedException {
441+ final int urgency = urgency();
442+ if (!_appendOnly.get()) {
443+ if (urgency == URGENT) {
444+ Util.sleep(URGENT_COMMIT_DELAY_MILLIS);
445+ } else if (urgency >= ALMOST_URGENT) {
446+ Util.sleep(GENTLE_COMMIT_DELAY_MILLIS);
447+ }
448 }
449- return Math.min(urgency, URGENT);
450 }
451
452 int handleForVolume(final Volume volume) throws PersistitException {
453@@ -981,6 +1008,14 @@
454 //
455 force();
456 //
457+ // Make sure all copied pages have been flushed to disk.
458+ //
459+ for (final Volume vol : _volumeToHandleMap.keySet()) {
460+ if (vol.isOpened()) {
461+ vol.getStorage().force();
462+ }
463+ }
464+ //
465 // Prepare room for CP.OVERHEAD bytes in the journal. If doing so
466 // started a new journal file then there's no need to write another
467 // CP record.
468@@ -1743,6 +1778,9 @@
469 * three commit modes: SOFT, HARD and GROUP. The two parameters represent
470 * time intervals in milliseconds.
471 *
472+ * @param flushedTimestamp
473+ * a timestamp taken after the transaction buffer belonging to
474+ * the current transaction has been flushed.
475 * @param leadTime
476 * time interval in milliseconds by which to anticipate I/O
477 * completion; the method will return as soon as the I/O
478@@ -1757,10 +1795,11 @@
479 * @throws PersistitInterruptedException
480 */
481
482- void waitForDurability(final long leadTime, final long stallTime) throws PersistitException {
483+ void waitForDurability(final long flushedTimestamp, final long leadTime, final long stallTime)
484+ throws PersistitException {
485 final JournalFlusher flusher = _flusher;
486 if (flusher != null) {
487- flusher.waitForDurability(leadTime, stallTime);
488+ flusher.waitForDurability(flushedTimestamp, leadTime, stallTime);
489 } else {
490 throw new IllegalStateException("JOURNAL_FLUSHER is not running");
491 }
492@@ -2161,7 +2200,7 @@
493 int divisor = 1;
494
495 if (iom.recentCharge() < iom.getQuiescentIOthreshold()) {
496- divisor = URGENT - HALF_URGENT;
497+ divisor = HALF_URGENT;
498 } else if (urgency > HALF_URGENT) {
499 divisor = urgency - HALF_URGENT;
500 }
501@@ -2199,16 +2238,16 @@
502
503 /**
504 * General method used to wait for durability. {@See
505- * JournalManager#waitForDurability(long, long)}.
506+ * JournalManager#waitForDurability(long, long, long)}.
507 *
508 * @throws PersistitInterruptedException
509 */
510- private void waitForDurability(final long leadTime, final long stallTime) throws PersistitException {
511+ private void waitForDurability(final long flushedTimestamp, final long leadTime, final long stallTime)
512+ throws PersistitException {
513 /*
514 * Commit is known durable once the JOURNAL_FLUSHER thread has
515- * posted a timestamp value to _endTimestamp larger than this.
516+ * posted an _endTimestamp larger than flushedTimestamp.
517 */
518- final long timestamp = _persistit.getTimestampAllocator().getCurrentTimestamp();
519 final long now = System.nanoTime();
520
521 while (true) {
522@@ -2231,7 +2270,7 @@
523 endTimestamp = _endTimestamp;
524 startTime = _startTime;
525 endTime = _endTime;
526- if (timestamp > startTimestamp && startTimestamp > endTimestamp) {
527+ if (flushedTimestamp > startTimestamp && startTimestamp > endTimestamp) {
528 estimatedRemainingIoNanos = Math.max(startTime + _expectedIoTime - now, 0);
529 }
530 if (startTimestamp == _startTimestamp && endTimestamp == _endTimestamp) {
531@@ -2240,7 +2279,7 @@
532 Util.spinSleep();
533 }
534
535- if (endTimestamp > timestamp && startTimestamp > timestamp) {
536+ if (endTimestamp > flushedTimestamp && startTimestamp > flushedTimestamp) {
537 /*
538 * Done - commit is fully durable
539 */
540@@ -2256,7 +2295,7 @@
541 }
542
543 long estimatedNanosToFinish = Math.max(estimatedRemainingIoNanos, 0);
544- if (startTimestamp < timestamp) {
545+ if (startTimestamp < flushedTimestamp) {
546 estimatedNanosToFinish += remainingSleepNanos + _expectedIoTime;
547 }
548
549@@ -2285,7 +2324,7 @@
550 if (_lock.readLock().tryLock(NS_PER_MS, TimeUnit.NANOSECONDS)) {
551 _lock.readLock().unlock();
552 }
553- } catch (InterruptedException e) {
554+ } catch (final InterruptedException e) {
555 throw new PersistitInterruptedException(e);
556 }
557 }
558@@ -2310,7 +2349,7 @@
559 _waitLoopsWithNoDelay.incrementAndGet();
560 }
561 }
562- if (_lastExceptionTimestamp > timestamp) {
563+ if (_lastExceptionTimestamp > flushedTimestamp) {
564 final Exception e = _lastException;
565 if (e instanceof PersistitException) {
566 throw (PersistitException) e;
567@@ -2451,6 +2490,8 @@
568 continue;
569 }
570 pageAddress = readPageBufferFromJournal(stablePageNode, bb);
571+ _persistit.getIOMeter().chargeCopyPageFromJournal(volumeRef, pageAddress, volume.getPageSize(),
572+ stablePageNode.getJournalAddress(), urgency());
573 } catch (final PersistitException ioe) {
574 _persistit
575 .getAlertMonitor()
576@@ -2478,8 +2519,6 @@
577 Volume volume = null;
578 int handle = -1;
579
580- final HashSet<Volume> volumes = new HashSet<Volume>();
581-
582 for (final Iterator<PageNode> iterator = list.iterator(); iterator.hasNext();) {
583 if (_closed.get() && !_copyFast.get() || _appendOnly.get()) {
584 list.clear();
585@@ -2535,15 +2574,11 @@
586 throw ioe;
587 }
588
589- volumes.add(volume);
590 _copiedPageCount++;
591 _persistit.getIOMeter().chargeCopyPageToVolume(volume, pageAddress, volume.getPageSize(),
592- pageNode.getJournalAddress(), _copyFast.get() ? URGENT : urgency());
593+ pageNode.getJournalAddress(), urgency());
594 }
595
596- for (final Volume vol : volumes) {
597- vol.getStorage().force();
598- }
599 }
600
601 private void cleanupForCopy(final List<PageNode> list) throws PersistitException {
602@@ -2590,6 +2625,7 @@
603 // Detect first journal address holding a mapped page
604 // required for recovery
605 //
606+
607 for (final PageNode pageNode : _pageMap.values()) {
608 //
609 // If there are multiple versions, we need to keep
610@@ -2607,9 +2643,9 @@
611 //
612 for (final Iterator<TransactionMapItem> iterator = _liveTransactionMap.values().iterator(); iterator
613 .hasNext();) {
614- final TransactionMapItem ts = iterator.next();
615- if (ts.getStartAddress() < recoveryBoundary) {
616- recoveryBoundary = ts.getStartAddress();
617+ final TransactionMapItem item = iterator.next();
618+ if (item.getStartAddress() < recoveryBoundary) {
619+ recoveryBoundary = item.getStartAddress();
620 }
621 }
622
623@@ -2772,7 +2808,6 @@
624
625 @Override
626 public void store(final long address, final long timestamp, final Exchange exchange) throws PersistitException {
627- final TransactionStatus ts = _persistit.getTransactionIndex().getStatus(timestamp);
628 exchange.prune();
629 }
630
631@@ -2840,6 +2875,7 @@
632 /**
633 * Extend ArrayList to export the removeRange method.
634 */
635+ @SuppressWarnings("serial")
636 static class RangeRemovingArrayList<T> extends ArrayList<T> {
637 @Override
638 public void removeRange(final int fromIndex, final int toIndex) {
639
640=== added file 'src/main/java/com/persistit/JournalManagerBench.java'
641--- src/main/java/com/persistit/JournalManagerBench.java 1970-01-01 00:00:00 +0000
642+++ src/main/java/com/persistit/JournalManagerBench.java 2012-08-28 16:17:18 +0000
643@@ -0,0 +1,186 @@
644+/**
645+ * Copyright © 2012 Akiban Technologies, Inc. All rights reserved.
646+ *
647+ * This program and the accompanying materials are made available
648+ * under the terms of the Eclipse Public License v1.0 which
649+ * accompanies this distribution, and is available at
650+ * http://www.eclipse.org/legal/epl-v10.html
651+ *
652+ * This program may also be available under different license terms.
653+ * For more information, see www.akiban.com or contact licensing@akiban.com.
654+ *
655+ * Contributors:
656+ * Akiban Technologies, Inc.
657+ */
658+
659+package com.persistit;
660+
661+import java.io.File;
662+import java.io.RandomAccessFile;
663+import java.nio.ByteBuffer;
664+import java.nio.channels.FileChannel;
665+
666+import com.persistit.util.ArgParser;
667+
668+/**
669+ * Benchmark for primitive I/O simulating HARD (durable) commit. This code is
670+ * intended to explore two elements:
671+ *
672+ * (1) Pre-extending the journal file (so that FileChannel.force(false) usually
673+ * does not need to write any metadata.
674+ *
675+ * (2) Performing I/O in fixed-length blocks so that to write a some bytes the
676+ * file system does not first need to read existing data from disk.
677+ *
678+ * Parameters
679+ *
680+ * align - smallest unit of I/O (default = 1) datapath - directory in which fake
681+ * journal file will be written (default = /tmp/persistit_test_data) buffersize
682+ * - emulated journal buffer size (default = 64M)
683+ *
684+ *
685+ * @author peter
686+ *
687+ */
688+public class JournalManagerBench {
689+
690+ private final long NS_PER_S = 1000000000L;
691+ private final byte[] NULLS = new byte[65536];
692+
693+ private final String[] ARG_TEMPLATE = new String[] { "duration|int:10:10:86400|Duration of test in seconds",
694+ "policy|String:HARD|Commit policy: SOFT, HARD or GROUP",
695+ "datapath|String:/tmp/persistit_test_data|Datapath property",
696+ "buffersize|int:64:1:1024|Emulated journal buffer size in MBytes",
697+ "extension|int:0:0:1024|MBytes by which to extend file when full",
698+ "prealloc|int:0:0:1024|Preallocated file size in MBytes",
699+ "align|int:1:1:65536|Blocking factor for I/O size",
700+ "recsize|int:123:64:65536|Emulated transaction record size" };
701+
702+ final ByteBuffer buffer;
703+ final ArgParser ap;
704+
705+ private File file;
706+ private FileChannel fc;
707+
708+ private long writeAddress = 0;
709+ private long currentAddress = 0;
710+
711+ long count = 0;
712+ long minTime = Long.MAX_VALUE;
713+ long maxTime = Long.MIN_VALUE;
714+
715+ final byte[] bytes = new byte[65536];
716+
717+ public static void main(final String[] args) throws Exception {
718+ final JournalManagerBench jmb = new JournalManagerBench(args);
719+ jmb.runTest();
720+ }
721+
722+ private JournalManagerBench(final String[] args) throws Exception {
723+ ap = new ArgParser("JournalManagerBench", args, ARG_TEMPLATE).strict();
724+ buffer = ByteBuffer.allocate(ap.getIntValue("buffersize") * 1024 * 1024);
725+ }
726+
727+ @SuppressWarnings("resource")
728+ private void runTest() throws Exception {
729+ file = new File(ap.getStringValue("datapath"), "JManBench_TestFile");
730+ fc = new RandomAccessFile(file, "rw").getChannel();
731+ preallocateFile(ap.getIntValue("prealloc") * 1024 * 1024);
732+ for (int i = 0; i < bytes.length; i++) {
733+ bytes[i] = (byte) ('-');
734+ }
735+ final int align = ap.getIntValue("align");
736+ final long extension = ap.getIntValue("extension") * 1024 * 1024;
737+
738+ final long start = System.nanoTime();
739+ final long expires = start + ap.getIntValue("duration") * NS_PER_S;
740+ long now = System.nanoTime();
741+
742+ while (now < expires) {
743+ doOneCycle(now - start, align, extension, 100);
744+ final long then = System.nanoTime();
745+ count++;
746+ minTime = Math.min(minTime, then - now);
747+ maxTime = Math.max(maxTime, then - now);
748+ now = then;
749+ }
750+ final long elapsed = now - start;
751+ System.out.printf("%,d commits took %,dms at a rate of %,d/second minimum time=%,dns maximumTime=%,dns\n",
752+ count, elapsed, (count * NS_PER_S) / elapsed, minTime, maxTime);
753+
754+ }
755+
756+ private void preallocateFile(final long size) throws Exception {
757+ if (size > 0 && fc.size() > size) {
758+ System.out.printf("Truncating file %s from %,d to %,d\n", file, fc.size(), size);
759+ fc.truncate(size);
760+ } else if (fc.size() < size) {
761+ System.out.printf("Preallocating file %s to size %,d ", file, size);
762+ while (true) {
763+ long remaining = size - fc.size();
764+ if (remaining <= 0) {
765+ break;
766+ }
767+ if (remaining > buffer.capacity()) {
768+ remaining = buffer.capacity();
769+ long unaligned = fc.size() % 16384;
770+ if (unaligned > 0) {
771+ remaining = remaining - (16384 - unaligned);
772+ }
773+ }
774+ buffer.position(0).limit((int) remaining);
775+ fc.write(buffer, fc.size());
776+ System.out.print(".");
777+ }
778+ fc.force(true);
779+ System.out.println("done");
780+ }
781+ }
782+
783+ private void doOneCycle(final long time, final int align, final long extension, final int size) throws Exception {
784+ // Make a fake transaction record
785+ String header = String.format("\nsize=%06d count=%06d time=%012d\n", size, count, time);
786+ byte[] b = header.getBytes();
787+ System.arraycopy(b, 0, bytes, 0, b.length);
788+
789+ // Add the record, possibly offset to maintaining alignment
790+ int toRewrite = (int) (currentAddress - writeAddress);
791+ buffer.position(toRewrite);
792+ buffer.put(bytes, 0, size);
793+ boolean extended = false;
794+
795+ int position = buffer.position();
796+
797+ // If extension is needed, add those bytes
798+ long currentSize;
799+ if (extension > 0 && writeAddress + buffer.position() > (currentSize = fc.size())) {
800+ long newSize = currentSize + extension;
801+ if (newSize - writeAddress > buffer.capacity()) {
802+ newSize = writeAddress + buffer.capacity();
803+ assert newSize > currentSize;
804+ }
805+ int add = (int) (newSize - writeAddress - buffer.position());
806+ while (add > 0) {
807+ buffer.put(NULLS, 0, Math.min(NULLS.length, add));
808+ add -= NULLS.length;
809+ }
810+ extended = true;
811+ }
812+
813+ // Write and force the buffer
814+
815+ buffer.flip();
816+ fc.write(buffer, writeAddress);
817+ fc.force(extended);
818+
819+ // Align the bytes to the beginning of the buffer as needed
820+
821+ currentAddress = writeAddress + position;
822+ buffer.limit(position);
823+ position = (position / align) * align;
824+ buffer.position(position);
825+ buffer.compact();
826+ writeAddress += position;
827+ }
828+
829+}
830
831=== modified file 'src/main/java/com/persistit/JournalTool.java'
832--- src/main/java/com/persistit/JournalTool.java 2012-08-15 16:11:36 +0000
833+++ src/main/java/com/persistit/JournalTool.java 2012-08-28 16:17:18 +0000
834@@ -688,7 +688,10 @@
835 }
836
837 protected void flush() {
838- write(sb.toString());
839+ if (sb.length() > 0) {
840+ write(sb.toString());
841+ sb.setLength(0);
842+ }
843 }
844
845 protected void write(final String msg) {
846@@ -908,7 +911,6 @@
847 long address = from + PM.OVERHEAD;
848 int index = 0;
849 int loaded = 0;
850- sb.setLength(0);
851 long lastPage = Long.MAX_VALUE;
852 int lastVolumeHandle = Integer.MAX_VALUE;
853 for (int remaining = count; remaining > 0; remaining--) {
854@@ -930,10 +932,7 @@
855 final long journalAddress = PM.getEntryJournalAddress(_readBuffer, index);
856 if (_selectedPages.isSelected(pageAddress) && _selectedTimestamps.isSelected(pageTimestamp)) {
857 if (pageAddress != lastPage || volumeHandle != lastVolumeHandle) {
858- if (sb.length() > 0) {
859- flush();
860- sb.setLength(0);
861- }
862+ flush();
863 lastPage = pageAddress;
864 lastVolumeHandle = volumeHandle;
865 appendf("-- %5d:%,12d: ", volumeHandle, pageAddress);
866@@ -953,7 +952,6 @@
867 long address = from + TM.OVERHEAD;
868 int index = 0;
869 int loaded = 0;
870- sb.setLength(0);
871 for (int remaining = count; remaining > 0; remaining--) {
872 if (index == loaded) {
873 read(address, Math.min(_readBuffer.capacity(), remaining * TM.ENTRY_SIZE));
874@@ -972,7 +970,6 @@
875 appendf("-- start %,12d commit %,12d @%,18d %s", startTimestamp, commitTimestamp, journalAddress,
876 isCommitted ? "committed" : "uncommitted");
877 flush();
878- sb.setLength(0);
879 index++;
880 }
881 }
882
883=== modified file 'src/main/java/com/persistit/MVV.java'
884--- src/main/java/com/persistit/MVV.java 2012-08-15 16:11:36 +0000
885+++ src/main/java/com/persistit/MVV.java 2012-08-28 16:17:18 +0000
886@@ -19,6 +19,7 @@
887 import static com.persistit.Buffer.LONGREC_SIZE;
888 import static com.persistit.Buffer.LONGREC_TYPE;
889 import static com.persistit.TransactionIndex.vh2ts;
890+import static com.persistit.TransactionStatus.ABORTED;
891 import static com.persistit.TransactionStatus.UNCOMMITTED;
892
893 import java.util.List;
894@@ -307,7 +308,7 @@
895 * simply replaced.
896 */
897 else {
898- Debug.$assert0.t(verify(target, targetOffset, targetLength));
899+ assert verify(target, targetOffset, targetLength);
900 /*
901 * Search for the matching version.
902 */
903@@ -600,6 +601,37 @@
904 return true;
905 }
906
907+ static boolean verify(final TransactionIndex ti, final byte[] bytes, final int offset, final int length) {
908+ if (!isArrayMVV(bytes, offset, length)) {
909+ /*
910+ * Not an MVV
911+ */
912+ return true;
913+ }
914+ int from = offset + 1;
915+ final long lastVersion = -1;
916+ while (from < offset + length) {
917+ final int vlength = getLength(bytes, from);
918+ final long version = getVersion(bytes, from);
919+ if (vlength < 0 || from + vlength + LENGTH_PER_VERSION > offset + length) {
920+ return false;
921+ }
922+ if (version < lastVersion) {
923+ try {
924+ final long lastVersionTc = ti.commitStatus(lastVersion, UNCOMMITTED, 0);
925+ assert lastVersionTc == ABORTED;
926+ } catch (final InterruptedException e) {
927+ // ignore
928+ } catch (final TimeoutException e) {
929+ // ignore
930+ }
931+ }
932+ assert version != lastVersion;
933+ from += vlength + LENGTH_PER_VERSION;
934+ }
935+ return true;
936+ }
937+
938 /**
939 * Search for a known version within a MVV array. If the version is found
940 * within the array, copy the contents out to the target and return the
941
942=== modified file 'src/main/java/com/persistit/Transaction.java'
943--- src/main/java/com/persistit/Transaction.java 2012-08-23 15:24:42 +0000
944+++ src/main/java/com/persistit/Transaction.java 2012-08-28 16:17:18 +0000
945@@ -854,21 +854,27 @@
946 sequence(COMMIT_FLUSH_A);
947 _commitTimestamp = _persistit.getTimestampAllocator().updateTimestamp();
948 sequence(COMMIT_FLUSH_C);
949+ long flushedTimetimestamp = 0;
950 boolean committed = false;
951 try {
952+
953 if (flushTransactionBuffer(false)) {
954- _persistit.getJournalManager().waitForDurability(
955- policy == CommitPolicy.SOFT ? _persistit.getTransactionCommitLeadTime() : 0,
956- policy == CommitPolicy.GROUP ? _persistit.getTransactionCommitStallTime() : 0);
957+ flushedTimetimestamp = _persistit.getTimestampAllocator().getCurrentTimestamp();
958 }
959 committed = true;
960 } finally {
961-
962 _persistit.getTransactionIndex().notifyCompleted(_transactionStatus,
963 committed ? _commitTimestamp : TransactionStatus.ABORTED);
964 _commitCompleted = committed;
965 _rollbackPending = _rollbackCompleted = !committed;
966 }
967+
968+ _persistit.getJournalManager().throttle();
969+ if (flushedTimetimestamp != 0) {
970+ _persistit.getJournalManager().waitForDurability(flushedTimetimestamp,
971+ policy == CommitPolicy.SOFT ? _persistit.getTransactionCommitLeadTime() : 0,
972+ policy == CommitPolicy.GROUP ? _persistit.getTransactionCommitStallTime() : 0);
973+ }
974 }
975 }
976
977
978=== modified file 'src/main/java/com/persistit/TransactionIndex.java'
979--- src/main/java/com/persistit/TransactionIndex.java 2012-08-15 16:11:36 +0000
980+++ src/main/java/com/persistit/TransactionIndex.java 2012-08-28 16:17:18 +0000
981@@ -50,7 +50,7 @@
982 /**
983 * Interval in milliseconds for updating the active transaction cache
984 */
985- final static long POLLING_TASK_INTERVAL = 50;
986+ final static long POLLING_TASK_INTERVAL = 10;
987
988 /**
989 * Default threshold value for moving long-running transactions to the
990
991=== modified file 'src/main/java/com/persistit/mxbeans/IOMeterMXBean.java'
992--- src/main/java/com/persistit/mxbeans/IOMeterMXBean.java 2012-08-15 16:11:36 +0000
993+++ src/main/java/com/persistit/mxbeans/IOMeterMXBean.java 2012-08-28 16:17:18 +0000
994@@ -59,12 +59,12 @@
995 *
996 */
997 public final static String[] OPERATION_NAMES = { "Unknown", "Read page from Volume", "Read page from Journal",
998- "Copy page from journal to volume", "Write page from Journal", "Write Transaction to Journal", "Other",
999- "Evict page from pool", "Flush journal", "Get page" };
1000-
1001- public final static String[] OPERATIONS = { "??", "RV", "RJ", "CC", "WJ", "TJ", "XX", "EV", "FJ", "GP" };
1002-
1003- public final static String[] SUMMARY_ITEMS = { "CC", "RV", "RJ", "WJ", "EV", "FJ" };
1004+ "Copy page from journal", "Copy page to volume", "Write page from Journal", "Write Transaction to Journal",
1005+ "Other", "Evict page from pool", "Flush journal", "Get page" };
1006+
1007+ public final static String[] OPERATIONS = { "??", "RV", "RJ", "CJ", "CV", "WJ", "TJ", "XX", "EV", "FJ", "GP" };
1008+
1009+ public final static String[] SUMMARY_ITEMS = { "CJ", "CV", "RV", "RJ", "WJ", "EV", "FJ" };
1010
1011 /**
1012 * @return the quiescentIOthreshold
1013
1014=== modified file 'src/main/java/com/persistit/mxbeans/JournalManagerMXBean.java'
1015--- src/main/java/com/persistit/mxbeans/JournalManagerMXBean.java 2012-08-15 16:11:36 +0000
1016+++ src/main/java/com/persistit/mxbeans/JournalManagerMXBean.java 2012-08-28 16:17:18 +0000
1017@@ -207,6 +207,12 @@
1018 @Description("True to enable pruning of rolled-back transactions")
1019 boolean isRollbackPruningEnabled();
1020
1021+ @Description("True to enable pruning when writing pages to journal")
1022+ void setWritePagePruningEnabled(boolean rollbackPruning);
1023+
1024+ @Description("True to enable pruning when writing pages to journal")
1025+ boolean isWritePagePruningEnabled();
1026+
1027 @Description("Degree of urgency for copying pages: 0-10")
1028 int urgency();
1029
1030
1031=== modified file 'src/test/java/com/persistit/AccumulatorMemoryTest.java'
1032--- src/test/java/com/persistit/AccumulatorMemoryTest.java 2012-08-15 16:11:36 +0000
1033+++ src/test/java/com/persistit/AccumulatorMemoryTest.java 2012-08-28 16:17:18 +0000
1034@@ -21,8 +21,6 @@
1035
1036 import org.junit.Test;
1037
1038-import com.persistit.unit.PersistitUnitTestCase;
1039-
1040 public class AccumulatorMemoryTest extends PersistitUnitTestCase {
1041
1042 @Test
1043
1044=== modified file 'src/test/java/com/persistit/AccumulatorRecoveryTest.java'
1045--- src/test/java/com/persistit/AccumulatorRecoveryTest.java 2012-08-15 16:11:36 +0000
1046+++ src/test/java/com/persistit/AccumulatorRecoveryTest.java 2012-08-28 16:17:18 +0000
1047@@ -31,7 +31,6 @@
1048 import com.persistit.TransactionPlayer.TransactionPlayerListener;
1049 import com.persistit.exception.PersistitException;
1050 import com.persistit.exception.RollbackException;
1051-import com.persistit.unit.PersistitUnitTestCase;
1052 import com.persistit.unit.UnitTestProperties;
1053
1054 public class AccumulatorRecoveryTest extends PersistitUnitTestCase {
1055
1056=== modified file 'src/test/java/com/persistit/AccumulatorTest.java'
1057--- src/test/java/com/persistit/AccumulatorTest.java 2012-08-15 16:11:36 +0000
1058+++ src/test/java/com/persistit/AccumulatorTest.java 2012-08-28 16:17:18 +0000
1059@@ -33,7 +33,6 @@
1060 import com.persistit.exception.PersistitException;
1061 import com.persistit.exception.TimeoutException;
1062 import com.persistit.unit.ConcurrentUtil;
1063-import com.persistit.unit.PersistitUnitTestCase;
1064 import com.persistit.unit.UnitTestProperties;
1065
1066 public class AccumulatorTest extends PersistitUnitTestCase {
1067
1068=== modified file 'src/test/java/com/persistit/AlertMonitorTest.java'
1069--- src/test/java/com/persistit/AlertMonitorTest.java 2012-08-15 16:11:36 +0000
1070+++ src/test/java/com/persistit/AlertMonitorTest.java 2012-08-28 16:17:18 +0000
1071@@ -31,7 +31,6 @@
1072 import com.persistit.logging.PersistitLevel;
1073 import com.persistit.logging.PersistitLogMessage.LogItem;
1074 import com.persistit.logging.PersistitLogger;
1075-import com.persistit.unit.PersistitUnitTestCase;
1076
1077 public class AlertMonitorTest extends PersistitUnitTestCase {
1078
1079
1080=== modified file 'src/test/java/com/persistit/BackupTaskTest.java'
1081--- src/test/java/com/persistit/BackupTaskTest.java 2012-08-15 16:11:36 +0000
1082+++ src/test/java/com/persistit/BackupTaskTest.java 2012-08-28 16:17:18 +0000
1083@@ -29,7 +29,6 @@
1084
1085 import org.junit.Test;
1086
1087-import com.persistit.unit.PersistitUnitTestCase;
1088 import com.persistit.unit.UnitTestProperties;
1089
1090 public class BackupTaskTest extends PersistitUnitTestCase {
1091
1092=== modified file 'src/test/java/com/persistit/BufferMaxPack.java'
1093--- src/test/java/com/persistit/BufferMaxPack.java 2012-08-15 16:11:36 +0000
1094+++ src/test/java/com/persistit/BufferMaxPack.java 2012-08-28 16:17:18 +0000
1095@@ -20,7 +20,6 @@
1096 import org.junit.Test;
1097
1098 import com.persistit.ValueHelper.RawValueWriter;
1099-import com.persistit.unit.PersistitUnitTestCase;
1100
1101 public class BufferMaxPack extends PersistitUnitTestCase {
1102
1103
1104=== modified file 'src/test/java/com/persistit/BufferPoolTest.java'
1105--- src/test/java/com/persistit/BufferPoolTest.java 2012-08-15 16:11:36 +0000
1106+++ src/test/java/com/persistit/BufferPoolTest.java 2012-08-28 16:17:18 +0000
1107@@ -26,7 +26,6 @@
1108 import org.junit.Test;
1109
1110 import com.persistit.BufferPool.BufferHolder;
1111-import com.persistit.unit.PersistitUnitTestCase;
1112
1113 public class BufferPoolTest extends PersistitUnitTestCase {
1114
1115
1116=== modified file 'src/test/java/com/persistit/BufferTest.java'
1117--- src/test/java/com/persistit/BufferTest.java 2012-08-15 16:11:36 +0000
1118+++ src/test/java/com/persistit/BufferTest.java 2012-08-28 16:17:18 +0000
1119@@ -27,7 +27,6 @@
1120 import com.persistit.exception.RebalanceException;
1121 import com.persistit.policy.JoinPolicy;
1122 import com.persistit.policy.SplitPolicy;
1123-import com.persistit.unit.PersistitUnitTestCase;
1124
1125 public class BufferTest extends PersistitUnitTestCase {
1126 int leftn;
1127
1128=== modified file 'src/test/java/com/persistit/BufferTest2.java'
1129--- src/test/java/com/persistit/BufferTest2.java 2012-08-15 16:11:36 +0000
1130+++ src/test/java/com/persistit/BufferTest2.java 2012-08-28 16:17:18 +0000
1131@@ -33,7 +33,6 @@
1132 import com.persistit.exception.RebalanceException;
1133 import com.persistit.policy.JoinPolicy;
1134 import com.persistit.policy.SplitPolicy;
1135-import com.persistit.unit.PersistitUnitTestCase;
1136
1137 public class BufferTest2 extends PersistitUnitTestCase {
1138
1139
1140=== modified file 'src/test/java/com/persistit/Bug1003578Test.java'
1141--- src/test/java/com/persistit/Bug1003578Test.java 2012-08-15 16:11:36 +0000
1142+++ src/test/java/com/persistit/Bug1003578Test.java 2012-08-28 16:17:18 +0000
1143@@ -27,7 +27,6 @@
1144 import org.junit.Test;
1145
1146 import com.persistit.exception.PersistitException;
1147-import com.persistit.unit.PersistitUnitTestCase;
1148
1149 /**
1150 * https://bugs.launchpad.net/akiban-persistit/+bug/1003578
1151
1152=== modified file 'src/test/java/com/persistit/Bug1017957Test.java'
1153--- src/test/java/com/persistit/Bug1017957Test.java 2012-08-15 16:11:36 +0000
1154+++ src/test/java/com/persistit/Bug1017957Test.java 2012-08-28 16:17:18 +0000
1155@@ -23,7 +23,6 @@
1156
1157 import org.junit.Test;
1158
1159-import com.persistit.unit.PersistitUnitTestCase;
1160 import com.persistit.unit.UnitTestProperties;
1161
1162 /**
1163
1164=== modified file 'src/test/java/com/persistit/Bug1018526Test.java'
1165--- src/test/java/com/persistit/Bug1018526Test.java 2012-08-15 16:11:36 +0000
1166+++ src/test/java/com/persistit/Bug1018526Test.java 2012-08-28 16:17:18 +0000
1167@@ -27,7 +27,6 @@
1168 import org.junit.Test;
1169
1170 import com.persistit.JournalManager.TreeDescriptor;
1171-import com.persistit.unit.PersistitUnitTestCase;
1172
1173 public class Bug1018526Test extends PersistitUnitTestCase {
1174
1175
1176=== modified file 'src/test/java/com/persistit/Bug706132Test.java'
1177--- src/test/java/com/persistit/Bug706132Test.java 2012-08-15 16:11:36 +0000
1178+++ src/test/java/com/persistit/Bug706132Test.java 2012-08-28 16:17:18 +0000
1179@@ -22,7 +22,6 @@
1180 import org.junit.Test;
1181
1182 import com.persistit.policy.SplitPolicy;
1183-import com.persistit.unit.PersistitUnitTestCase;
1184
1185 /*
1186 * Stress10 with 1K pages exhibited a failure in which a value was simply not
1187
1188=== modified file 'src/test/java/com/persistit/Bug708592Test.java'
1189--- src/test/java/com/persistit/Bug708592Test.java 2012-08-15 16:11:36 +0000
1190+++ src/test/java/com/persistit/Bug708592Test.java 2012-08-28 16:17:18 +0000
1191@@ -21,7 +21,6 @@
1192 import org.junit.Test;
1193
1194 import com.persistit.policy.SplitPolicy;
1195-import com.persistit.unit.PersistitUnitTestCase;
1196
1197 /*
1198 * Got this while loading sample data. Apparently the new PACK split policy
1199
1200=== modified file 'src/test/java/com/persistit/Bug739533Test.java'
1201--- src/test/java/com/persistit/Bug739533Test.java 2012-08-15 16:11:36 +0000
1202+++ src/test/java/com/persistit/Bug739533Test.java 2012-08-28 16:17:18 +0000
1203@@ -17,8 +17,6 @@
1204
1205 import org.junit.Test;
1206
1207-import com.persistit.unit.PersistitUnitTestCase;
1208-
1209 public class Bug739533Test extends PersistitUnitTestCase {
1210
1211 private final String _volumeName = "persistit";
1212
1213=== modified file 'src/test/java/com/persistit/Bug777918Test.java'
1214--- src/test/java/com/persistit/Bug777918Test.java 2012-08-15 16:11:36 +0000
1215+++ src/test/java/com/persistit/Bug777918Test.java 2012-08-28 16:17:18 +0000
1216@@ -25,7 +25,6 @@
1217 import com.persistit.exception.MissingThreadException;
1218 import com.persistit.exception.PersistitException;
1219 import com.persistit.exception.TestException;
1220-import com.persistit.unit.PersistitUnitTestCase;
1221 import com.persistit.unit.UnitTestProperties;
1222 import com.persistit.util.Util;
1223
1224
1225=== modified file 'src/test/java/com/persistit/Bug790709Test.java'
1226--- src/test/java/com/persistit/Bug790709Test.java 2012-08-15 16:11:36 +0000
1227+++ src/test/java/com/persistit/Bug790709Test.java 2012-08-28 16:17:18 +0000
1228@@ -20,8 +20,6 @@
1229
1230 import org.junit.Test;
1231
1232-import com.persistit.unit.PersistitUnitTestCase;
1233-
1234 /**
1235 * Bug 790709 This happened on-site at XXX with the halo release. The server
1236 * process was running with assertions enabled. The DELETE statement that failed
1237
1238=== modified file 'src/test/java/com/persistit/Bug870352Test.java'
1239--- src/test/java/com/persistit/Bug870352Test.java 2012-08-15 16:11:36 +0000
1240+++ src/test/java/com/persistit/Bug870352Test.java 2012-08-28 16:17:18 +0000
1241@@ -19,8 +19,6 @@
1242
1243 import org.junit.Test;
1244
1245-import com.persistit.unit.PersistitUnitTestCase;
1246-
1247 public class Bug870352Test extends PersistitUnitTestCase {
1248
1249 @Test
1250
1251=== modified file 'src/test/java/com/persistit/Bug877656Test.java'
1252--- src/test/java/com/persistit/Bug877656Test.java 2012-08-15 16:11:36 +0000
1253+++ src/test/java/com/persistit/Bug877656Test.java 2012-08-28 16:17:18 +0000
1254@@ -19,8 +19,6 @@
1255
1256 import org.junit.Test;
1257
1258-import com.persistit.unit.PersistitUnitTestCase;
1259-
1260 public class Bug877656Test extends PersistitUnitTestCase {
1261
1262 @Test
1263
1264=== modified file 'src/test/java/com/persistit/Bug882219Test.java'
1265--- src/test/java/com/persistit/Bug882219Test.java 2012-08-15 16:11:36 +0000
1266+++ src/test/java/com/persistit/Bug882219Test.java 2012-08-28 16:17:18 +0000
1267@@ -26,7 +26,6 @@
1268 import com.persistit.Transaction.CommitPolicy;
1269 import com.persistit.exception.PersistitIOException;
1270 import com.persistit.exception.PersistitInterruptedException;
1271-import com.persistit.unit.PersistitUnitTestCase;
1272
1273 /**
1274 * Interrupting a thread while it is performing a read or write closes the
1275
1276=== modified file 'src/test/java/com/persistit/Bug885477Test.java'
1277--- src/test/java/com/persistit/Bug885477Test.java 2012-08-15 16:11:36 +0000
1278+++ src/test/java/com/persistit/Bug885477Test.java 2012-08-28 16:17:18 +0000
1279@@ -21,8 +21,6 @@
1280
1281 import org.junit.Test;
1282
1283-import com.persistit.unit.PersistitUnitTestCase;
1284-
1285 /**
1286 * Suppose a persistit tree has keys (1, 10), (1, 20), (2, 30). If an exchange's
1287 * key is (1), then traverse(GTEQ, false) should traverse to the first record,
1288
1289=== modified file 'src/test/java/com/persistit/Bug889850Test.java'
1290--- src/test/java/com/persistit/Bug889850Test.java 2012-08-15 16:11:36 +0000
1291+++ src/test/java/com/persistit/Bug889850Test.java 2012-08-28 16:17:18 +0000
1292@@ -17,8 +17,6 @@
1293
1294 import org.junit.Test;
1295
1296-import com.persistit.unit.PersistitUnitTestCase;
1297-
1298 /**
1299 *
1300 * From akiban-server 0.81:
1301
1302=== modified file 'src/test/java/com/persistit/Bug911849Test.java'
1303--- src/test/java/com/persistit/Bug911849Test.java 2012-08-15 16:11:36 +0000
1304+++ src/test/java/com/persistit/Bug911849Test.java 2012-08-28 16:17:18 +0000
1305@@ -25,7 +25,6 @@
1306 import org.junit.Test;
1307
1308 import com.persistit.exception.RollbackException;
1309-import com.persistit.unit.PersistitUnitTestCase;
1310
1311 /**
1312 * TableStatusRecoveryIT and RenameTableIT fail intermittently
1313
1314=== modified file 'src/test/java/com/persistit/Bug912514Test.java'
1315--- src/test/java/com/persistit/Bug912514Test.java 2012-08-15 16:11:36 +0000
1316+++ src/test/java/com/persistit/Bug912514Test.java 2012-08-28 16:17:18 +0000
1317@@ -20,8 +20,6 @@
1318
1319 import org.junit.Test;
1320
1321-import com.persistit.unit.PersistitUnitTestCase;
1322-
1323 /**
1324 * https://bugs.launchpad.net/akiban-persistit/+bug/912514
1325 *
1326
1327=== modified file 'src/test/java/com/persistit/Bug915594Test.java'
1328--- src/test/java/com/persistit/Bug915594Test.java 2012-08-15 16:11:36 +0000
1329+++ src/test/java/com/persistit/Bug915594Test.java 2012-08-28 16:17:18 +0000
1330@@ -21,8 +21,6 @@
1331
1332 import org.junit.Test;
1333
1334-import com.persistit.unit.PersistitUnitTestCase;
1335-
1336 /**
1337 * I did an update that failed due to constraint violation and the transaction
1338 * was rolled back.
1339
1340=== modified file 'src/test/java/com/persistit/Bug918909Test.java'
1341--- src/test/java/com/persistit/Bug918909Test.java 2012-08-15 16:11:36 +0000
1342+++ src/test/java/com/persistit/Bug918909Test.java 2012-08-28 16:17:18 +0000
1343@@ -22,8 +22,6 @@
1344
1345 import org.junit.Test;
1346
1347-import com.persistit.unit.PersistitUnitTestCase;
1348-
1349 /**
1350 * At a DP site experiencing very low insert rates the JournalManager was
1351 * failing to delete obsolete journal files. This was noticed just prior to the
1352
1353=== modified file 'src/test/java/com/persistit/Bug920754Test.java'
1354--- src/test/java/com/persistit/Bug920754Test.java 2012-08-15 16:11:36 +0000
1355+++ src/test/java/com/persistit/Bug920754Test.java 2012-08-28 16:17:18 +0000
1356@@ -19,8 +19,6 @@
1357
1358 import org.junit.Test;
1359
1360-import com.persistit.unit.PersistitUnitTestCase;
1361-
1362 public class Bug920754Test extends PersistitUnitTestCase {
1363 /*
1364 * https://bugs.launchpad.net/akiban-persistit/+bug/920754
1365
1366=== modified file 'src/test/java/com/persistit/Bug923790Test.java'
1367--- src/test/java/com/persistit/Bug923790Test.java 2012-08-15 16:11:36 +0000
1368+++ src/test/java/com/persistit/Bug923790Test.java 2012-08-28 16:17:18 +0000
1369@@ -19,7 +19,6 @@
1370
1371 import org.junit.Test;
1372
1373-import com.persistit.unit.PersistitUnitTestCase;
1374 import com.persistit.util.Util;
1375
1376 /**
1377
1378=== modified file 'src/test/java/com/persistit/Bug927701Test.java'
1379--- src/test/java/com/persistit/Bug927701Test.java 2012-08-15 16:11:36 +0000
1380+++ src/test/java/com/persistit/Bug927701Test.java 2012-08-28 16:17:18 +0000
1381@@ -19,8 +19,6 @@
1382
1383 import org.junit.Test;
1384
1385-import com.persistit.unit.PersistitUnitTestCase;
1386-
1387 /**
1388 * Failure detected during TPCC testing. Upon restarting server, the following
1389 * error was emitted:
1390@@ -54,7 +52,7 @@
1391 @Test
1392 public void testBug927701() throws Exception {
1393 final JournalManager jman = _persistit.getJournalManager();
1394- _persistit.getCleanupManager().setMinimumPruningDelay(0);
1395+ disableBackgroundCleanup();
1396 jman.setCopierInterval(1000);
1397 final long blockSize = jman.getBlockSize();
1398 /*
1399
1400=== modified file 'src/test/java/com/persistit/Bug932097Test.java'
1401--- src/test/java/com/persistit/Bug932097Test.java 2012-08-02 04:45:28 +0000
1402+++ src/test/java/com/persistit/Bug932097Test.java 2012-08-28 16:17:18 +0000
1403@@ -19,8 +19,6 @@
1404
1405 import org.junit.Test;
1406
1407-import com.persistit.unit.PersistitUnitTestCase;
1408-
1409 public class Bug932097Test extends PersistitUnitTestCase {
1410
1411 @Test
1412
1413=== modified file 'src/test/java/com/persistit/Bug937877Test.java'
1414--- src/test/java/com/persistit/Bug937877Test.java 2012-08-15 16:11:36 +0000
1415+++ src/test/java/com/persistit/Bug937877Test.java 2012-08-28 16:17:18 +0000
1416@@ -24,7 +24,6 @@
1417
1418 import org.junit.Test;
1419
1420-import com.persistit.unit.PersistitUnitTestCase;
1421 import com.persistit.util.ThreadSequencer;
1422
1423 public class Bug937877Test extends PersistitUnitTestCase {
1424
1425=== modified file 'src/test/java/com/persistit/Bug942669Test.java'
1426--- src/test/java/com/persistit/Bug942669Test.java 2012-08-15 16:11:36 +0000
1427+++ src/test/java/com/persistit/Bug942669Test.java 2012-08-28 16:17:18 +0000
1428@@ -26,8 +26,6 @@
1429 import org.junit.Ignore;
1430 import org.junit.Test;
1431
1432-import com.persistit.unit.PersistitUnitTestCase;
1433-
1434 public class Bug942669Test extends PersistitUnitTestCase {
1435
1436 // See https://bugs.launchpad.net/akiban-persistit/+bug/942669
1437
1438=== modified file 'src/test/java/com/persistit/Bug947182Test.java'
1439--- src/test/java/com/persistit/Bug947182Test.java 2012-08-15 16:11:36 +0000
1440+++ src/test/java/com/persistit/Bug947182Test.java 2012-08-28 16:17:18 +0000
1441@@ -38,7 +38,6 @@
1442 import org.junit.Test;
1443
1444 import com.persistit.exception.PersistitException;
1445-import com.persistit.unit.PersistitUnitTestCase;
1446 import com.persistit.unit.UnitTestProperties;
1447
1448 public class Bug947182Test extends PersistitUnitTestCase {
1449
1450=== modified file 'src/test/java/com/persistit/Bug974589Test.java'
1451--- src/test/java/com/persistit/Bug974589Test.java 2012-08-15 16:11:36 +0000
1452+++ src/test/java/com/persistit/Bug974589Test.java 2012-08-28 16:17:18 +0000
1453@@ -22,7 +22,6 @@
1454 import org.junit.Test;
1455
1456 import com.persistit.exception.PersistitException;
1457-import com.persistit.unit.PersistitUnitTestCase;
1458 import com.persistit.unit.UnitTestProperties;
1459
1460 public class Bug974589Test extends PersistitUnitTestCase {
1461
1462=== modified file 'src/test/java/com/persistit/Bug980292Test.java'
1463--- src/test/java/com/persistit/Bug980292Test.java 2012-08-15 16:11:36 +0000
1464+++ src/test/java/com/persistit/Bug980292Test.java 2012-08-28 16:17:18 +0000
1465@@ -22,7 +22,6 @@
1466 import org.junit.Test;
1467
1468 import com.persistit.exception.PersistitException;
1469-import com.persistit.unit.PersistitUnitTestCase;
1470 import com.persistit.unit.UnitTestProperties;
1471
1472 public class Bug980292Test extends PersistitUnitTestCase {
1473
1474=== modified file 'src/test/java/com/persistit/Bug989202Test.java'
1475--- src/test/java/com/persistit/Bug989202Test.java 2012-08-15 16:11:36 +0000
1476+++ src/test/java/com/persistit/Bug989202Test.java 2012-08-28 16:17:18 +0000
1477@@ -19,8 +19,6 @@
1478
1479 import org.junit.Test;
1480
1481-import com.persistit.unit.PersistitUnitTestCase;
1482-
1483 /**
1484 * Persistit rev: 284
1485 *
1486
1487=== modified file 'src/test/java/com/persistit/Bug992801Test.java'
1488--- src/test/java/com/persistit/Bug992801Test.java 2012-08-15 16:11:36 +0000
1489+++ src/test/java/com/persistit/Bug992801Test.java 2012-08-28 16:17:18 +0000
1490@@ -19,8 +19,6 @@
1491
1492 import org.junit.Test;
1493
1494-import com.persistit.unit.PersistitUnitTestCase;
1495-
1496 public class Bug992801Test extends PersistitUnitTestCase {
1497 /*
1498 * https://bugs.launchpad.net/akiban-persistit/+bug/992801
1499
1500=== modified file 'src/test/java/com/persistit/Bug996241Test.java'
1501--- src/test/java/com/persistit/Bug996241Test.java 2012-08-15 16:11:36 +0000
1502+++ src/test/java/com/persistit/Bug996241Test.java 2012-08-28 16:17:18 +0000
1503@@ -20,7 +20,6 @@
1504 import org.junit.Test;
1505
1506 import com.persistit.exception.PersistitException;
1507-import com.persistit.unit.PersistitUnitTestCase;
1508 import com.persistit.unit.UnitTestProperties;
1509
1510 public class Bug996241Test extends PersistitUnitTestCase {
1511
1512=== modified file 'src/test/java/com/persistit/ClassIndexTest.java'
1513--- src/test/java/com/persistit/ClassIndexTest.java 2012-08-15 16:11:36 +0000
1514+++ src/test/java/com/persistit/ClassIndexTest.java 2012-08-28 16:17:18 +0000
1515@@ -31,7 +31,6 @@
1516 import org.junit.Test;
1517
1518 import com.persistit.Transaction.CommitPolicy;
1519-import com.persistit.unit.PersistitUnitTestCase;
1520 import com.persistit.util.Util;
1521
1522 public class ClassIndexTest extends PersistitUnitTestCase {
1523
1524=== modified file 'src/test/java/com/persistit/CleanupManagerTest.java'
1525--- src/test/java/com/persistit/CleanupManagerTest.java 2012-08-15 16:11:36 +0000
1526+++ src/test/java/com/persistit/CleanupManagerTest.java 2012-08-28 16:17:18 +0000
1527@@ -24,7 +24,6 @@
1528
1529 import com.persistit.CleanupManager.CleanupAction;
1530 import com.persistit.exception.PersistitException;
1531-import com.persistit.unit.PersistitUnitTestCase;
1532
1533 public class CleanupManagerTest extends PersistitUnitTestCase {
1534
1535
1536=== modified file 'src/test/java/com/persistit/CommandLineTest.java'
1537--- src/test/java/com/persistit/CommandLineTest.java 2012-08-15 16:11:36 +0000
1538+++ src/test/java/com/persistit/CommandLineTest.java 2012-08-28 16:17:18 +0000
1539@@ -29,7 +29,6 @@
1540
1541 import org.junit.Test;
1542
1543-import com.persistit.unit.PersistitUnitTestCase;
1544 import com.persistit.util.Util;
1545
1546 public class CommandLineTest extends PersistitUnitTestCase {
1547
1548=== modified file 'src/test/java/com/persistit/ConfigurationTest.java'
1549--- src/test/java/com/persistit/ConfigurationTest.java 2012-08-15 16:11:36 +0000
1550+++ src/test/java/com/persistit/ConfigurationTest.java 2012-08-28 16:17:18 +0000
1551@@ -33,7 +33,6 @@
1552 import org.junit.Test;
1553
1554 import com.persistit.Configuration.BufferPoolConfiguration;
1555-import com.persistit.unit.PersistitUnitTestCase;
1556
1557 public class ConfigurationTest extends PersistitUnitTestCase {
1558
1559
1560=== modified file 'src/test/java/com/persistit/CorruptVolumeTest.java'
1561--- src/test/java/com/persistit/CorruptVolumeTest.java 2012-08-15 16:11:36 +0000
1562+++ src/test/java/com/persistit/CorruptVolumeTest.java 2012-08-28 16:17:18 +0000
1563@@ -23,7 +23,6 @@
1564
1565 import com.persistit.exception.CorruptVolumeException;
1566 import com.persistit.exception.PersistitException;
1567-import com.persistit.unit.PersistitUnitTestCase;
1568
1569 public class CorruptVolumeTest extends PersistitUnitTestCase {
1570
1571
1572=== modified file 'src/test/java/com/persistit/DumpTaskTest.java'
1573--- src/test/java/com/persistit/DumpTaskTest.java 2012-08-15 16:11:36 +0000
1574+++ src/test/java/com/persistit/DumpTaskTest.java 2012-08-28 16:17:18 +0000
1575@@ -32,7 +32,6 @@
1576 import com.persistit.JournalRecord.IV;
1577 import com.persistit.JournalRecord.PA;
1578 import com.persistit.exception.PersistitException;
1579-import com.persistit.unit.PersistitUnitTestCase;
1580
1581 public class DumpTaskTest extends PersistitUnitTestCase {
1582
1583
1584=== modified file 'src/test/java/com/persistit/FastIndexTest.java'
1585--- src/test/java/com/persistit/FastIndexTest.java 2012-08-15 16:11:36 +0000
1586+++ src/test/java/com/persistit/FastIndexTest.java 2012-08-28 16:17:18 +0000
1587@@ -22,7 +22,6 @@
1588 import org.junit.Test;
1589
1590 import com.persistit.ValueHelper.RawValueWriter;
1591-import com.persistit.unit.PersistitUnitTestCase;
1592
1593 public class FastIndexTest extends PersistitUnitTestCase {
1594
1595
1596=== modified file 'src/test/java/com/persistit/FatalErrorExceptionTest.java'
1597--- src/test/java/com/persistit/FatalErrorExceptionTest.java 2012-08-15 16:11:36 +0000
1598+++ src/test/java/com/persistit/FatalErrorExceptionTest.java 2012-08-28 16:17:18 +0000
1599@@ -20,7 +20,6 @@
1600 import org.junit.Test;
1601
1602 import com.persistit.Persistit.FatalErrorException;
1603-import com.persistit.unit.PersistitUnitTestCase;
1604
1605 public class FatalErrorExceptionTest extends PersistitUnitTestCase {
1606
1607
1608=== modified file 'src/test/java/com/persistit/IOFailureTest.java'
1609--- src/test/java/com/persistit/IOFailureTest.java 2012-08-23 17:52:56 +0000
1610+++ src/test/java/com/persistit/IOFailureTest.java 2012-08-28 16:17:18 +0000
1611@@ -34,7 +34,6 @@
1612 import com.persistit.exception.CorruptVolumeException;
1613 import com.persistit.exception.PersistitException;
1614 import com.persistit.exception.PersistitIOException;
1615-import com.persistit.unit.PersistitUnitTestCase;
1616 import com.persistit.unit.UnitTestProperties;
1617
1618 public class IOFailureTest extends PersistitUnitTestCase {
1619
1620=== modified file 'src/test/java/com/persistit/IOMeterChargeBenchmark.java'
1621--- src/test/java/com/persistit/IOMeterChargeBenchmark.java 2012-08-15 16:11:36 +0000
1622+++ src/test/java/com/persistit/IOMeterChargeBenchmark.java 2012-08-28 16:17:18 +0000
1623@@ -19,8 +19,6 @@
1624
1625 import org.junit.Test;
1626
1627-import com.persistit.unit.PersistitUnitTestCase;
1628-
1629 public class IOMeterChargeBenchmark extends PersistitUnitTestCase {
1630
1631 private final static long SECOND = 1000000000;
1632
1633=== modified file 'src/test/java/com/persistit/InsertSequenceTest.java'
1634--- src/test/java/com/persistit/InsertSequenceTest.java 2012-08-15 16:11:36 +0000
1635+++ src/test/java/com/persistit/InsertSequenceTest.java 2012-08-28 16:17:18 +0000
1636@@ -22,7 +22,6 @@
1637 import com.persistit.Exchange.Sequence;
1638 import com.persistit.exception.PersistitException;
1639 import com.persistit.policy.SplitPolicy;
1640-import com.persistit.unit.PersistitUnitTestCase;
1641
1642 public class InsertSequenceTest extends PersistitUnitTestCase {
1643
1644
1645=== modified file 'src/test/java/com/persistit/IntegrityCheckTest.java'
1646--- src/test/java/com/persistit/IntegrityCheckTest.java 2012-08-15 16:11:36 +0000
1647+++ src/test/java/com/persistit/IntegrityCheckTest.java 2012-08-28 16:17:18 +0000
1648@@ -25,7 +25,6 @@
1649 import org.junit.Test;
1650
1651 import com.persistit.exception.PersistitException;
1652-import com.persistit.unit.PersistitUnitTestCase;
1653
1654 public class IntegrityCheckTest extends PersistitUnitTestCase {
1655
1656@@ -55,7 +54,7 @@
1657 @Test
1658 public void testSimpleMvvTree() throws Exception {
1659 final Exchange ex = _persistit.getExchange(_volumeName, "mvv", true);
1660- _persistit.getCleanupManager().setPollInterval(Integer.MAX_VALUE);
1661+ disableBackgroundCleanup();
1662
1663 transactionalStore(ex);
1664
1665@@ -76,7 +75,7 @@
1666 @Test
1667 public void testBrokenKeySequence() throws Exception {
1668 final Exchange ex = _persistit.getExchange(_volumeName, "mvv", true);
1669- _persistit.getCleanupManager().setPollInterval(Integer.MAX_VALUE);
1670+ disableBackgroundCleanup();
1671
1672 transactionalStore(ex);
1673
1674@@ -90,7 +89,7 @@
1675 @Test
1676 public void testBrokenMVVs() throws Exception {
1677 final Exchange ex = _persistit.getExchange(_volumeName, "mvv", true);
1678- _persistit.getCleanupManager().setPollInterval(Integer.MAX_VALUE);
1679+ disableBackgroundCleanup();
1680 transactionalStore(ex);
1681 corrupt2(ex);
1682 final IntegrityCheck icheck = icheck();
1683@@ -155,6 +154,7 @@
1684 @Test
1685 public void testPruneRemovesAbortedTransactionStatus() throws Exception {
1686 _persistit.getJournalManager().setRollbackPruningEnabled(false);
1687+ _persistit.getJournalManager().setWritePagePruningEnabled(false);
1688
1689 for (int i = 0; i < 10; i++) {
1690 final Exchange ex = _persistit.getExchange(_volumeName, "mvv" + i, true);
1691@@ -179,9 +179,7 @@
1692 _persistit = new Persistit();
1693 _persistit.getRecoveryManager().setRecoveryDisabledForTestMode(true);
1694 _persistit.getJournalManager().setRollbackPruningEnabled(false);
1695- _persistit.getCleanupManager().setMinimumPruningDelay(0); // no
1696- // background
1697- // pruningIn
1698+ disableBackgroundCleanup();
1699 _persistit.initialize(properties);
1700
1701 for (int i = 0; i < 10; i++) {
1702
1703=== modified file 'src/test/java/com/persistit/JournalManagerTest.java'
1704--- src/test/java/com/persistit/JournalManagerTest.java 2012-08-23 15:24:42 +0000
1705+++ src/test/java/com/persistit/JournalManagerTest.java 2012-08-28 16:17:18 +0000
1706@@ -47,7 +47,6 @@
1707 import com.persistit.TransactionPlayer.TransactionPlayerListener;
1708 import com.persistit.exception.PersistitException;
1709 import com.persistit.unit.ConcurrentUtil.ThrowingRunnable;
1710-import com.persistit.unit.PersistitUnitTestCase;
1711 import com.persistit.unit.UnitTestProperties;
1712 import com.persistit.util.Util;
1713
1714@@ -89,6 +88,7 @@
1715 jman.writeCheckpointToJournal(checkpoint1);
1716 final Exchange exchange = _persistit.getExchange(_volumeName, "JournalManagerTest1", false);
1717 volume.getTree("JournalManagerTest1", false).resetHandle();
1718+
1719 assertTrue(exchange.next(true));
1720 final long[] timestamps = new long[100];
1721
1722@@ -299,6 +299,7 @@
1723 public void testRollback() throws Exception {
1724 // Allow test to control when pruning will happen
1725 _persistit.getJournalManager().setRollbackPruningEnabled(false);
1726+ _persistit.getJournalManager().setWritePagePruningEnabled(false);
1727 final Transaction txn = _persistit.getTransaction();
1728 for (int i = 0; i < 10; i++) {
1729 txn.begin();
1730@@ -349,6 +350,8 @@
1731 public void testRollbackLongRecords() throws Exception {
1732 // Allow test to control when pruning will happen
1733 _persistit.getJournalManager().setRollbackPruningEnabled(false);
1734+ _persistit.getJournalManager().setWritePagePruningEnabled(false);
1735+
1736 final Volume volume = _persistit.getVolume(_volumeName);
1737 final Transaction txn = _persistit.getTransaction();
1738 for (int i = 0; i < 10; i++) {
1739
1740=== modified file 'src/test/java/com/persistit/KeyHistogramTest.java'
1741--- src/test/java/com/persistit/KeyHistogramTest.java 2012-08-15 16:11:36 +0000
1742+++ src/test/java/com/persistit/KeyHistogramTest.java 2012-08-28 16:17:18 +0000
1743@@ -19,8 +19,6 @@
1744
1745 import org.junit.Test;
1746
1747-import com.persistit.unit.PersistitUnitTestCase;
1748-
1749 public class KeyHistogramTest extends PersistitUnitTestCase {
1750
1751 private final String _volumeName = "persistit";
1752
1753=== modified file 'src/test/java/com/persistit/MVCCPruneBufferTest.java'
1754--- src/test/java/com/persistit/MVCCPruneBufferTest.java 2012-08-15 16:11:36 +0000
1755+++ src/test/java/com/persistit/MVCCPruneBufferTest.java 2012-08-28 16:17:18 +0000
1756@@ -144,7 +144,7 @@
1757
1758 @Test
1759 public void testPruneLongRecordsSimple() throws Exception {
1760- _persistit.getCleanupManager().setPollInterval(-1);
1761+ disableBackgroundCleanup();
1762 trx1.begin();
1763 storeLongMVV(ex1, "x");
1764 trx1.commit();
1765@@ -156,7 +156,7 @@
1766
1767 @Test
1768 public void testPruneLongRecordsWithRollback() throws Exception {
1769- _persistit.getCleanupManager().setPollInterval(-1);
1770+ disableBackgroundCleanup();
1771 /*
1772 * Start a concurrent transaction to prevent pruning during the store
1773 * operations.
1774@@ -182,7 +182,7 @@
1775
1776 @Test
1777 public void induceBug1006576() throws Exception {
1778- _persistit.getCleanupManager().setPollInterval(-1);
1779+ disableBackgroundCleanup();
1780 trx1.begin();
1781 storeLongMVV(ex1, "x");
1782 storeLongMVV(ex1, "y");
1783@@ -203,7 +203,7 @@
1784
1785 @Test
1786 public void induceBug1005206() throws Exception {
1787- _persistit.getCleanupManager().setPollInterval(-1);
1788+ disableBackgroundCleanup();
1789 trx1.begin();
1790 storeLongMVV(ex1, "x");
1791
1792@@ -297,6 +297,27 @@
1793 }
1794 }
1795
1796+ @Test
1797+ public void testWritePagePrune() throws Exception {
1798+ final Transaction txn = _persistit.getTransaction();
1799+ try {
1800+ txn.begin();
1801+ storeNewVersion(1);
1802+ txn.commit();
1803+ } finally {
1804+ txn.end();
1805+ }
1806+ final Volume volume = _persistit.getVolume(TEST_VOLUME_NAME);
1807+ final Buffer buffer = volume.getPool().get(volume, 3, true, true);
1808+ assertTrue("Should have multiple MVV records", buffer.getMvvCount() > 2);
1809+ _persistit.getJournalManager().setWritePagePruningEnabled(true);
1810+ _persistit.getTransactionIndex().updateActiveTransactionCache();
1811+ buffer.setDirtyAtTimestamp(_persistit.getCurrentTimestamp());
1812+ buffer.writePage();
1813+ assertTrue("Should no more than one MVV record", buffer.getMvvCount() < 2);
1814+ buffer.release();
1815+ }
1816+
1817 private void storeNewVersion(final int cycle) throws Exception {
1818 final Exchange exchange = _persistit.getExchange(TEST_VOLUME_NAME,
1819 String.format("%s%04d", TEST_TREE_NAME, cycle), true);
1820
1821=== modified file 'src/test/java/com/persistit/MVCCTestBase.java'
1822--- src/test/java/com/persistit/MVCCTestBase.java 2012-08-15 16:11:36 +0000
1823+++ src/test/java/com/persistit/MVCCTestBase.java 2012-08-28 16:17:18 +0000
1824@@ -24,7 +24,6 @@
1825
1826 import com.persistit.exception.PersistitException;
1827 import com.persistit.exception.PersistitInterruptedException;
1828-import com.persistit.unit.PersistitUnitTestCase;
1829 import com.persistit.util.Util;
1830
1831 public abstract class MVCCTestBase extends PersistitUnitTestCase {
1832
1833=== added file 'src/test/java/com/persistit/PersistitUnitTestCase.java'
1834--- src/test/java/com/persistit/PersistitUnitTestCase.java 1970-01-01 00:00:00 +0000
1835+++ src/test/java/com/persistit/PersistitUnitTestCase.java 2012-08-28 16:17:18 +0000
1836@@ -0,0 +1,136 @@
1837+/**
1838+ * Copyright © 2005-2012 Akiban Technologies, Inc. All rights reserved.
1839+ *
1840+ * This program and the accompanying materials are made available
1841+ * under the terms of the Eclipse Public License v1.0 which
1842+ * accompanies this distribution, and is available at
1843+ * http://www.eclipse.org/legal/epl-v10.html
1844+ *
1845+ * This program may also be available under different license terms.
1846+ * For more information, see www.akiban.com or contact licensing@akiban.com.
1847+ *
1848+ * Contributors:
1849+ * Akiban Technologies, Inc.
1850+ */
1851+
1852+package com.persistit;
1853+
1854+import java.lang.ref.WeakReference;
1855+import java.util.Map;
1856+import java.util.Properties;
1857+
1858+import org.junit.After;
1859+import org.junit.Before;
1860+
1861+import com.persistit.exception.PersistitException;
1862+import com.persistit.unit.UnitTestProperties;
1863+
1864+public abstract class PersistitUnitTestCase {
1865+
1866+ private final static long TEN_SECONDS = 10L * 1000L * 1000L * 1000L;
1867+
1868+ protected final static String RED_FOX = "The quick red fox jumped over the lazy brown dog.";
1869+
1870+ protected static String createString(final int exactLength) {
1871+ final StringBuilder sb = new StringBuilder(exactLength);
1872+ // Simple 0..9a..z string
1873+ for (int i = 0; i < 36; ++i) {
1874+ sb.append(Character.forDigit(i, 36));
1875+ }
1876+ final String numAndLetters = sb.toString();
1877+ while (sb.length() < exactLength) {
1878+ sb.append(numAndLetters);
1879+ }
1880+ return sb.toString().substring(0, exactLength);
1881+ }
1882+
1883+ protected Persistit _persistit = new Persistit();
1884+
1885+ protected Properties getProperties(final boolean cleanup) {
1886+ return UnitTestProperties.getProperties(cleanup);
1887+ }
1888+
1889+ @Before
1890+ public void setUp() throws Exception {
1891+ checkNoPersistitThreads();
1892+ _persistit.initialize(getProperties(true));
1893+ }
1894+
1895+ @After
1896+ public void tearDown() throws Exception {
1897+ final WeakReference<Persistit> ref = new WeakReference<Persistit>(_persistit);
1898+ _persistit.close(false);
1899+ _persistit = null;
1900+
1901+ if (!doesRefBecomeNull(ref)) {
1902+ System.out.println("Persistit has a leftover strong reference");
1903+ }
1904+ checkNoPersistitThreads();
1905+ }
1906+
1907+ public void runAllTests() throws Exception {
1908+
1909+ }
1910+
1911+ public void setPersistit(final Persistit persistit) {
1912+ _persistit = persistit;
1913+ }
1914+
1915+ protected void initAndRunTest() throws Exception {
1916+ setUp();
1917+ try {
1918+ runAllTests();
1919+ } catch (final Throwable t) {
1920+ t.printStackTrace();
1921+ } finally {
1922+ tearDown();
1923+ }
1924+ }
1925+
1926+ private final static String[] PERSISTIT_THREAD_NAMES = { "CHECKPOINT_WRITER", "JOURNAL_COPIER", "JOURNAL_FLUSHER",
1927+ "PAGE_WRITER", "TXN_UPDATE" };
1928+
1929+ protected boolean checkNoPersistitThreads() {
1930+ boolean alive = false;
1931+ final Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();
1932+ for (final Thread t : map.keySet()) {
1933+ final String name = t.getName();
1934+ for (final String p : PERSISTIT_THREAD_NAMES) {
1935+ if (name.contains(p)) {
1936+ alive = true;
1937+ System.err.println("Thread " + t + " is still alive");
1938+ }
1939+ }
1940+ }
1941+ return alive;
1942+ }
1943+
1944+ protected void safeCrashAndRestoreProperties() throws PersistitException {
1945+ final Properties properties = _persistit.getProperties();
1946+ _persistit.flush();
1947+ _persistit.crash();
1948+ _persistit = new Persistit();
1949+ _persistit.initialize(properties);
1950+ }
1951+
1952+ protected void crashWithoutFlushAndRestoreProperties() throws PersistitException {
1953+ final Properties properties = _persistit.getProperties();
1954+ _persistit.crash();
1955+ _persistit = new Persistit();
1956+ _persistit.initialize(properties);
1957+ }
1958+
1959+ public static boolean doesRefBecomeNull(final WeakReference<?> ref) throws InterruptedException {
1960+ final long expires = System.nanoTime() + TEN_SECONDS;
1961+ while (ref.get() != null && System.nanoTime() < expires) {
1962+ System.gc();
1963+ Thread.sleep(10);
1964+ }
1965+ return ref.get() == null;
1966+ }
1967+
1968+ protected void disableBackgroundCleanup() {
1969+ _persistit.getCleanupManager().setPollInterval(-1);
1970+ _persistit.getJournalManager().setWritePagePruningEnabled(false);
1971+ }
1972+}
1973
1974=== modified file 'src/test/java/com/persistit/RecoveryTest.java'
1975--- src/test/java/com/persistit/RecoveryTest.java 2012-08-15 16:11:36 +0000
1976+++ src/test/java/com/persistit/RecoveryTest.java 2012-08-28 16:17:18 +0000
1977@@ -37,7 +37,6 @@
1978 import com.persistit.exception.PersistitException;
1979 import com.persistit.exception.RollbackException;
1980 import com.persistit.exception.TransactionFailedException;
1981-import com.persistit.unit.PersistitUnitTestCase;
1982 import com.persistit.unit.UnitTestProperties;
1983
1984 public class RecoveryTest extends PersistitUnitTestCase {
1985@@ -53,6 +52,8 @@
1986 public void setUp() throws Exception {
1987 super.setUp();
1988 _persistit.getJournalManager().setRollbackPruningEnabled(false);
1989+ _persistit.getJournalManager().setWritePagePruningEnabled(false);
1990+
1991 }
1992
1993 @Override
1994
1995=== modified file 'src/test/java/com/persistit/SplitPolicyTest.java'
1996--- src/test/java/com/persistit/SplitPolicyTest.java 2012-08-15 16:11:36 +0000
1997+++ src/test/java/com/persistit/SplitPolicyTest.java 2012-08-28 16:17:18 +0000
1998@@ -24,7 +24,6 @@
1999
2000 import com.persistit.Exchange.Sequence;
2001 import com.persistit.policy.SplitPolicy;
2002-import com.persistit.unit.PersistitUnitTestCase;
2003
2004 public class SplitPolicyTest extends PersistitUnitTestCase {
2005
2006
2007=== modified file 'src/test/java/com/persistit/StatisticsTaskTest.java'
2008--- src/test/java/com/persistit/StatisticsTaskTest.java 2012-08-02 04:45:28 +0000
2009+++ src/test/java/com/persistit/StatisticsTaskTest.java 2012-08-28 16:17:18 +0000
2010@@ -27,7 +27,6 @@
2011
2012 import com.persistit.StatisticsTask.Display;
2013 import com.persistit.StatisticsTask.Stat;
2014-import com.persistit.unit.PersistitUnitTestCase;
2015
2016 public class StatisticsTaskTest extends PersistitUnitTestCase {
2017
2018
2019=== modified file 'src/test/java/com/persistit/TransactionLifetimeTest.java'
2020--- src/test/java/com/persistit/TransactionLifetimeTest.java 2012-08-15 16:11:36 +0000
2021+++ src/test/java/com/persistit/TransactionLifetimeTest.java 2012-08-28 16:17:18 +0000
2022@@ -24,7 +24,6 @@
2023
2024 import com.persistit.exception.PersistitException;
2025 import com.persistit.exception.TreeNotFoundException;
2026-import com.persistit.unit.PersistitUnitTestCase;
2027
2028 /**
2029 * Attempt to cover all cases from the pseudo graph below and ensure that the
2030@@ -63,6 +62,8 @@
2031 _persistit.getCheckpointManager().setCheckpointIntervalNanos(FIVE_MIN_NANOS);
2032 super.setUp();
2033 _persistit.getJournalManager().setRollbackPruningEnabled(false);
2034+ _persistit.getJournalManager().setWritePagePruningEnabled(false);
2035+
2036 }
2037
2038 @Test
2039@@ -354,6 +355,8 @@
2040 currentInLiveMap = false;
2041 safeCrashAndRestoreProperties();
2042 _persistit.getJournalManager().setRollbackPruningEnabled(false);
2043+ _persistit.getJournalManager().setWritePagePruningEnabled(false);
2044+
2045 } else {
2046 fail("Unknown test node: " + curNode);
2047 }
2048
2049=== modified file 'src/test/java/com/persistit/TransactionTest2.java'
2050--- src/test/java/com/persistit/TransactionTest2.java 2012-08-15 16:11:36 +0000
2051+++ src/test/java/com/persistit/TransactionTest2.java 2012-08-28 16:17:18 +0000
2052@@ -33,7 +33,6 @@
2053 import com.persistit.exception.PersistitIOException;
2054 import com.persistit.exception.PersistitInterruptedException;
2055 import com.persistit.exception.RollbackException;
2056-import com.persistit.unit.PersistitUnitTestCase;
2057
2058 /**
2059 * Demonstrates the use of Persistit Transactions. This demo runs multiple
2060
2061=== modified file 'src/test/java/com/persistit/TreeLifetimeTest.java'
2062--- src/test/java/com/persistit/TreeLifetimeTest.java 2012-08-15 16:11:36 +0000
2063+++ src/test/java/com/persistit/TreeLifetimeTest.java 2012-08-28 16:17:18 +0000
2064@@ -45,7 +45,6 @@
2065 import com.persistit.JournalManager.TreeDescriptor;
2066 import com.persistit.exception.PersistitException;
2067 import com.persistit.exception.TreeNotFoundException;
2068-import com.persistit.unit.PersistitUnitTestCase;
2069 import com.persistit.unit.UnitTestProperties;
2070
2071 public class TreeLifetimeTest extends PersistitUnitTestCase {
2072
2073=== modified file 'src/test/java/com/persistit/TreeTest2.java'
2074--- src/test/java/com/persistit/TreeTest2.java 2012-08-15 16:11:36 +0000
2075+++ src/test/java/com/persistit/TreeTest2.java 2012-08-28 16:17:18 +0000
2076@@ -23,8 +23,6 @@
2077
2078 import org.junit.Test;
2079
2080-import com.persistit.unit.PersistitUnitTestCase;
2081-
2082 public class TreeTest2 extends PersistitUnitTestCase {
2083
2084 final static int COUNT = 10000;
2085
2086=== modified file 'src/test/java/com/persistit/ValueTest7.java'
2087--- src/test/java/com/persistit/ValueTest7.java 2012-08-15 16:11:36 +0000
2088+++ src/test/java/com/persistit/ValueTest7.java 2012-08-28 16:17:18 +0000
2089@@ -23,7 +23,6 @@
2090 import org.junit.Test;
2091
2092 import com.persistit.Value.Version;
2093-import com.persistit.unit.PersistitUnitTestCase;
2094
2095 public class ValueTest7 extends PersistitUnitTestCase {
2096
2097
2098=== modified file 'src/test/java/com/persistit/VolumeTest.java'
2099--- src/test/java/com/persistit/VolumeTest.java 2012-08-15 16:11:36 +0000
2100+++ src/test/java/com/persistit/VolumeTest.java 2012-08-28 16:17:18 +0000
2101@@ -32,7 +32,6 @@
2102 import com.persistit.exception.InUseException;
2103 import com.persistit.exception.InvalidVolumeSpecificationException;
2104 import com.persistit.exception.VolumeFullException;
2105-import com.persistit.unit.PersistitUnitTestCase;
2106 import com.persistit.unit.UnitTestProperties;
2107
2108 public class VolumeTest extends PersistitUnitTestCase {
2109
2110=== modified file 'src/test/java/com/persistit/WarmupTest.java'
2111--- src/test/java/com/persistit/WarmupTest.java 2012-08-27 21:54:10 +0000
2112+++ src/test/java/com/persistit/WarmupTest.java 2012-08-28 16:17:18 +0000
2113@@ -22,8 +22,6 @@
2114
2115 import org.junit.Test;
2116
2117-import com.persistit.unit.PersistitUnitTestCase;
2118-
2119 public class WarmupTest extends PersistitUnitTestCase {
2120
2121 @Override
2122
2123=== modified file 'src/test/java/com/persistit/stress/unit/CommitBench.java'
2124--- src/test/java/com/persistit/stress/unit/CommitBench.java 2012-08-23 15:24:42 +0000
2125+++ src/test/java/com/persistit/stress/unit/CommitBench.java 2012-08-28 16:17:18 +0000
2126@@ -15,15 +15,19 @@
2127
2128 package com.persistit.stress.unit;
2129
2130+import java.io.File;
2131+import java.io.IOException;
2132+import java.io.RandomAccessFile;
2133 import java.util.Properties;
2134 import java.util.Random;
2135 import java.util.concurrent.atomic.AtomicInteger;
2136+import java.util.regex.Pattern;
2137
2138 import com.persistit.Exchange;
2139+import com.persistit.PersistitUnitTestCase;
2140 import com.persistit.Transaction;
2141 import com.persistit.Transaction.CommitPolicy;
2142 import com.persistit.exception.RollbackException;
2143-import com.persistit.unit.PersistitUnitTestCase;
2144 import com.persistit.unit.UnitTestProperties;
2145 import com.persistit.util.ArgParser;
2146
2147@@ -38,6 +42,9 @@
2148 *
2149 */
2150 public class CommitBench extends PersistitUnitTestCase {
2151+
2152+ final static Pattern PATH_PATTERN = Pattern.compile("(.+)\\.(\\d{12})");
2153+
2154 /*
2155 * Want about 1000 pages worth of data (no evictions). Each record is about
2156 * 50 bytes, so 1000 * 16384 * 60% / 50 ~= 200000.
2157@@ -47,19 +54,56 @@
2158 private final int RECORDS_PER_TXN = 10;
2159 private final String[] ARG_TEMPLATE = new String[] { "threads|int:1:1:1000|Number of threads",
2160 "duration|int:10:10:86400|Duration of test in seconds",
2161- "policy|String:HARD|Commit policy: SOFT, HARD or GROUP", };
2162+ "policy|String:HARD|Commit policy: SOFT, HARD or GROUP", "datapath|String|Datapath property",
2163+ "_flag|P|Reuse journal file" };
2164
2165 volatile long stopTime;
2166+ final ArgParser ap;
2167 AtomicInteger commitCount = new AtomicInteger();
2168 AtomicInteger rollbackCount = new AtomicInteger();
2169
2170+ CommitBench(final String[] args) {
2171+ ap = new ArgParser("CommitBench", args, ARG_TEMPLATE).strict();
2172+ }
2173+
2174 @Override
2175 protected Properties getProperties(final boolean cleanup) {
2176- return UnitTestProperties.getBiggerProperties(cleanup);
2177+ final Properties p = UnitTestProperties.getBiggerProperties(false);
2178+ if (ap.isSpecified("datapath")) {
2179+ p.setProperty("datapath", ap.getStringValue("datapath"));
2180+ }
2181+ /*
2182+ * Custom data directory cleanup - leaving the journal file behind if
2183+ */
2184+ final String path = p.getProperty("datapath");
2185+ final File dir = new File(path);
2186+ assert dir.isDirectory() : "Data path does not specify a directory: " + path;
2187+ final File[] files = dir.listFiles();
2188+ for (final File file : files) {
2189+ if (ap.isFlag('P') && PATH_PATTERN.matcher(file.getName()).matches()) {
2190+ try {
2191+ /*
2192+ * Damage the file so that there's no keystone checkpoint
2193+ */
2194+ RandomAccessFile raf = new RandomAccessFile(file, "rws");
2195+ raf.seek(0);
2196+ raf.write(new byte[256]);
2197+ raf.close();
2198+ } catch (IOException e) {
2199+ throw new RuntimeException(e);
2200+ }
2201+ } else {
2202+ if (file.isDirectory()) {
2203+ UnitTestProperties.cleanUpDirectory(file);
2204+ } else {
2205+ file.delete();
2206+ }
2207+ }
2208+ }
2209+ return p;
2210 }
2211
2212- public void bench(final String[] args) throws Exception {
2213- final ArgParser ap = new ArgParser("CommitBench", args, ARG_TEMPLATE).strict();
2214+ public void bench() throws Exception {
2215 final int threadCount = ap.getIntValue("threads");
2216 final int duration = ap.getIntValue("duration");
2217 final String policy = ap.getStringValue("policy");
2218@@ -138,10 +182,10 @@
2219 }
2220
2221 public static void main(final String[] args) throws Exception {
2222- final CommitBench bench = new CommitBench();
2223+ final CommitBench bench = new CommitBench(args);
2224 try {
2225 bench.setUp();
2226- bench.bench(args);
2227+ bench.bench();
2228 } finally {
2229 bench.tearDown();
2230 }
2231
2232=== modified file 'src/test/java/com/persistit/stress/unit/TestSamePageOptimization.java'
2233--- src/test/java/com/persistit/stress/unit/TestSamePageOptimization.java 2012-08-15 16:11:36 +0000
2234+++ src/test/java/com/persistit/stress/unit/TestSamePageOptimization.java 2012-08-28 16:17:18 +0000
2235@@ -19,8 +19,8 @@
2236
2237 import com.persistit.Exchange;
2238 import com.persistit.Key;
2239+import com.persistit.PersistitUnitTestCase;
2240 import com.persistit.exception.PersistitException;
2241-import com.persistit.unit.PersistitUnitTestCase;
2242
2243 public class TestSamePageOptimization extends PersistitUnitTestCase {
2244 final int KEYS = 1000000;
2245
2246=== modified file 'src/test/java/com/persistit/unit/BufferPoolMemConfigurationTest.java'
2247--- src/test/java/com/persistit/unit/BufferPoolMemConfigurationTest.java 2012-08-15 16:11:36 +0000
2248+++ src/test/java/com/persistit/unit/BufferPoolMemConfigurationTest.java 2012-08-28 16:17:18 +0000
2249@@ -24,6 +24,7 @@
2250 import org.junit.Test;
2251
2252 import com.persistit.Management.BufferPoolInfo;
2253+import com.persistit.PersistitUnitTestCase;
2254
2255 public class BufferPoolMemConfigurationTest extends PersistitUnitTestCase {
2256
2257
2258=== modified file 'src/test/java/com/persistit/unit/DefaultCoderManagerTest.java'
2259--- src/test/java/com/persistit/unit/DefaultCoderManagerTest.java 2012-08-02 04:45:28 +0000
2260+++ src/test/java/com/persistit/unit/DefaultCoderManagerTest.java 2012-08-28 16:17:18 +0000
2261@@ -25,6 +25,7 @@
2262 import org.junit.Test;
2263
2264 import com.persistit.DefaultCoderManager;
2265+import com.persistit.PersistitUnitTestCase;
2266 import com.persistit.exception.PersistitException;
2267
2268 public class DefaultCoderManagerTest extends PersistitUnitTestCase implements Serializable {
2269
2270=== modified file 'src/test/java/com/persistit/unit/ExchangeTest.java'
2271--- src/test/java/com/persistit/unit/ExchangeTest.java 2012-08-15 16:11:36 +0000
2272+++ src/test/java/com/persistit/unit/ExchangeTest.java 2012-08-28 16:17:18 +0000
2273@@ -28,6 +28,7 @@
2274 import com.persistit.Exchange;
2275 import com.persistit.Key;
2276 import com.persistit.KeyFilter;
2277+import com.persistit.PersistitUnitTestCase;
2278 import com.persistit.Transaction;
2279 import com.persistit.Volume;
2280 import com.persistit.exception.ConversionException;
2281
2282=== modified file 'src/test/java/com/persistit/unit/FileLockTest.java'
2283--- src/test/java/com/persistit/unit/FileLockTest.java 2012-08-15 16:11:36 +0000
2284+++ src/test/java/com/persistit/unit/FileLockTest.java 2012-08-28 16:17:18 +0000
2285@@ -22,6 +22,7 @@
2286 import org.junit.Test;
2287
2288 import com.persistit.Persistit;
2289+import com.persistit.PersistitUnitTestCase;
2290 import com.persistit.exception.PersistitException;
2291
2292 /**
2293
2294=== modified file 'src/test/java/com/persistit/unit/JoinTest1.java'
2295--- src/test/java/com/persistit/unit/JoinTest1.java 2012-08-15 16:11:36 +0000
2296+++ src/test/java/com/persistit/unit/JoinTest1.java 2012-08-28 16:17:18 +0000
2297@@ -21,6 +21,7 @@
2298
2299 import com.persistit.Exchange;
2300 import com.persistit.Key;
2301+import com.persistit.PersistitUnitTestCase;
2302 import com.persistit.Value;
2303 import com.persistit.exception.PersistitException;
2304
2305
2306=== modified file 'src/test/java/com/persistit/unit/KeyCoderTest1.java'
2307--- src/test/java/com/persistit/unit/KeyCoderTest1.java 2012-08-15 16:11:36 +0000
2308+++ src/test/java/com/persistit/unit/KeyCoderTest1.java 2012-08-28 16:17:18 +0000
2309@@ -27,6 +27,7 @@
2310 import org.junit.Test;
2311
2312 import com.persistit.Key;
2313+import com.persistit.PersistitUnitTestCase;
2314 import com.persistit.TestShim;
2315 import com.persistit.encoding.CoderContext;
2316 import com.persistit.encoding.KeyCoder;
2317
2318=== modified file 'src/test/java/com/persistit/unit/KeyFilterTest1.java'
2319--- src/test/java/com/persistit/unit/KeyFilterTest1.java 2012-08-02 04:45:28 +0000
2320+++ src/test/java/com/persistit/unit/KeyFilterTest1.java 2012-08-28 16:17:18 +0000
2321@@ -28,6 +28,7 @@
2322 import com.persistit.KeyFilter;
2323 import com.persistit.KeyState;
2324 import com.persistit.Persistit;
2325+import com.persistit.PersistitUnitTestCase;
2326 import com.persistit.exception.PersistitException;
2327
2328 /**
2329
2330=== modified file 'src/test/java/com/persistit/unit/KeyFilterTest2.java'
2331--- src/test/java/com/persistit/unit/KeyFilterTest2.java 2012-08-15 16:11:36 +0000
2332+++ src/test/java/com/persistit/unit/KeyFilterTest2.java 2012-08-28 16:17:18 +0000
2333@@ -23,6 +23,7 @@
2334 import com.persistit.Exchange;
2335 import com.persistit.Key;
2336 import com.persistit.KeyFilter;
2337+import com.persistit.PersistitUnitTestCase;
2338 import com.persistit.exception.PersistitException;
2339
2340 /**
2341
2342=== modified file 'src/test/java/com/persistit/unit/KeyParserTest1.java'
2343--- src/test/java/com/persistit/unit/KeyParserTest1.java 2012-08-02 04:45:28 +0000
2344+++ src/test/java/com/persistit/unit/KeyParserTest1.java 2012-08-28 16:17:18 +0000
2345@@ -23,6 +23,7 @@
2346 import com.persistit.Key;
2347 import com.persistit.KeyParser;
2348 import com.persistit.Persistit;
2349+import com.persistit.PersistitUnitTestCase;
2350
2351 /**
2352 * @version 1.0
2353
2354=== modified file 'src/test/java/com/persistit/unit/KeyParserTest2.java'
2355--- src/test/java/com/persistit/unit/KeyParserTest2.java 2012-08-02 04:45:28 +0000
2356+++ src/test/java/com/persistit/unit/KeyParserTest2.java 2012-08-28 16:17:18 +0000
2357@@ -23,6 +23,7 @@
2358 import com.persistit.Key;
2359 import com.persistit.KeyFilter;
2360 import com.persistit.KeyParser;
2361+import com.persistit.PersistitUnitTestCase;
2362
2363 public class KeyParserTest2 extends PersistitUnitTestCase {
2364
2365
2366=== modified file 'src/test/java/com/persistit/unit/KeyTest1.java'
2367--- src/test/java/com/persistit/unit/KeyTest1.java 2012-08-15 16:11:36 +0000
2368+++ src/test/java/com/persistit/unit/KeyTest1.java 2012-08-28 16:17:18 +0000
2369@@ -30,6 +30,7 @@
2370 import com.persistit.Buffer;
2371 import com.persistit.Key;
2372 import com.persistit.KeyState;
2373+import com.persistit.PersistitUnitTestCase;
2374 import com.persistit.TestShim;
2375 import com.persistit.exception.InvalidKeyException;
2376 import com.persistit.exception.MissingKeySegmentException;
2377
2378=== modified file 'src/test/java/com/persistit/unit/Log4JLoggerTest.java'
2379--- src/test/java/com/persistit/unit/Log4JLoggerTest.java 2012-08-15 16:11:36 +0000
2380+++ src/test/java/com/persistit/unit/Log4JLoggerTest.java 2012-08-28 16:17:18 +0000
2381@@ -20,6 +20,7 @@
2382 import org.junit.Test;
2383
2384 import com.persistit.Persistit;
2385+import com.persistit.PersistitUnitTestCase;
2386 import com.persistit.exception.PersistitException;
2387 import com.persistit.logging.Log4JAdapter;
2388
2389
2390=== modified file 'src/test/java/com/persistit/unit/LongRecordTest1.java'
2391--- src/test/java/com/persistit/unit/LongRecordTest1.java 2012-08-15 16:11:36 +0000
2392+++ src/test/java/com/persistit/unit/LongRecordTest1.java 2012-08-28 16:17:18 +0000
2393@@ -22,6 +22,7 @@
2394
2395 import com.persistit.Exchange;
2396 import com.persistit.Key;
2397+import com.persistit.PersistitUnitTestCase;
2398 import com.persistit.exception.PersistitException;
2399 import com.persistit.util.Debug;
2400 import com.persistit.util.Util;
2401
2402=== modified file 'src/test/java/com/persistit/unit/LotsaSmallKeys.java'
2403--- src/test/java/com/persistit/unit/LotsaSmallKeys.java 2012-08-15 16:11:36 +0000
2404+++ src/test/java/com/persistit/unit/LotsaSmallKeys.java 2012-08-28 16:17:18 +0000
2405@@ -20,6 +20,7 @@
2406 import org.junit.Test;
2407
2408 import com.persistit.Exchange;
2409+import com.persistit.PersistitUnitTestCase;
2410 import com.persistit.exception.PersistitException;
2411 import com.persistit.policy.SplitPolicy;
2412
2413
2414=== modified file 'src/test/java/com/persistit/unit/PersistitMapTest.java'
2415--- src/test/java/com/persistit/unit/PersistitMapTest.java 2012-08-15 16:11:36 +0000
2416+++ src/test/java/com/persistit/unit/PersistitMapTest.java 2012-08-28 16:17:18 +0000
2417@@ -34,6 +34,7 @@
2418 import com.persistit.Exchange;
2419 import com.persistit.KeyFilter;
2420 import com.persistit.PersistitMap;
2421+import com.persistit.PersistitUnitTestCase;
2422 import com.persistit.exception.PersistitException;
2423 import com.persistit.util.Util;
2424
2425
2426=== removed file 'src/test/java/com/persistit/unit/PersistitUnitTestCase.java'
2427--- src/test/java/com/persistit/unit/PersistitUnitTestCase.java 2012-08-23 15:30:46 +0000
2428+++ src/test/java/com/persistit/unit/PersistitUnitTestCase.java 1970-01-01 00:00:00 +0000
2429@@ -1,133 +0,0 @@
2430-/**
2431- * Copyright © 2011-2012 Akiban Technologies, Inc. All rights reserved.
2432- *
2433- * This program and the accompanying materials are made available
2434- * under the terms of the Eclipse Public License v1.0 which
2435- * accompanies this distribution, and is available at
2436- * http://www.eclipse.org/legal/epl-v10.html
2437- *
2438- * This program may also be available under different license terms.
2439- * For more information, see www.akiban.com or contact licensing@akiban.com.
2440- *
2441- * Contributors:
2442- * Akiban Technologies, Inc.
2443- */
2444-
2445-package com.persistit.unit;
2446-
2447-import java.lang.ref.WeakReference;
2448-import java.util.Map;
2449-import java.util.Properties;
2450-
2451-import org.junit.After;
2452-import org.junit.Before;
2453-
2454-import com.persistit.Persistit;
2455-import com.persistit.exception.PersistitException;
2456-
2457-public abstract class PersistitUnitTestCase {
2458-
2459- private final static long TEN_SECONDS = 10L * 1000L * 1000L * 1000L;
2460-
2461- protected final static String RED_FOX = "The quick red fox jumped over the lazy brown dog.";
2462-
2463- protected static String createString(final int exactLength) {
2464- final StringBuilder sb = new StringBuilder(exactLength);
2465- // Simple 0..9a..z string
2466- for (int i = 0; i < 36; ++i) {
2467- sb.append(Character.forDigit(i, 36));
2468- }
2469- final String numAndLetters = sb.toString();
2470- while (sb.length() < exactLength) {
2471- sb.append(numAndLetters);
2472- }
2473- return sb.toString().substring(0, exactLength);
2474- }
2475-
2476- protected Persistit _persistit = new Persistit();
2477-
2478- protected Properties getProperties(final boolean cleanup) {
2479- final Properties p = UnitTestProperties.getProperties(cleanup);
2480- return p;
2481- }
2482-
2483- @Before
2484- public void setUp() throws Exception {
2485- checkNoPersistitThreads();
2486-
2487- _persistit.initialize(getProperties(true));
2488- }
2489-
2490- @After
2491- public void tearDown() throws Exception {
2492- final WeakReference<Persistit> ref = new WeakReference<Persistit>(_persistit);
2493- _persistit.close(false);
2494- _persistit = null;
2495-
2496- if (!doesRefBecomeNull(ref)) {
2497- System.out.println("Persistit has a leftover strong reference");
2498- }
2499- checkNoPersistitThreads();
2500- }
2501-
2502- public void runAllTests() throws Exception {
2503-
2504- }
2505-
2506- public void setPersistit(final Persistit persistit) {
2507- _persistit = persistit;
2508- }
2509-
2510- protected void initAndRunTest() throws Exception {
2511- setUp();
2512- try {
2513- runAllTests();
2514- } catch (final Throwable t) {
2515- t.printStackTrace();
2516- } finally {
2517- tearDown();
2518- }
2519- }
2520-
2521- private final static String[] PERSISTIT_THREAD_NAMES = { "CHECKPOINT_WRITER", "JOURNAL_COPIER", "JOURNAL_FLUSHER",
2522- "PAGE_WRITER", "TXN_UPDATE" };
2523-
2524- protected boolean checkNoPersistitThreads() {
2525- boolean alive = false;
2526- final Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();
2527- for (final Thread t : map.keySet()) {
2528- final String name = t.getName();
2529- for (final String p : PERSISTIT_THREAD_NAMES) {
2530- if (name.contains(p)) {
2531- alive = true;
2532- System.err.println("Thread " + t + " is still alive");
2533- }
2534- }
2535- }
2536- return alive;
2537- }
2538-
2539- protected void safeCrashAndRestoreProperties() throws PersistitException {
2540- final Properties properties = _persistit.getProperties();
2541- _persistit.flush();
2542- _persistit.crash();
2543- _persistit = new Persistit();
2544- _persistit.initialize(properties);
2545- }
2546-
2547- protected void crashWithoutFlushAndRestoreProperties() throws PersistitException {
2548- final Properties properties = _persistit.getProperties();
2549- _persistit.crash();
2550- _persistit = new Persistit();
2551- _persistit.initialize(properties);
2552- }
2553-
2554- public static boolean doesRefBecomeNull(final WeakReference<?> ref) throws InterruptedException {
2555- final long expires = System.nanoTime() + TEN_SECONDS;
2556- while (ref.get() != null && System.nanoTime() < expires) {
2557- System.gc();
2558- Thread.sleep(10);
2559- }
2560- return ref.get() == null;
2561- }
2562-}
2563
2564=== modified file 'src/test/java/com/persistit/unit/SaveLoadTest1.java'
2565--- src/test/java/com/persistit/unit/SaveLoadTest1.java 2012-08-02 04:45:28 +0000
2566+++ src/test/java/com/persistit/unit/SaveLoadTest1.java 2012-08-28 16:17:18 +0000
2567@@ -24,6 +24,7 @@
2568 import org.junit.Test;
2569
2570 import com.persistit.PersistitMap;
2571+import com.persistit.PersistitUnitTestCase;
2572 import com.persistit.StreamLoader;
2573 import com.persistit.StreamSaver;
2574 import com.persistit.exception.PersistitException;
2575
2576=== modified file 'src/test/java/com/persistit/unit/SimpleTest1.java'
2577--- src/test/java/com/persistit/unit/SimpleTest1.java 2012-08-15 16:11:36 +0000
2578+++ src/test/java/com/persistit/unit/SimpleTest1.java 2012-08-28 16:17:18 +0000
2579@@ -25,6 +25,7 @@
2580
2581 import com.persistit.Exchange;
2582 import com.persistit.Key;
2583+import com.persistit.PersistitUnitTestCase;
2584 import com.persistit.Value;
2585 import com.persistit.exception.PersistitException;
2586
2587
2588=== modified file 'src/test/java/com/persistit/unit/TemporaryVolumeTest1.java'
2589--- src/test/java/com/persistit/unit/TemporaryVolumeTest1.java 2012-08-15 16:11:36 +0000
2590+++ src/test/java/com/persistit/unit/TemporaryVolumeTest1.java 2012-08-28 16:17:18 +0000
2591@@ -28,6 +28,7 @@
2592 import com.persistit.Exchange;
2593 import com.persistit.Key;
2594 import com.persistit.Management;
2595+import com.persistit.PersistitUnitTestCase;
2596 import com.persistit.Value;
2597 import com.persistit.Volume;
2598 import com.persistit.exception.PersistitException;
2599
2600=== modified file 'src/test/java/com/persistit/unit/TransactionTest1.java'
2601--- src/test/java/com/persistit/unit/TransactionTest1.java 2012-08-15 16:11:36 +0000
2602+++ src/test/java/com/persistit/unit/TransactionTest1.java 2012-08-28 16:17:18 +0000
2603@@ -28,6 +28,7 @@
2604 import com.persistit.Exchange;
2605 import com.persistit.Key;
2606 import com.persistit.KeyFilter;
2607+import com.persistit.PersistitUnitTestCase;
2608 import com.persistit.Transaction;
2609 import com.persistit.Value;
2610 import com.persistit.exception.PersistitException;
2611
2612=== modified file 'src/test/java/com/persistit/unit/TransactionTest3.java'
2613--- src/test/java/com/persistit/unit/TransactionTest3.java 2012-08-15 16:11:36 +0000
2614+++ src/test/java/com/persistit/unit/TransactionTest3.java 2012-08-28 16:17:18 +0000
2615@@ -27,6 +27,7 @@
2616
2617 import com.persistit.Exchange;
2618 import com.persistit.Key;
2619+import com.persistit.PersistitUnitTestCase;
2620 import com.persistit.Transaction;
2621 import com.persistit.exception.PersistitException;
2622
2623
2624=== modified file 'src/test/java/com/persistit/unit/TreeTest1.java'
2625--- src/test/java/com/persistit/unit/TreeTest1.java 2012-08-02 04:45:28 +0000
2626+++ src/test/java/com/persistit/unit/TreeTest1.java 2012-08-28 16:17:18 +0000
2627@@ -23,6 +23,7 @@
2628
2629 import com.persistit.Exchange;
2630 import com.persistit.Key;
2631+import com.persistit.PersistitUnitTestCase;
2632
2633 public class TreeTest1 extends PersistitUnitTestCase {
2634
2635
2636=== modified file 'src/test/java/com/persistit/unit/ValueCoderTest1.java'
2637--- src/test/java/com/persistit/unit/ValueCoderTest1.java 2012-08-15 16:11:36 +0000
2638+++ src/test/java/com/persistit/unit/ValueCoderTest1.java 2012-08-28 16:17:18 +0000
2639@@ -28,6 +28,7 @@
2640 import org.junit.Test;
2641
2642 import com.persistit.Exchange;
2643+import com.persistit.PersistitUnitTestCase;
2644 import com.persistit.Value;
2645 import com.persistit.encoding.CoderContext;
2646 import com.persistit.encoding.ValueCoder;
2647
2648=== modified file 'src/test/java/com/persistit/unit/ValueCoderTest2.java'
2649--- src/test/java/com/persistit/unit/ValueCoderTest2.java 2012-08-02 04:45:28 +0000
2650+++ src/test/java/com/persistit/unit/ValueCoderTest2.java 2012-08-28 16:17:18 +0000
2651@@ -25,6 +25,7 @@
2652
2653 import com.persistit.DefaultObjectCoder;
2654 import com.persistit.Exchange;
2655+import com.persistit.PersistitUnitTestCase;
2656 import com.persistit.exception.PersistitException;
2657
2658 public class ValueCoderTest2 extends PersistitUnitTestCase {
2659
2660=== modified file 'src/test/java/com/persistit/unit/ValueTest1.java'
2661--- src/test/java/com/persistit/unit/ValueTest1.java 2012-08-15 16:11:36 +0000
2662+++ src/test/java/com/persistit/unit/ValueTest1.java 2012-08-28 16:17:18 +0000
2663@@ -28,6 +28,7 @@
2664
2665 import org.junit.Test;
2666
2667+import com.persistit.PersistitUnitTestCase;
2668 import com.persistit.Value;
2669 import com.persistit.util.Util;
2670
2671
2672=== modified file 'src/test/java/com/persistit/unit/ValueTest2.java'
2673--- src/test/java/com/persistit/unit/ValueTest2.java 2012-08-15 16:11:36 +0000
2674+++ src/test/java/com/persistit/unit/ValueTest2.java 2012-08-28 16:17:18 +0000
2675@@ -30,6 +30,7 @@
2676 import org.junit.Test;
2677
2678 import com.persistit.Exchange;
2679+import com.persistit.PersistitUnitTestCase;
2680 import com.persistit.Value;
2681 import com.persistit.encoding.CollectionValueCoder;
2682 import com.persistit.exception.PersistitException;
2683
2684=== modified file 'src/test/java/com/persistit/unit/ValueTest3.java'
2685--- src/test/java/com/persistit/unit/ValueTest3.java 2012-08-15 16:11:36 +0000
2686+++ src/test/java/com/persistit/unit/ValueTest3.java 2012-08-28 16:17:18 +0000
2687@@ -34,6 +34,7 @@
2688 import com.persistit.DefaultValueCoder;
2689 import com.persistit.Exchange;
2690 import com.persistit.Persistit;
2691+import com.persistit.PersistitUnitTestCase;
2692 import com.persistit.Value;
2693 import com.persistit.encoding.CoderContext;
2694 import com.persistit.encoding.CoderManager;
2695
2696=== modified file 'src/test/java/com/persistit/unit/ValueTest4.java'
2697--- src/test/java/com/persistit/unit/ValueTest4.java 2012-08-15 16:11:36 +0000
2698+++ src/test/java/com/persistit/unit/ValueTest4.java 2012-08-28 16:17:18 +0000
2699@@ -35,6 +35,7 @@
2700 import com.persistit.DefaultValueCoder;
2701 import com.persistit.Exchange;
2702 import com.persistit.Persistit;
2703+import com.persistit.PersistitUnitTestCase;
2704 import com.persistit.Value;
2705 import com.persistit.encoding.CoderContext;
2706 import com.persistit.encoding.CoderManager;
2707
2708=== modified file 'src/test/java/com/persistit/unit/ValueTest5.java'
2709--- src/test/java/com/persistit/unit/ValueTest5.java 2012-08-15 16:11:36 +0000
2710+++ src/test/java/com/persistit/unit/ValueTest5.java 2012-08-28 16:17:18 +0000
2711@@ -22,6 +22,7 @@
2712 import org.junit.Test;
2713
2714 import com.persistit.Exchange;
2715+import com.persistit.PersistitUnitTestCase;
2716 import com.persistit.encoding.CoderManager;
2717 import com.persistit.exception.PersistitException;
2718

Subscribers

People subscribed via source and target branches