use of org.h2.mvstore.Cursor in project h2database by h2database.
the class TestMVStore method testIndexSkip.
private void testIndexSkip() {
MVStore s = openStore(null, 4);
MVMap<Integer, Integer> map = s.openMap("test");
for (int i = 0; i < 100; i += 2) {
map.put(i, 10 * i);
}
Cursor<Integer, Integer> c = map.cursor(50);
// skip must reset the root of the cursor
c.skip(10);
for (int i = 70; i < 100; i += 2) {
assertTrue(c.hasNext());
assertEquals(i, c.next().intValue());
}
assertFalse(c.hasNext());
for (int i = -1; i < 100; i++) {
long index = map.getKeyIndex(i);
if (i < 0 || (i % 2) != 0) {
assertEquals(i < 0 ? -1 : -(i / 2) - 2, index);
} else {
assertEquals(i / 2, index);
}
}
for (int i = -1; i < 60; i++) {
Integer k = map.getKey(i);
if (i < 0 || i >= 50) {
assertNull(k);
} else {
assertEquals(i * 2, k.intValue());
}
}
// skip
c = map.cursor(0);
assertTrue(c.hasNext());
assertEquals(0, c.next().intValue());
c.skip(0);
assertEquals(2, c.next().intValue());
c.skip(1);
assertEquals(6, c.next().intValue());
c.skip(20);
assertEquals(48, c.next().intValue());
c = map.cursor(0);
c.skip(20);
assertEquals(40, c.next().intValue());
c = map.cursor(0);
assertEquals(0, c.next().intValue());
assertEquals(12, map.keyList().indexOf(24));
assertEquals(24, map.keyList().get(12).intValue());
assertEquals(-14, map.keyList().indexOf(25));
assertEquals(map.size(), map.keyList().size());
}
use of org.h2.mvstore.Cursor in project h2database by h2database.
the class RegularTable method addIndex.
@Override
public Index addIndex(Session session, String indexName, int indexId, IndexColumn[] cols, IndexType indexType, boolean create, String indexComment) {
if (indexType.isPrimaryKey()) {
for (IndexColumn c : cols) {
Column column = c.column;
if (column.isNullable()) {
throw DbException.get(ErrorCode.COLUMN_MUST_NOT_BE_NULLABLE_1, column.getName());
}
column.setPrimaryKey(true);
}
}
boolean isSessionTemporary = isTemporary() && !isGlobalTemporary();
if (!isSessionTemporary) {
database.lockMeta(session);
}
Index index;
if (isPersistIndexes() && indexType.isPersistent()) {
int mainIndexColumn;
if (database.isStarting() && database.getPageStore().getRootPageId(indexId) != 0) {
mainIndexColumn = -1;
} else if (!database.isStarting() && mainIndex.getRowCount(session) != 0) {
mainIndexColumn = -1;
} else {
mainIndexColumn = getMainIndexColumn(indexType, cols);
}
if (mainIndexColumn != -1) {
mainIndex.setMainIndexColumn(mainIndexColumn);
index = new PageDelegateIndex(this, indexId, indexName, indexType, mainIndex, create, session);
} else if (indexType.isSpatial()) {
index = new SpatialTreeIndex(this, indexId, indexName, cols, indexType, true, create, session);
} else {
index = new PageBtreeIndex(this, indexId, indexName, cols, indexType, create, session);
}
} else {
if (indexType.isHash()) {
if (cols.length != 1) {
throw DbException.getUnsupportedException("hash indexes may index only one column");
}
if (indexType.isUnique()) {
index = new HashIndex(this, indexId, indexName, cols, indexType);
} else {
index = new NonUniqueHashIndex(this, indexId, indexName, cols, indexType);
}
} else if (indexType.isSpatial()) {
index = new SpatialTreeIndex(this, indexId, indexName, cols, indexType, false, true, session);
} else {
index = new TreeIndex(this, indexId, indexName, cols, indexType);
}
}
if (database.isMultiVersion()) {
index = new MultiVersionIndex(index, this);
}
if (index.needRebuild() && rowCount > 0) {
try {
Index scan = getScanIndex(session);
long remaining = scan.getRowCount(session);
long total = remaining;
Cursor cursor = scan.find(session, null, null);
long i = 0;
int bufferSize = (int) Math.min(rowCount, database.getMaxMemoryRows());
ArrayList<Row> buffer = new ArrayList<>(bufferSize);
String n = getName() + ":" + index.getName();
int t = MathUtils.convertLongToInt(total);
while (cursor.next()) {
database.setProgress(DatabaseEventListener.STATE_CREATE_INDEX, n, MathUtils.convertLongToInt(i++), t);
Row row = cursor.get();
buffer.add(row);
if (buffer.size() >= bufferSize) {
addRowsToIndex(session, buffer, index);
}
remaining--;
}
addRowsToIndex(session, buffer, index);
if (SysProperties.CHECK && remaining != 0) {
DbException.throwInternalError("rowcount remaining=" + remaining + " " + getName());
}
} catch (DbException e) {
getSchema().freeUniqueName(indexName);
try {
index.remove(session);
} catch (DbException e2) {
// this could happen, for example on failure in the storage
// but if that is not the case it means
// there is something wrong with the database
trace.error(e2, "could not remove index");
throw e2;
}
throw e;
}
}
index.setTemporary(isTemporary());
if (index.getCreateSQL() != null) {
index.setComment(indexComment);
if (isSessionTemporary) {
session.addLocalTempTableIndex(index);
} else {
database.addSchemaObject(session, index);
}
}
indexes.add(index);
setModified();
return index;
}
use of org.h2.mvstore.Cursor in project h2database by h2database.
the class JoinBatch method getValue.
/**
* Get the value for the given column.
*
* @param filterId table filter id
* @param column the column
* @return column value for current row
*/
public Value getValue(int filterId, Column column) {
if (current == null) {
return null;
}
Object x = current.row(filterId);
assert x != null;
Row row = current.isRow(filterId) ? (Row) x : ((Cursor) x).get();
int columnId = column.getColumnId();
if (columnId == -1) {
return ValueLong.get(row.getKey());
}
Value value = row.getValue(column.getColumnId());
if (value == null) {
throw DbException.throwInternalError("value is null: " + column + " " + row);
}
return value;
}
use of org.h2.mvstore.Cursor in project h2database by h2database.
the class JoinBatch method start.
private void start() {
// initialize current row
current = new JoinRow(new Object[filters.length]);
// initialize top cursor
Cursor cursor;
if (batchedSubQuery) {
assert viewTopFutureCursor != null;
cursor = get(viewTopFutureCursor);
} else {
// setup usual index cursor
TableFilter f = top.filter;
IndexCursor indexCursor = f.getIndexCursor();
indexCursor.find(f.getSession(), f.getIndexConditions());
cursor = indexCursor;
}
current.updateRow(top.id, cursor, JoinRow.S_NULL, JoinRow.S_CURSOR);
// we need fake first row because batchedNext always will move to the
// next row
JoinRow fake = new JoinRow(null);
fake.next = current;
current = fake;
}
use of org.h2.mvstore.Cursor in project h2database by h2database.
the class JoinBatch method fetchCurrent.
@SuppressWarnings("unchecked")
private void fetchCurrent(final int jfId) {
assert current.prev == null || current.prev.isRow(jfId) : "prev must be already fetched";
assert jfId == 0 || current.isRow(jfId - 1) : "left must be already fetched";
assert !current.isRow(jfId) : "double fetching";
Object x = current.row(jfId);
assert x != null : "x null";
// in case of outer join we don't have any future around empty cursor
boolean newCursor = x == EMPTY_CURSOR;
if (newCursor) {
if (jfId == 0) {
// the top cursor is new and empty, then the whole select will
// not produce any rows
current.drop();
return;
}
} else if (current.isFuture(jfId)) {
// get cursor from a future
x = get((Future<Cursor>) x);
current.updateRow(jfId, x, JoinRow.S_FUTURE, JoinRow.S_CURSOR);
newCursor = true;
}
final JoinFilter jf = filters[jfId];
Cursor c = (Cursor) x;
assert c != null;
JoinFilter join = jf.join;
while (true) {
if (c == null || !c.next()) {
if (newCursor && jf.isOuterJoin()) {
// replace cursor with null-row
current.updateRow(jfId, jf.getNullRow(), JoinRow.S_CURSOR, JoinRow.S_ROW);
c = null;
newCursor = false;
} else {
// cursor is done, drop it
current.drop();
return;
}
}
if (!jf.isOk(c == null)) {
// try another row from the cursor
continue;
}
boolean joinEmpty = false;
if (join != null && !join.collectSearchRows()) {
if (join.isOuterJoin()) {
joinEmpty = true;
} else {
// join will fail, try next row in the cursor
continue;
}
}
if (c != null) {
current = current.copyBehind(jfId);
// update jf, set current row from cursor
current.updateRow(jfId, c.get(), JoinRow.S_CURSOR, JoinRow.S_ROW);
}
if (joinEmpty) {
// update jf.join, set an empty cursor
current.updateRow(join.id, EMPTY_CURSOR, JoinRow.S_NULL, JoinRow.S_CURSOR);
}
return;
}
}
Aggregations