File D:\maven-qcr-plugin-testsunitaires\qcr4java\h2-1.3.170-sources\target\site\qc\lecode\index\PageData.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.engine.Session;
10 import org.h2.result.Row;
11 import org.h2.store.Data;
12 import org.h2.store.Page;
13
14 /**
15 * A page that contains data rows.
16 */
17 abstract class PageData extends Page {
18
19 /**
20 * The position of the parent page id.
21 */
22 static final int START_PARENT = 3;
23
24 /**
25 * This is a root page.
26 */
27 static final int ROOT = 0;
28
29 /**
30 * Indicator that the row count is not known.
31 */
32 static final int UNKNOWN_ROWCOUNT = -1;
33
34 /**
35 * The index.
36 */
37 protected final PageDataIndex index;
38
39 /**
40 * The page number of the parent.
41 */
42 protected int parentPageId;
43
44 /**
45 * The data page.
46 */
47 protected final Data data;
48
49 /**
50 * The number of entries.
51 */
52 protected int entryCount;
53
54 /**
55 * The row keys.
56 */
57 protected long[] keys;
58
59 /**
60 * Whether the data page is up-to-date.
61 */
62 protected boolean written;
63
64 /**
65 * The estimated heap memory used by this object, in number of double words
66 * (4 bytes each).
67 */
68 private final int memoryEstimated;
69
70 PageData(PageDataIndex index, int pageId, Data data) {
71 this.index = index;
72 this.data = data;
73 setPos(pageId);
74 memoryEstimated = index.getMemoryPerPage();
75 }
76
77 /**
78 * Get the real row count. If required, this will read all child pages.
79 *
80 * @return the row count
81 */
82 abstract int getRowCount();
83
84 /**
85 * Set the stored row count. This will write the page.
86 *
87 * @param rowCount the stored row count
88 */
89 abstract void setRowCountStored(int rowCount);
90
91 /**
92 * Find an entry by key.
93 *
94 * @param key the key (may not exist)
95 * @return the matching or next index
96 */
97 int find(long key) {
98 int l = 0, r = entryCount;
99 while (l < r) {
100 int i = (l + r) >>> 1;
101 long k = keys[i];
102 if (k == key) {
103 return i;
104 } else if (k > key) {
105 r = i;
106 } else {
107 l = i + 1;
108 }
109 }
110 return l;
111 }
112
113 /**
114 * Add a row if possible. If it is possible this method returns -1, otherwise
115 * the split point. It is always possible to add one row.
116 *
117 * @param row the now to add
118 * @return the split point of this page, or -1 if no split is required
119 */
120 abstract int addRowTry(Row row);
121
122 /**
123 * Get a cursor.
124 *
125 * @param session the session
126 * @param minKey the smallest key
127 * @param maxKey the largest key
128 * @param multiVersion if the delta should be used
129 * @return the cursor
130 */
131 abstract Cursor find(Session session, long minKey, long maxKey, boolean multiVersion);
132
133 /**
134 * Get the key at this position.
135 *
136 * @param at the index
137 * @return the key
138 */
139 long getKey(int at) {
140 return keys[at];
141 }
142
143 /**
144 * Split the index page at the given point.
145 *
146 * @param splitPoint the index where to split
147 * @return the new page that contains about half the entries
148 */
149 abstract PageData split(int splitPoint);
150
151 /**
152 * Change the page id.
153 *
154 * @param id the new page id
155 */
156 void setPageId(int id) {
157 int old = getPos();
158 index.getPageStore().removeRecord(getPos());
159 setPos(id);
160 index.getPageStore().logUndo(this, null);
161 remapChildren(old);
162 }
163
164 /**
165 * Get the last key of a page.
166 *
167 * @return the last key
168 */
169 abstract long getLastKey();
170
171 /**
172 * Get the first child leaf page of a page.
173 *
174 * @return the page
175 */
176 abstract PageDataLeaf getFirstLeaf();
177
178 /**
179 * Change the parent page id.
180 *
181 * @param id the new parent page id
182 */
183 void setParentPageId(int id) {
184 index.getPageStore().logUndo(this, data);
185 parentPageId = id;
186 if (written) {
187 changeCount = index.getPageStore().getChangeCount();
188 data.setInt(START_PARENT, parentPageId);
189 }
190 }
191
192 /**
193 * Update the parent id of all children.
194 *
195 * @param old the previous position
196 */
197 abstract void remapChildren(int old);
198
199 /**
200 * Remove a row.
201 *
202 * @param key the key of the row to remove
203 * @return true if this page is now empty
204 */
205 abstract boolean remove(long key);
206
207 /**
208 * Free this page and all child pages.
209 */
210 abstract void freeRecursive();
211
212 /**
213 * Get the row for the given key.
214 *
215 * @param key the key
216 * @return the row
217 */
218 abstract Row getRowWithKey(long key);
219
220 /**
221 * Get the estimated heap memory size.
222 *
223 * @return number of double words (4 bytes each)
224 */
225 public int getMemory() {
226 // need to always return the same value for the same object (otherwise
227 // the cache size would change after adding and then removing the same
228 // page from the cache) but index.getMemoryPerPage() can adopt according
229 // to how much memory a row needs on average
230 return memoryEstimated;
231 }
232
233 int getParentPageId() {
234 return parentPageId;
235 }
236
237 public boolean canRemove() {
238 if (changeCount >= index.getPageStore().getChangeCount()) {
239 return false;
240 }
241 return true;
242 }
243
244 }
245