File D:\maven-qcr-plugin-testsunitaires\qcr4java\h2-1.3.170-sources\target\site\qc\lecode\index\MultiVersionCursor.java.html

1 /*
2 * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
3 * Version 1.0, and under the Eclipse Public License, Version 1.0
4 * (http://h2database.com/html/license.html).
5 * Initial Developer: H2 Group
6 */
7 package org.h2.index;
8
9 import org.h2.constant.SysProperties;
10 import org.h2.engine.Session;
11 import org.h2.message.DbException;
12 import org.h2.result.Row;
13 import org.h2.result.SearchRow;
14 import org.h2.util.MathUtils;
15
16 /**
17 * The cursor implementation for the multi-version index.
18 */
19 public class MultiVersionCursor implements Cursor {
20
21 private final MultiVersionIndex index;
22 private final Session session;
23 private final Cursor baseCursor, deltaCursor;
24 private final Object sync;
25 private SearchRow baseRow;
26 private Row deltaRow;
27 private boolean onBase;
28 private boolean end;
29 private boolean needNewDelta, needNewBase;
30 private boolean reverse;
31
32 MultiVersionCursor(Session session, MultiVersionIndex index, Cursor base, Cursor delta, Object sync) {
33 this.session = session;
34 this.index = index;
35 this.baseCursor = base;
36 this.deltaCursor = delta;
37 this.sync = sync;
38 needNewDelta = true;
39 needNewBase = true;
40 }
41
42 /**
43 * Load the current row.
44 */
45 void loadCurrent() {
46 synchronized (sync) {
47 baseRow = baseCursor.getSearchRow();
48 deltaRow = deltaCursor.get();
49 needNewDelta = false;
50 needNewBase = false;
51 }
52 }
53
54 private void loadNext(boolean base) {
55 synchronized (sync) {
56 if (base) {
57 if (step(baseCursor)) {
58 baseRow = baseCursor.getSearchRow();
59 } else {
60 baseRow = null;
61 }
62 } else {
63 if (step(deltaCursor)) {
64 deltaRow = deltaCursor.get();
65 } else {
66 deltaRow = null;
67 }
68 }
69 }
70 }
71
72 private boolean step(Cursor cursor) {
73 return reverse ? cursor.previous() : cursor.next();
74 }
75
76 public Row get() {
77 synchronized (sync) {
78 if (end) {
79 return null;
80 }
81 return onBase ? baseCursor.get() : deltaCursor.get();
82 }
83 }
84
85 public SearchRow getSearchRow() {
86 synchronized (sync) {
87 if (end) {
88 return null;
89 }
90 return onBase ? baseCursor.getSearchRow() : deltaCursor.getSearchRow();
91 }
92 }
93
94 public boolean next() {
95 synchronized (sync) {
96 if (SysProperties.CHECK && end) {
97 DbException.throwInternalError();
98 }
99 while (true) {
100 if (needNewDelta) {
101 loadNext(false);
102 needNewDelta = false;
103 }
104 if (needNewBase) {
105 loadNext(true);
106 needNewBase = false;
107 }
108 if (deltaRow == null) {
109 if (baseRow == null) {
110 end = true;
111 return false;
112 }
113 onBase = true;
114 needNewBase = true;
115 return true;
116 }
117 int sessionId = deltaRow.getSessionId();
118 boolean isThisSession = sessionId == session.getId();
119 boolean isDeleted = deltaRow.isDeleted();
120 if (isThisSession && isDeleted) {
121 needNewDelta = true;
122 continue;
123 }
124 if (baseRow == null) {
125 if (isDeleted) {
126 if (isThisSession) {
127 end = true;
128 return false;
129 }
130 // the row was deleted by another session: return it
131 onBase = false;
132 needNewDelta = true;
133 return true;
134 }
135 DbException.throwInternalError();
136 }
137 int compare = index.compareRows(deltaRow, baseRow);
138 if (compare == 0) {
139 // can't use compareKeys because the
140 // version would be compared as well
141 long k1 = deltaRow.getKey();
142 long k2 = baseRow.getKey();
143 compare = MathUtils.compareLong(k1, k2);
144 }
145 if (compare == 0) {
146 if (isDeleted) {
147 if (isThisSession) {
148 DbException.throwInternalError();
149 }
150 // another session updated the row
151 } else {
152 if (isThisSession) {
153 onBase = false;
154 needNewBase = true;
155 needNewDelta = true;
156 return true;
157 }
158 // another session inserted the row: ignore
159 needNewBase = true;
160 needNewDelta = true;
161 continue;
162 }
163 }
164 if (compare > 0) {
165 onBase = true;
166 needNewBase = true;
167 return true;
168 }
169 onBase = false;
170 needNewDelta = true;
171 return true;
172 }
173 }
174 }
175
176 public boolean previous() {
177 reverse = true;
178 try {
179 return next();
180 } finally {
181 reverse = false;
182 }
183 }
184
185 }
186