提交 4cd69931 authored 作者: Thomas Mueller's avatar Thomas Mueller

Bugfixes, trace

上级 2505065e
...@@ -15,6 +15,7 @@ import java.util.ArrayList; ...@@ -15,6 +15,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.h2.constant.ErrorCode;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.message.DbException; import org.h2.message.DbException;
...@@ -34,6 +35,8 @@ import org.h2.value.ValueLobDb; ...@@ -34,6 +35,8 @@ import org.h2.value.ValueLobDb;
*/ */
public class LobStorageMap implements LobStorageInterface { public class LobStorageMap implements LobStorageInterface {
private static final boolean TRACE = false;
private final Database database; private final Database database;
private boolean init; private boolean init;
...@@ -89,9 +92,11 @@ public class LobStorageMap implements LobStorageInterface { ...@@ -89,9 +92,11 @@ public class LobStorageMap implements LobStorageInterface {
new MVMapConcurrent.Builder<Long, Object[]>()); new MVMapConcurrent.Builder<Long, Object[]>());
refMap = mvStore.openMap("lobRef", refMap = mvStore.openMap("lobRef",
new MVMapConcurrent.Builder<Object[], Boolean>()); new MVMapConcurrent.Builder<Object[], Boolean>());
dataMap = mvStore.openMap("lobData", dataMap = mvStore.openMap("lobData",
new MVMapConcurrent.Builder<Long, byte[]>()); new MVMapConcurrent.Builder<Long, byte[]>());
streamStore = new StreamStore(dataMap); streamStore = new StreamStore(dataMap);
// TODO currently needed to avoid out of memory
streamStore.setMaxBlockSize(32 * 1024);
} }
@Override @Override
...@@ -118,6 +123,8 @@ public class LobStorageMap implements LobStorageInterface { ...@@ -118,6 +123,8 @@ public class LobStorageMap implements LobStorageInterface {
in = b; in = b;
} }
return createLob(in, type); return createLob(in, type);
} catch (IllegalStateException e) {
throw DbException.get(ErrorCode.OBJECT_CLOSED);
} catch (IOException e) { } catch (IOException e) {
throw DbException.convertIOException(e, null); throw DbException.convertIOException(e, null);
} }
...@@ -152,6 +159,8 @@ public class LobStorageMap implements LobStorageInterface { ...@@ -152,6 +159,8 @@ public class LobStorageMap implements LobStorageInterface {
// the length is not correct // the length is not correct
lob = ValueLobDb.create(type, database, lob.getTableId(), lob.getLobId(), null, in.getLength()); lob = ValueLobDb.create(type, database, lob.getTableId(), lob.getLobId(), null, in.getLength());
return lob; return lob;
} catch (IllegalStateException e) {
throw DbException.get(ErrorCode.OBJECT_CLOSED);
} catch (IOException e) { } catch (IOException e) {
throw DbException.convertIOException(e, null); throw DbException.convertIOException(e, null);
} }
...@@ -164,7 +173,7 @@ public class LobStorageMap implements LobStorageInterface { ...@@ -164,7 +173,7 @@ public class LobStorageMap implements LobStorageInterface {
} catch (Exception e) { } catch (Exception e) {
throw DbException.convertToIOException(e); throw DbException.convertToIOException(e);
} }
long lobId = streamStore.getAndIncrementNextKey(); long lobId = generateLobId();
long length = streamStore.length(streamStoreId); long length = streamStore.length(streamStoreId);
int tableId = LobStorageFrontend.TABLE_TEMP; int tableId = LobStorageFrontend.TABLE_TEMP;
Object[] value = new Object[] { streamStoreId, tableId, length, 0 }; Object[] value = new Object[] { streamStoreId, tableId, length, 0 };
...@@ -172,8 +181,16 @@ public class LobStorageMap implements LobStorageInterface { ...@@ -172,8 +181,16 @@ public class LobStorageMap implements LobStorageInterface {
Object[] key = new Object[] { streamStoreId, lobId }; Object[] key = new Object[] { streamStoreId, lobId };
refMap.put(key, Boolean.TRUE); refMap.put(key, Boolean.TRUE);
ValueLobDb lob = ValueLobDb.create(type, database, tableId, lobId, null, length); ValueLobDb lob = ValueLobDb.create(type, database, tableId, lobId, null, length);
if (TRACE) {
trace("create " + tableId + "/" + lobId);
}
return lob; return lob;
} }
private long generateLobId() {
Long id = lobMap.lastKey();
return id == null ? 1 : id + 1;
}
@Override @Override
public ValueLobDb copyLob(ValueLobDb old, int tableId, long length) { public ValueLobDb copyLob(ValueLobDb old, int tableId, long length) {
...@@ -185,13 +202,17 @@ public class LobStorageMap implements LobStorageInterface { ...@@ -185,13 +202,17 @@ public class LobStorageMap implements LobStorageInterface {
throw DbException.throwInternalError("Length is different"); throw DbException.throwInternalError("Length is different");
} }
Object[] value = lobMap.get(oldLobId); Object[] value = lobMap.get(oldLobId);
value = Arrays.copyOf(value, value.length);
byte[] streamStoreId = (byte[]) value[0]; byte[] streamStoreId = (byte[]) value[0];
long lobId = streamStore.getAndIncrementNextKey(); long lobId = generateLobId();
value[1] = tableId; value[1] = tableId;
lobMap.put(lobId, value); lobMap.put(lobId, value);
Object[] key = new Object[] { streamStoreId, lobId }; Object[] key = new Object[] { streamStoreId, lobId };
refMap.put(key, Boolean.TRUE); refMap.put(key, Boolean.TRUE);
ValueLobDb lob = ValueLobDb.create(type, database, tableId, lobId, null, length); ValueLobDb lob = ValueLobDb.create(type, database, tableId, lobId, null, length);
if (TRACE) {
trace("copy " + old.getTableId() + "/" + old.getLobId() + " > " + tableId + "/" + lobId);
}
return lob; return lob;
} }
...@@ -209,6 +230,9 @@ public class LobStorageMap implements LobStorageInterface { ...@@ -209,6 +230,9 @@ public class LobStorageMap implements LobStorageInterface {
init(); init();
long lobId = lob.getLobId(); long lobId = lob.getLobId();
Object[] value = lobMap.remove(lobId); Object[] value = lobMap.remove(lobId);
if (TRACE) {
trace("move " + lob.getTableId() + "/" + lob.getLobId() + " > " + tableId + "/" + lobId);
}
value[1] = tableId; value[1] = tableId;
lobMap.put(lobId, value); lobMap.put(lobId, value);
} }
...@@ -239,10 +263,15 @@ public class LobStorageMap implements LobStorageInterface { ...@@ -239,10 +263,15 @@ public class LobStorageMap implements LobStorageInterface {
} }
private void removeLob(int tableId, long lobId) { private void removeLob(int tableId, long lobId) {
if (TRACE) {
trace("remove " + tableId + "/" + lobId);
}
Object[] value = lobMap.remove(lobId); Object[] value = lobMap.remove(lobId);
byte[] streamStoreId = (byte[]) value[0]; byte[] streamStoreId = (byte[]) value[0];
Object[] key = new Object[] {streamStoreId, lobId };
refMap.remove(key);
// check if there are more entries for this streamStoreId // check if there are more entries for this streamStoreId
Object[] key = new Object[] {streamStoreId, 0 }; key = new Object[] {streamStoreId, 0 };
value = refMap.ceilingKey(key); value = refMap.ceilingKey(key);
boolean hasMoreEntries = false; boolean hasMoreEntries = false;
if (value != null) { if (value != null) {
...@@ -255,5 +284,9 @@ public class LobStorageMap implements LobStorageInterface { ...@@ -255,5 +284,9 @@ public class LobStorageMap implements LobStorageInterface {
streamStore.remove(streamStoreId); streamStore.remove(streamStoreId);
} }
} }
private static void trace(String op) {
System.out.println("LOB " + op);
}
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论