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

Proposed by Peter Beaman
Status: Merged
Merged at revision: 314
Proposed branch: lp:~pbeaman/akiban-persistit/fix_1006576_long_record_pruning
Merge into: lp:akiban-persistit
Diff against target: 118 lines (+42/-10)
3 files modified
src/main/java/com/persistit/Buffer.java (+1/-0)
src/main/java/com/persistit/Value.java (+20/-10)
src/test/java/com/persistit/MVCCPruneBufferTest.java (+21/-0)
To merge this branch: bzr merge lp:~pbeaman/akiban-persistit/fix_1006576_long_record_pruning
Reviewer Review Type Date Requested Status
Akiban Build User Needs Fixing
Nathan Williams Needs Information
Review via email: mp+108091@code.launchpad.net

Description of the change

Fix a critical bug that was added with lp:~pbeaman/akiban-persistit/fix_945244_incomplete_pruning.

New code added with that branch failed to restore a Value to normal, non-long-record-mode after using it. When that value is used again, it is in an incorrect state.

This branch fixes the specific problem and adds a test to cover it.

Longer term the handling of "long record mode" in the Value object is murky at best and will be cleaned up when we refactor the Exchange class.

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

Ack, nasty one.

I think this is right. I said that last time, but I've believed it both times!

About the test:
Do we want the pollInterval to be -1 instead of MAX? If correct as-is, feel free to Approve.

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

Yes, -1 is correct. Confusion was caused by my earlier mistake when I set some of these to MAX. I'll press the big-A button.

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

There were 2 failures during build/test:

* job server-mt failed at build number 1747: http://172.16.20.104:8080/job/server-mt/1747/

* view must-pass failed: server-mt is red

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

