Merge lp:~pbeaman/akiban-persistit/fix-1023549-traverse-wrong into lp:akiban-persistit

Proposed by Peter Beaman
Status: Merged
Approved by: Peter Beaman
Approved revision: 382
Merged at revision: 382
Proposed branch: lp:~pbeaman/akiban-persistit/fix-1023549-traverse-wrong
Merge into: lp:akiban-persistit
Diff against target: 95 lines (+28/-7)
2 files modified
src/main/java/com/persistit/Exchange.java (+16/-7)
src/test/java/com/persistit/unit/ExchangeTest.java (+12/-0)
To merge this branch: bzr merge lp:~pbeaman/akiban-persistit/fix-1023549-traverse-wrong
Reviewer Review Type Date Requested Status
Nathan Williams Approve
Review via email: mp+129744@code.launchpad.net

Description of the change

Fix bug 1023549: traverse(LTEQ, false, 0) incorrectly returns true.

The bug resulted from some failure to handle a couple of cases in the Exchange#traverse method. Proposed code sets the "matches" variable on each applicable code path. Also fixes an infinite loop in code path for travers(EQ, false, 0) where the key provided is for an MVV that has no visible versions.

Currently Akiban Server works around this problem: see

   com.akiban.server.store.PersistitStore#keyExistsInIndexcom.akiban.server.store

With this proposed branch I have successfully tested a version of Akiban Server in which the deep flag is set to false as originally intended.

Since the changes are subtle and Akiban Server currently works around this problem I recommend holding this proposal out of 3.2.0.

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

Looks good.

Holding off big-A until version bump gets through.

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

Pushing this through since 3.2.1 update is now merged.

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/Exchange.java'
2--- src/main/java/com/persistit/Exchange.java 2012-10-08 19:48:22 +0000
3+++ src/main/java/com/persistit/Exchange.java 2012-10-15 19:30:28 +0000
4@@ -2053,7 +2053,7 @@
5 for (;;) {
6 ++_keysVisitedDuringTraverse;
7 final LevelCache lc = _levelCache[0];
8- boolean matches = false;
9+ boolean matches;
10 //
11 // Optimal path - pick up the buffer and location left
12 // by previous operation.
13@@ -2103,9 +2103,9 @@
14 if (edge && (foundAt & EXACT_MASK) != 0) {
15 matches = true;
16 } else if (edge && !deep && Buffer.decodeDepth(foundAt) == index) {
17- // None
18+ matches = true;
19 } else if (direction == EQ) {
20- // None
21+ matches = false;
22 } else {
23 edge = false;
24 foundAt = buffer.traverse(_key, direction, foundAt);
25@@ -2123,7 +2123,12 @@
26 buffer = rightSibling;
27 checkPageType(buffer, PAGE_TYPE_DATA, false);
28 foundAt = buffer.traverse(_key, direction, buffer.toKeyBlock(0));
29+ matches = !buffer.isAfterRightEdge(foundAt);
30+ } else {
31+ matches = false;
32 }
33+ } else {
34+ matches = true;
35 }
36
37 //
38@@ -2164,7 +2169,7 @@
39 // finishing
40
41 if (reverse && _key.isLeftEdge() || !reverse && _key.isRightEdge() || stopDueToKeyDepth) {
42- // None
43+ matches = false;
44 } else {
45 if (deep) {
46 matches |= direction != EQ;
47@@ -2186,7 +2191,7 @@
48 parentIndex = 0;
49 }
50
51- matches = (spareKey.compareKeyFragment(_key, 0, parentIndex) == 0);
52+ matches &= (spareKey.compareKeyFragment(_key, 0, parentIndex) == 0);
53
54 if (matches) {
55 index = _key.nextElementIndex(parentIndex);
56@@ -2201,10 +2206,14 @@
57 //
58 if (!isVisibleMatch) {
59 nudged = false;
60- nudgeForMVCC = (direction == GTEQ || direction == LTEQ);
61 buffer.release();
62 buffer = null;
63- continue;
64+ if (direction == EQ) {
65+ matches = false;
66+ } else {
67+ nudgeForMVCC = (direction == GTEQ || direction == LTEQ);
68+ continue;
69+ }
70 }
71 //
72 // It was a niece or nephew, record non-exact
73
74=== modified file 'src/test/java/com/persistit/unit/ExchangeTest.java'
75--- src/test/java/com/persistit/unit/ExchangeTest.java 2012-10-08 17:59:29 +0000
76+++ src/test/java/com/persistit/unit/ExchangeTest.java 2012-10-15 19:30:28 +0000
77@@ -424,6 +424,18 @@
78 assertEquals("Should be false", false, ex.traverse(Key.LT, deep, -1));
79 ex.clear();
80
81+ ex.append(1);
82+ assertEquals("Should be false", false, ex.traverse(Key.EQ, deep, -1));
83+ ex.clear().append(1);
84+ assertEquals("Should be false", false, ex.traverse(Key.GTEQ, deep, -1));
85+ ex.clear().append(1);
86+ assertEquals("Should be false", false, ex.traverse(Key.GT, deep, -1));
87+ ex.clear().append(1);
88+ assertEquals("Should be false", false, ex.traverse(Key.LTEQ, deep, -1));
89+ ex.clear().append(1);
90+ assertEquals("Should be false", false, ex.traverse(Key.LT, deep, -1));
91+ ex.clear().append(1);
92+
93 ex.append(1).append(2).store();
94 ex.clear().append(Key.BEFORE);
95 assertEquals("Should be false", false, ex.traverse(Key.EQ, deep, -1));

Subscribers

People subscribed via source and target branches