use of org.h2.dev.util.BinaryArithmeticStream.In in project h2database by h2database.
the class LobStorageBackend method init.
@Override
public void init() {
if (init) {
return;
}
synchronized (database) {
// thread
if (init) {
return;
}
init = true;
conn = database.getLobConnectionForRegularUse();
JdbcConnection initConn = database.getLobConnectionForInit();
try {
Statement stat = initConn.createStatement();
// stat.execute("SET UNDO_LOG 0");
// stat.execute("SET REDO_LOG_BINARY 0");
boolean create = true;
PreparedStatement prep = initConn.prepareStatement("SELECT ZERO() FROM INFORMATION_SCHEMA.COLUMNS WHERE " + "TABLE_SCHEMA=? AND TABLE_NAME=? AND COLUMN_NAME=?");
prep.setString(1, "INFORMATION_SCHEMA");
prep.setString(2, "LOB_MAP");
prep.setString(3, "POS");
ResultSet rs;
rs = prep.executeQuery();
if (rs.next()) {
prep = initConn.prepareStatement("SELECT ZERO() FROM INFORMATION_SCHEMA.TABLES WHERE " + "TABLE_SCHEMA=? AND TABLE_NAME=?");
prep.setString(1, "INFORMATION_SCHEMA");
prep.setString(2, "LOB_DATA");
rs = prep.executeQuery();
if (rs.next()) {
create = false;
}
}
if (create) {
stat.execute("CREATE CACHED TABLE IF NOT EXISTS " + LOBS + "(ID BIGINT PRIMARY KEY, BYTE_COUNT BIGINT, TABLE INT) HIDDEN");
stat.execute("CREATE INDEX IF NOT EXISTS " + "INFORMATION_SCHEMA.INDEX_LOB_TABLE ON " + LOBS + "(TABLE)");
stat.execute("CREATE CACHED TABLE IF NOT EXISTS " + LOB_MAP + "(LOB BIGINT, SEQ INT, POS BIGINT, HASH INT, " + "BLOCK BIGINT, PRIMARY KEY(LOB, SEQ)) HIDDEN");
stat.execute("ALTER TABLE " + LOB_MAP + " RENAME TO " + LOB_MAP + " HIDDEN");
stat.execute("ALTER TABLE " + LOB_MAP + " ADD IF NOT EXISTS POS BIGINT BEFORE HASH");
// TODO the column name OFFSET was used in version 1.3.156,
// so this can be remove in a later version
stat.execute("ALTER TABLE " + LOB_MAP + " DROP COLUMN IF EXISTS \"OFFSET\"");
stat.execute("CREATE INDEX IF NOT EXISTS " + "INFORMATION_SCHEMA.INDEX_LOB_MAP_DATA_LOB ON " + LOB_MAP + "(BLOCK, LOB)");
stat.execute("CREATE CACHED TABLE IF NOT EXISTS " + LOB_DATA + "(BLOCK BIGINT PRIMARY KEY, COMPRESSED INT, DATA BINARY) HIDDEN");
}
rs = stat.executeQuery("SELECT MAX(BLOCK) FROM " + LOB_DATA);
rs.next();
nextBlock = rs.getLong(1) + 1;
stat.close();
} catch (SQLException e) {
throw DbException.convert(e);
}
}
}
use of org.h2.dev.util.BinaryArithmeticStream.In in project h2database by h2database.
the class LobStorageMap method createLob.
private ValueLobDb createLob(InputStream in, int type) throws IOException {
byte[] streamStoreId;
try {
streamStoreId = streamStore.put(in);
} catch (Exception e) {
throw DbException.convertToIOException(e);
}
long lobId = generateLobId();
long length = streamStore.length(streamStoreId);
int tableId = LobStorageFrontend.TABLE_TEMP;
Object[] value = { streamStoreId, tableId, length, 0 };
lobMap.put(lobId, value);
Object[] key = { streamStoreId, lobId };
refMap.put(key, Boolean.TRUE);
ValueLobDb lob = ValueLobDb.create(type, database, tableId, lobId, null, length);
if (TRACE) {
trace("create " + tableId + "/" + lobId);
}
return lob;
}
use of org.h2.dev.util.BinaryArithmeticStream.In in project h2database by h2database.
the class LobStorageMap method createClob.
@Override
public Value createClob(Reader reader, long maxLength) {
init();
int type = Value.CLOB;
try {
// we multiple by 3 here to get the worst-case size in bytes
if (maxLength != -1 && maxLength * 3 <= database.getMaxLengthInplaceLob()) {
char[] small = new char[(int) maxLength];
int len = IOUtils.readFully(reader, small, (int) maxLength);
if (len > maxLength) {
throw new IllegalStateException("len > blobLength, " + len + " > " + maxLength);
}
byte[] utf8 = new String(small, 0, len).getBytes(StandardCharsets.UTF_8);
if (utf8.length > database.getMaxLengthInplaceLob()) {
throw new IllegalStateException("len > maxinplace, " + utf8.length + " > " + database.getMaxLengthInplaceLob());
}
return ValueLobDb.createSmallLob(type, utf8);
}
if (maxLength < 0) {
maxLength = Long.MAX_VALUE;
}
CountingReaderInputStream in = new CountingReaderInputStream(reader, maxLength);
ValueLobDb lob = createLob(in, type);
// the length is not correct
lob = ValueLobDb.create(type, database, lob.getTableId(), lob.getLobId(), null, in.getLength());
return lob;
} catch (IllegalStateException e) {
throw DbException.get(ErrorCode.OBJECT_CLOSED, e);
} catch (IOException e) {
throw DbException.convertIOException(e, null);
}
}
use of org.h2.dev.util.BinaryArithmeticStream.In in project h2database by h2database.
the class LobStorageMap method init.
@Override
public void init() {
if (init) {
return;
}
init = true;
Store s = database.getMvStore();
MVStore mvStore;
if (s == null) {
// in-memory database
mvStore = MVStore.open(null);
} else {
mvStore = s.getStore();
}
lobMap = mvStore.openMap("lobMap");
refMap = mvStore.openMap("lobRef");
dataMap = mvStore.openMap("lobData");
streamStore = new StreamStore(dataMap);
// garbage collection of the last blocks
if (database.isReadOnly()) {
return;
}
if (dataMap.isEmpty()) {
return;
}
// search for the last block
// (in theory, only the latest lob can have unreferenced blocks,
// but the latest lob could be a copy of another one, and
// we don't know that, so we iterate over all lobs)
long lastUsedKey = -1;
for (Entry<Long, Object[]> e : lobMap.entrySet()) {
long lobId = e.getKey();
Object[] v = e.getValue();
byte[] id = (byte[]) v[0];
long max = streamStore.getMaxBlockKey(id);
// a lob may not have a referenced blocks if data is kept inline
if (max != -1 && max > lastUsedKey) {
lastUsedKey = max;
if (TRACE) {
trace("lob " + lobId + " lastUsedKey=" + lastUsedKey);
}
}
}
if (TRACE) {
trace("lastUsedKey=" + lastUsedKey);
}
// delete all blocks that are newer
while (true) {
Long last = dataMap.lastKey();
if (last == null || last <= lastUsedKey) {
break;
}
if (TRACE) {
trace("gc " + last);
}
dataMap.remove(last);
}
// don't re-use block ids, except at the very end
Long last = dataMap.lastKey();
if (last != null) {
streamStore.setNextKey(last + 1);
}
}
use of org.h2.dev.util.BinaryArithmeticStream.In in project h2database by h2database.
the class PageLog method readRow.
/**
* Read a row from an input stream.
*
* @param rowFactory the row factory
* @param in the input stream
* @param data a temporary buffer
* @return the row
*/
public static Row readRow(RowFactory rowFactory, DataReader in, Data data) throws IOException {
long key = in.readVarLong();
int len = in.readVarInt();
data.reset();
data.checkCapacity(len);
in.readFully(data.getBytes(), len);
int columnCount = data.readVarInt();
Value[] values = new Value[columnCount];
for (int i = 0; i < columnCount; i++) {
values[i] = data.readValue();
}
Row row = rowFactory.createRow(values, Row.MEMORY_CALCULATE);
row.setKey(key);
return row;
}
Aggregations