All the way through and then network hiccup on server-mt.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/main/java/com/persistit/Buffer.java'
--- src/main/java/com/persistit/Buffer.java 2012-05-25 18:50:59 +0000
+++ src/main/java/com/persistit/Buffer.java 2012-05-31 02:25:21 +0000
@@ -3729,6 +3729,7 @@
3729 // Rewrite the tail block header3729 // Rewrite the tail block header
3730 putInt(tail, encodeTailBlock(newTailSize, klength));3730 putInt(tail, encodeTailBlock(newTailSize, klength));
3731 valueByte = newSize > 0 ? _bytes[offset] & 0xFF : -1;3731 valueByte = newSize > 0 ? _bytes[offset] & 0xFF : -1;
3732 value.changeLongRecordMode(false);
3732 }3733 }
3733 }3734 }
3734 boolean prunedAntiValue = pruneAntiValue(valueByte, p, tree);3735 boolean prunedAntiValue = pruneAntiValue(valueByte, p, tree);
37353736
=== modified file 'src/main/java/com/persistit/Value.java'
--- src/main/java/com/persistit/Value.java 2012-05-25 18:50:59 +0000
+++ src/main/java/com/persistit/Value.java 2012-05-31 02:25:21 +0000
@@ -683,9 +683,12 @@
683 * The <code>Value</code> to which state should be copied.683 * The <code>Value</code> to which state should be copied.
684 */684 */
685 public void copyTo(Value target) {685 public void copyTo(Value target) {
686 if (target == this)686 if (target == this) {
687 return;687 return;
688 target.changeLongRecordMode(isLongRecordMode());688 }
689 Debug.$assert0.t(!isLongRecordMode());
690 Debug.$assert0.t(!target.isLongRecordMode());
691
689 target.ensureFit(_size);692 target.ensureFit(_size);
690 System.arraycopy(_bytes, 0, target._bytes, 0, _size);693 System.arraycopy(_bytes, 0, target._bytes, 0, _size);
691 target._size = _size;694 target._size = _size;
@@ -775,12 +778,14 @@
775 * larger array.778 * larger array.
776 */779 */
777 public boolean ensureFit(int length) {780 public boolean ensureFit(int length) {
781
778 if (length > 0 && length * SIZE_GROWTH_DENOMINATOR < _size) {782 if (length > 0 && length * SIZE_GROWTH_DENOMINATOR < _size) {
779 length = _size / SIZE_GROWTH_DENOMINATOR;783 length = _size / SIZE_GROWTH_DENOMINATOR;
780 }784 }
781 final int newSize = _size + length;785 final int newSize = _size + length;
782 if (newSize <= _bytes.length)786 if (newSize <= _bytes.length) {
783 return false;787 return false;
788 }
784 int newArraySize = ((newSize + SIZE_GRANULARITY - 1) / SIZE_GRANULARITY) * SIZE_GRANULARITY;789 int newArraySize = ((newSize + SIZE_GRANULARITY - 1) / SIZE_GRANULARITY) * SIZE_GRANULARITY;
785 if (newArraySize > _maximumSize)790 if (newArraySize > _maximumSize)
786 newArraySize = _maximumSize;791 newArraySize = _maximumSize;
@@ -4064,6 +4069,7 @@
40644069
4065 void changeLongRecordMode(boolean mode) {4070 void changeLongRecordMode(boolean mode) {
4066 if (mode != _longMode) {4071 if (mode != _longMode) {
4072
4067 if (_longBytes == null || _longBytes.length < Buffer.LONGREC_SIZE) {4073 if (_longBytes == null || _longBytes.length < Buffer.LONGREC_SIZE) {
4068 _longBytes = new byte[Buffer.LONGREC_SIZE];4074 _longBytes = new byte[Buffer.LONGREC_SIZE];
4069 _longSize = Buffer.LONGREC_SIZE;4075 _longSize = Buffer.LONGREC_SIZE;
@@ -4080,11 +4086,15 @@
4080 _longSize = tempSize;4086 _longSize = tempSize;
4081 _longMode = mode;4087 _longMode = mode;
40824088
4083 if (mode) {4089 assertLongRecordModeIsCorrect();
4084 Debug.$assert1.t(_bytes.length == Buffer.LONGREC_SIZE);4090 }
4085 } else {4091 }
4086 Debug.$assert1.t(_longBytes.length == Buffer.LONGREC_SIZE);4092
4087 }4093 private void assertLongRecordModeIsCorrect() {
4094 if (_longMode) {
4095 Debug.$assert1.t(_bytes.length == Buffer.LONGREC_SIZE);
4096 } else {
4097 Debug.$assert1.t(_longBytes == null || _longBytes.length == Buffer.LONGREC_SIZE);
4088 }4098 }
4089 }4099 }
40904100
@@ -5071,8 +5081,8 @@
5071 }5081 }
50725082
5073 /**5083 /**
5074 * Construct a list of <code>Version</code> objects, each denoting one of the5084 * Construct a list of <code>Version</code> objects, each denoting one of
5075 * multi-value versions currently held in this Value object.5085 * the multi-value versions currently held in this Value object.
5076 * 5086 *
5077 * @return the list of <code>Version<code>s5087 * @return the list of <code>Version<code>s
5078 * @throws PersistitException5088 * @throws PersistitException
50795089
=== modified file 'src/test/java/com/persistit/MVCCPruneBufferTest.java'
--- src/test/java/com/persistit/MVCCPruneBufferTest.java 2012-05-25 18:50:59 +0000
+++ src/test/java/com/persistit/MVCCPruneBufferTest.java 2012-05-31 02:25:21 +0000
@@ -183,6 +183,27 @@
183 ex1.prune();183 ex1.prune();
184 assertTrue("Should no longer be an MVV", !ex1.isValueLongMVV());184 assertTrue("Should no longer be an MVV", !ex1.isValueLongMVV());
185 }185 }
186
187 @Test
188 public void induceBug1006576() throws Exception {
189 _persistit.getCleanupManager().setPollInterval(Long.MAX_VALUE);
190 trx1.begin();
191 storeLongMVV(ex1, "x");
192 storeLongMVV(ex1, "y");
193 trx1.commit();
194 trx1.end();
195 _persistit.getTransactionIndex().cleanup();
196 ex1.prune();
197 assertTrue("Should no longer be an MVV", !ex1.isValueLongMVV());
198
199 trx1.begin();
200 storeLongMVV(ex1, "x");
201 trx1.commit();
202 trx1.end();
203 _persistit.getTransactionIndex().cleanup();
204 ex1.prune();
205 assertTrue("Should no longer be an MVV", !ex1.isValueLongMVV());
206 }
186207
187 @Test208 @Test
188 public void testComplexPruning() throws Exception {209 public void testComplexPruning() throws Exception {

Subscribers

People subscribed via source and target branches