use of org.h2.dev.util.BinaryArithmeticStream.In in project h2database by h2database.
the class PageStore method redoDelete.
/**
* Redo a delete in a table.
*
* @param tableId the object id of the table
* @param key the key of the row to delete
*/
void redoDelete(int tableId, long key) {
Index index = metaObjects.get(tableId);
PageDataIndex scan = (PageDataIndex) index;
Row row = scan.getRowWithKey(key);
if (row == null || row.getKey() != key) {
trace.error(null, "Entry not found: " + key + " found instead: " + row + " - ignoring");
return;
}
redo(tableId, row, false);
}
use of org.h2.dev.util.BinaryArithmeticStream.In in project h2database by h2database.
the class MVTable method rebuildIndexBlockMerge.
private void rebuildIndexBlockMerge(Session session, MVIndex index) {
if (index instanceof MVSpatialIndex) {
// the spatial index doesn't support multi-way merge sort
rebuildIndexBuffered(session, index);
}
// Read entries in memory, sort them, write to a new map (in sorted
// order); repeat (using a new map for every block of 1 MB) until all
// record are read. Merge all maps to the target (using merge sort;
// duplicates are detected in the target). For randomly ordered data,
// this should use relatively few write operations.
// A possible optimization is: change the buffer size from "row count"
// to "amount of memory", and buffer index keys instead of rows.
Index scan = getScanIndex(session);
long remaining = scan.getRowCount(session);
long total = remaining;
Cursor cursor = scan.find(session, null, null);
long i = 0;
Store store = session.getDatabase().getMvStore();
int bufferSize = database.getMaxMemoryRows() / 2;
ArrayList<Row> buffer = new ArrayList<>(bufferSize);
String n = getName() + ":" + index.getName();
int t = MathUtils.convertLongToInt(total);
ArrayList<String> bufferNames = New.arrayList();
while (cursor.next()) {
Row row = cursor.get();
buffer.add(row);
database.setProgress(DatabaseEventListener.STATE_CREATE_INDEX, n, MathUtils.convertLongToInt(i++), t);
if (buffer.size() >= bufferSize) {
sortRows(buffer, index);
String mapName = store.nextTemporaryMapName();
index.addRowsToBuffer(buffer, mapName);
bufferNames.add(mapName);
buffer.clear();
}
remaining--;
}
sortRows(buffer, index);
if (!bufferNames.isEmpty()) {
String mapName = store.nextTemporaryMapName();
index.addRowsToBuffer(buffer, mapName);
bufferNames.add(mapName);
buffer.clear();
index.addBufferedRows(bufferNames);
} else {
addRowsToIndex(session, buffer, index);
}
if (SysProperties.CHECK && remaining != 0) {
DbException.throwInternalError("rowcount remaining=" + remaining + " " + getName());
}
}
use of org.h2.dev.util.BinaryArithmeticStream.In in project h2database by h2database.
the class MVTable method doLock1.
private void doLock1(Session session, int lockMode, boolean exclusive) {
traceLock(session, exclusive, TraceLockEvent.TRACE_LOCK_REQUESTING_FOR, NO_EXTRA_INFO);
// don't get the current time unless necessary
long max = 0;
boolean checkDeadlock = false;
while (true) {
// if I'm the next one in the queue
if (waitingSessions.getFirst() == session) {
if (doLock2(session, lockMode, exclusive)) {
return;
}
}
if (checkDeadlock) {
ArrayList<Session> sessions = checkDeadlock(session, null, null);
if (sessions != null) {
throw DbException.get(ErrorCode.DEADLOCK_1, getDeadlockDetails(sessions, exclusive));
}
} else {
// check for deadlocks from now on
checkDeadlock = true;
}
long now = System.nanoTime();
if (max == 0) {
// try at least one more time
max = now + TimeUnit.MILLISECONDS.toNanos(session.getLockTimeout());
} else if (now >= max) {
traceLock(session, exclusive, TraceLockEvent.TRACE_LOCK_TIMEOUT_AFTER, NO_EXTRA_INFO + session.getLockTimeout());
throw DbException.get(ErrorCode.LOCK_TIMEOUT_1, getName());
}
try {
traceLock(session, exclusive, TraceLockEvent.TRACE_LOCK_WAITING_FOR, NO_EXTRA_INFO);
if (database.getLockMode() == Constants.LOCK_MODE_TABLE_GC) {
for (int i = 0; i < 20; i++) {
long free = Runtime.getRuntime().freeMemory();
System.gc();
long free2 = Runtime.getRuntime().freeMemory();
if (free == free2) {
break;
}
}
}
// don't wait too long so that deadlocks are detected early
long sleep = Math.min(Constants.DEADLOCK_CHECK, TimeUnit.NANOSECONDS.toMillis(max - now));
if (sleep == 0) {
sleep = 1;
}
getLockSyncObject().wait(sleep);
} catch (InterruptedException e) {
// ignore
}
}
}
use of org.h2.dev.util.BinaryArithmeticStream.In in project h2database by h2database.
the class MVRTreeMap method remove.
@Override
protected synchronized Object remove(Page p, long writeVersion, Object key) {
Object result = null;
if (p.isLeaf()) {
for (int i = 0; i < p.getKeyCount(); i++) {
if (keyType.equals(p.getKey(i), key)) {
result = p.getValue(i);
p.remove(i);
break;
}
}
return result;
}
for (int i = 0; i < p.getKeyCount(); i++) {
if (contains(p, i, key)) {
Page cOld = p.getChildPage(i);
// this will mark the old page as deleted
// so we need to update the parent in any case
// (otherwise the old page might be deleted again)
Page c = cOld.copy(writeVersion);
long oldSize = c.getTotalCount();
result = remove(c, writeVersion, key);
p.setChild(i, c);
if (oldSize == c.getTotalCount()) {
continue;
}
if (c.getTotalCount() == 0) {
// this child was deleted
p.remove(i);
if (p.getKeyCount() == 0) {
c.removePage();
}
break;
}
Object oldBounds = p.getKey(i);
if (!keyType.isInside(key, oldBounds)) {
p.setKey(i, getBounds(c));
}
break;
}
}
return result;
}
use of org.h2.dev.util.BinaryArithmeticStream.In in project h2database by h2database.
the class TcpServerThread method run.
@Override
public void run() {
try {
transfer.init();
trace("Connect");
// and a list of allowed clients
try {
Socket socket = transfer.getSocket();
if (socket == null) {
// the transfer is already closed, prevent NPE in TcpServer#allow(Socket)
return;
}
if (!server.allow(transfer.getSocket())) {
throw DbException.get(ErrorCode.REMOTE_CONNECTION_NOT_ALLOWED);
}
int minClientVersion = transfer.readInt();
int maxClientVersion = transfer.readInt();
if (maxClientVersion < Constants.TCP_PROTOCOL_VERSION_MIN_SUPPORTED) {
throw DbException.get(ErrorCode.DRIVER_VERSION_ERROR_2, "" + clientVersion, "" + Constants.TCP_PROTOCOL_VERSION_MIN_SUPPORTED);
} else if (minClientVersion > Constants.TCP_PROTOCOL_VERSION_MAX_SUPPORTED) {
throw DbException.get(ErrorCode.DRIVER_VERSION_ERROR_2, "" + clientVersion, "" + Constants.TCP_PROTOCOL_VERSION_MAX_SUPPORTED);
}
if (maxClientVersion >= Constants.TCP_PROTOCOL_VERSION_MAX_SUPPORTED) {
clientVersion = Constants.TCP_PROTOCOL_VERSION_MAX_SUPPORTED;
} else {
clientVersion = maxClientVersion;
}
transfer.setVersion(clientVersion);
String db = transfer.readString();
String originalURL = transfer.readString();
if (db == null && originalURL == null) {
String targetSessionId = transfer.readString();
int command = transfer.readInt();
stop = true;
if (command == SessionRemote.SESSION_CANCEL_STATEMENT) {
// cancel a running statement
int statementId = transfer.readInt();
server.cancelStatement(targetSessionId, statementId);
} else if (command == SessionRemote.SESSION_CHECK_KEY) {
// check if this is the correct server
db = server.checkKeyAndGetDatabaseName(targetSessionId);
if (!targetSessionId.equals(db)) {
transfer.writeInt(SessionRemote.STATUS_OK);
} else {
transfer.writeInt(SessionRemote.STATUS_ERROR);
}
}
}
String baseDir = server.getBaseDir();
if (baseDir == null) {
baseDir = SysProperties.getBaseDir();
}
db = server.checkKeyAndGetDatabaseName(db);
ConnectionInfo ci = new ConnectionInfo(db);
ci.setOriginalURL(originalURL);
ci.setUserName(transfer.readString());
ci.setUserPasswordHash(transfer.readBytes());
ci.setFilePasswordHash(transfer.readBytes());
int len = transfer.readInt();
for (int i = 0; i < len; i++) {
ci.setProperty(transfer.readString(), transfer.readString());
}
// override client's requested properties with server settings
if (baseDir != null) {
ci.setBaseDir(baseDir);
}
if (server.getIfExists()) {
ci.setProperty("IFEXISTS", "TRUE");
}
transfer.writeInt(SessionRemote.STATUS_OK);
transfer.writeInt(clientVersion);
transfer.flush();
if (clientVersion >= Constants.TCP_PROTOCOL_VERSION_13) {
if (ci.getFilePasswordHash() != null) {
ci.setFileEncryptionKey(transfer.readBytes());
}
}
session = Engine.getInstance().createSession(ci);
transfer.setSession(session);
server.addConnection(threadId, originalURL, ci.getUserName());
trace("Connected");
} catch (Throwable e) {
sendError(e);
stop = true;
}
while (!stop) {
try {
process();
} catch (Throwable e) {
sendError(e);
}
}
trace("Disconnect");
} catch (Throwable e) {
server.traceError(e);
} finally {
close();
}
}
Aggregations