1 | /* |
2 | * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0, |
3 | * and the EPL 1.0 (http://h2database.com/html/license.html). |
4 | * Initial Developer: H2 Group |
5 | */ |
6 | package org.h2.index; |
7 | |
8 | import java.util.Iterator; |
9 | import org.h2.engine.Session; |
10 | import org.h2.message.DbException; |
11 | import org.h2.result.Row; |
12 | import org.h2.result.SearchRow; |
13 | |
14 | /** |
15 | * The cursor implementation for the page scan index. |
16 | */ |
17 | class PageDataCursor implements Cursor { |
18 | |
19 | private PageDataLeaf current; |
20 | private int idx; |
21 | private final long maxKey; |
22 | private Row row; |
23 | private final boolean multiVersion; |
24 | private final Session session; |
25 | private Iterator<Row> delta; |
26 | |
27 | PageDataCursor(Session session, PageDataLeaf current, int idx, long maxKey, |
28 | boolean multiVersion) { |
29 | this.current = current; |
30 | this.idx = idx; |
31 | this.maxKey = maxKey; |
32 | this.multiVersion = multiVersion; |
33 | this.session = session; |
34 | if (multiVersion) { |
35 | delta = current.index.getDelta(); |
36 | } |
37 | } |
38 | |
39 | @Override |
40 | public Row get() { |
41 | return row; |
42 | } |
43 | |
44 | @Override |
45 | public SearchRow getSearchRow() { |
46 | return get(); |
47 | } |
48 | |
49 | @Override |
50 | public boolean next() { |
51 | if (!multiVersion) { |
52 | nextRow(); |
53 | return checkMax(); |
54 | } |
55 | while (true) { |
56 | if (delta != null) { |
57 | if (!delta.hasNext()) { |
58 | delta = null; |
59 | row = null; |
60 | continue; |
61 | } |
62 | row = delta.next(); |
63 | if (!row.isDeleted() || row.getSessionId() == session.getId()) { |
64 | continue; |
65 | } |
66 | } else { |
67 | nextRow(); |
68 | if (row != null && row.getSessionId() != 0 && |
69 | row.getSessionId() != session.getId()) { |
70 | continue; |
71 | } |
72 | } |
73 | break; |
74 | } |
75 | return checkMax(); |
76 | } |
77 | |
78 | private boolean checkMax() { |
79 | if (row != null) { |
80 | if (maxKey != Long.MAX_VALUE) { |
81 | long x = current.index.getKey(row, Long.MAX_VALUE, Long.MAX_VALUE); |
82 | if (x > maxKey) { |
83 | row = null; |
84 | return false; |
85 | } |
86 | } |
87 | return true; |
88 | } |
89 | return false; |
90 | } |
91 | |
92 | private void nextRow() { |
93 | if (idx >= current.getEntryCount()) { |
94 | current = current.getNextPage(); |
95 | idx = 0; |
96 | if (current == null) { |
97 | row = null; |
98 | return; |
99 | } |
100 | } |
101 | row = current.getRowAt(idx); |
102 | idx++; |
103 | } |
104 | |
105 | @Override |
106 | public boolean previous() { |
107 | throw DbException.throwInternalError(); |
108 | } |
109 | |
110 | } |