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 org.h2.engine.Session; |
9 | import org.h2.message.DbException; |
10 | import org.h2.result.Row; |
11 | import org.h2.result.SearchRow; |
12 | import org.h2.result.SortOrder; |
13 | import org.h2.store.PageStore; |
14 | import org.h2.table.Column; |
15 | import org.h2.table.IndexColumn; |
16 | import org.h2.table.RegularTable; |
17 | import org.h2.table.TableFilter; |
18 | |
19 | /** |
20 | * An index that delegates indexing to the page data index. |
21 | */ |
22 | public class PageDelegateIndex extends PageIndex { |
23 | |
24 | private final PageDataIndex mainIndex; |
25 | |
26 | public PageDelegateIndex(RegularTable table, int id, String name, |
27 | IndexType indexType, PageDataIndex mainIndex, boolean create, |
28 | Session session) { |
29 | IndexColumn[] cols = IndexColumn.wrap( |
30 | new Column[] { table.getColumn(mainIndex.getMainIndexColumn())}); |
31 | this.initBaseIndex(table, id, name, cols, indexType); |
32 | this.mainIndex = mainIndex; |
33 | if (!database.isPersistent() || id < 0) { |
34 | throw DbException.throwInternalError("" + name); |
35 | } |
36 | PageStore store = database.getPageStore(); |
37 | store.addIndex(this); |
38 | if (create) { |
39 | store.addMeta(this, session); |
40 | } |
41 | } |
42 | |
43 | @Override |
44 | public void add(Session session, Row row) { |
45 | // nothing to do |
46 | } |
47 | |
48 | @Override |
49 | public boolean canFindNext() { |
50 | return false; |
51 | } |
52 | |
53 | @Override |
54 | public boolean canGetFirstOrLast() { |
55 | return true; |
56 | } |
57 | |
58 | @Override |
59 | public void close(Session session) { |
60 | // nothing to do |
61 | } |
62 | |
63 | @Override |
64 | public Cursor find(Session session, SearchRow first, SearchRow last) { |
65 | long min = mainIndex.getKey(first, Long.MIN_VALUE, Long.MIN_VALUE); |
66 | // ifNull is MIN_VALUE as well, because the column is never NULL |
67 | // so avoid returning all rows (returning one row is OK) |
68 | long max = mainIndex.getKey(last, Long.MAX_VALUE, Long.MIN_VALUE); |
69 | return mainIndex.find(session, min, max, false); |
70 | } |
71 | |
72 | @Override |
73 | public Cursor findFirstOrLast(Session session, boolean first) { |
74 | Cursor cursor; |
75 | if (first) { |
76 | cursor = mainIndex.find(session, Long.MIN_VALUE, Long.MAX_VALUE, false); |
77 | } else { |
78 | long x = mainIndex.getLastKey(); |
79 | cursor = mainIndex.find(session, x, x, false); |
80 | } |
81 | cursor.next(); |
82 | return cursor; |
83 | } |
84 | |
85 | @Override |
86 | public Cursor findNext(Session session, SearchRow higherThan, SearchRow last) { |
87 | throw DbException.throwInternalError(); |
88 | } |
89 | |
90 | @Override |
91 | public int getColumnIndex(Column col) { |
92 | if (col.getColumnId() == mainIndex.getMainIndexColumn()) { |
93 | return 0; |
94 | } |
95 | return -1; |
96 | } |
97 | |
98 | @Override |
99 | public double getCost(Session session, int[] masks, TableFilter filter, |
100 | SortOrder sortOrder) { |
101 | return 10 * getCostRangeIndex(masks, mainIndex.getRowCount(session), |
102 | filter, sortOrder); |
103 | } |
104 | |
105 | @Override |
106 | public boolean needRebuild() { |
107 | return false; |
108 | } |
109 | |
110 | @Override |
111 | public void remove(Session session, Row row) { |
112 | // nothing to do |
113 | } |
114 | |
115 | @Override |
116 | public void remove(Session session) { |
117 | mainIndex.setMainIndexColumn(-1); |
118 | session.getDatabase().getPageStore().removeMeta(this, session); |
119 | } |
120 | |
121 | @Override |
122 | public void truncate(Session session) { |
123 | // nothing to do |
124 | } |
125 | |
126 | @Override |
127 | public void checkRename() { |
128 | // ok |
129 | } |
130 | |
131 | @Override |
132 | public long getRowCount(Session session) { |
133 | return mainIndex.getRowCount(session); |
134 | } |
135 | |
136 | @Override |
137 | public long getRowCountApproximation() { |
138 | return mainIndex.getRowCountApproximation(); |
139 | } |
140 | |
141 | @Override |
142 | public long getDiskSpaceUsed() { |
143 | return mainIndex.getDiskSpaceUsed(); |
144 | } |
145 | |
146 | @Override |
147 | public void writeRowCount() { |
148 | // ignore |
149 | } |
150 | |
151 | } |