提交 f11667db authored 作者: Thomas Mueller's avatar Thomas Mueller

Formatting.

上级 bf43f380
...@@ -48,7 +48,7 @@ import org.h2.value.ValueLobDb; ...@@ -48,7 +48,7 @@ import org.h2.value.ValueLobDb;
* lock the Database object. However, in the case of the LOB data, we are using * lock the Database object. However, in the case of the LOB data, we are using
* the system session to store the data. If we locked the normal way, we see * the system session to store the data. If we locked the normal way, we see
* deadlocks caused by the following pattern: * deadlocks caused by the following pattern:
* *
* <pre> * <pre>
* Thread 1: * Thread 1:
* locks normal session * locks normal session
...@@ -58,7 +58,7 @@ import org.h2.value.ValueLobDb; ...@@ -58,7 +58,7 @@ import org.h2.value.ValueLobDb;
* locks system session * locks system session
* waiting to lock database. * waiting to lock database.
* </pre> * </pre>
* *
* So, in this class alone, we do two things: we have our very own dedicated * So, in this class alone, we do two things: we have our very own dedicated
* session, the LOB session, and we take the locks in this order: first the * session, the LOB session, and we take the locks in this order: first the
* Database object, and then the LOB session. Since we own the LOB session, * Database object, and then the LOB session. Since we own the LOB session,
...@@ -326,7 +326,7 @@ public class LobStorageBackend implements LobStorageInterface { ...@@ -326,7 +326,7 @@ public class LobStorageBackend implements LobStorageInterface {
// see locking discussion at the top // see locking discussion at the top
synchronized (database) { synchronized (database) {
synchronized (conn.getSession()) { synchronized (conn.getSession()) {
long lobId = lob.getLobId(); long lobId = lob.getLobId();
return new LobInputStream(lobId, byteCount); return new LobInputStream(lobId, byteCount);
} }
} }
......
...@@ -65,7 +65,7 @@ public class LobStorageFrontend implements LobStorageInterface { ...@@ -65,7 +65,7 @@ public class LobStorageFrontend implements LobStorageInterface {
public void setTable(ValueLobDb lob, int tableIdSessionVariable) { public void setTable(ValueLobDb lob, int tableIdSessionVariable) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public void removeAllForTable(int tableId) { public void removeAllForTable(int tableId) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
......
...@@ -70,17 +70,17 @@ public interface LobStorageInterface { ...@@ -70,17 +70,17 @@ public interface LobStorageInterface {
* @param lob the lob * @param lob the lob
*/ */
void removeLob(ValueLobDb lob); void removeLob(ValueLobDb lob);
/** /**
* Remove all LOBs for this table. * Remove all LOBs for this table.
* *
* @param tableId the table id * @param tableId the table id
*/ */
void removeAllForTable(int tableId); void removeAllForTable(int tableId);
/** /**
* Initialize the lob storage. * Initialize the lob storage.
*/ */
void init(); void init();
} }
...@@ -34,35 +34,36 @@ import org.h2.value.ValueLobDb; ...@@ -34,35 +34,36 @@ import org.h2.value.ValueLobDb;
* i.e. the server side of the LOB storage. * i.e. the server side of the LOB storage.
*/ */
public class LobStorageMap implements LobStorageInterface { public class LobStorageMap implements LobStorageInterface {
private static final boolean TRACE = false; private static final boolean TRACE = false;
private final Database database; private final Database database;
private boolean init; private boolean init;
/** /**
* The lob metadata map. It contains the mapping from the lob id * The lob metadata map. It contains the mapping from the lob id
* (which is a long) to the stream store id (which is a byte array). * (which is a long) to the stream store id (which is a byte array).
* *
* Key: lobId (long) * Key: lobId (long)
* Value: { streamStoreId (byte[]), tableId (int), byteCount (long), hashCode (long) }. * Value: { streamStoreId (byte[]), tableId (int),
* byteCount (long), hashCode (long) }.
*/ */
private MVMap<Long, Object[]> lobMap; private MVMap<Long, Object[]> lobMap;
/** /**
* The reference map. It is used to remove data from the stream store: if no * The reference map. It is used to remove data from the stream store: if no
* more entries for the given streamStoreId exist, the data is removed from * more entries for the given streamStoreId exist, the data is removed from
* the stream store. * the stream store.
* *
* Key: { streamStoreId (byte[]), lobId (long) }. * Key: { streamStoreId (byte[]), lobId (long) }.
* Value: true (boolean). * Value: true (boolean).
*/ */
private MVMap<Object[], Boolean> refMap; private MVMap<Object[], Boolean> refMap;
/** /**
* The stream store data map. * The stream store data map.
* *
* Key: stream store block id (long). * Key: stream store block id (long).
* Value: data (byte[]). * Value: data (byte[]).
*/ */
...@@ -73,7 +74,7 @@ public class LobStorageMap implements LobStorageInterface { ...@@ -73,7 +74,7 @@ public class LobStorageMap implements LobStorageInterface {
public LobStorageMap(Database database) { public LobStorageMap(Database database) {
this.database = database; this.database = database;
} }
@Override @Override
public void init() { public void init() {
if (init) { if (init) {
...@@ -88,14 +89,15 @@ public class LobStorageMap implements LobStorageInterface { ...@@ -88,14 +89,15 @@ public class LobStorageMap implements LobStorageInterface {
} else { } else {
mvStore = s.getStore(); mvStore = s.getStore();
} }
lobMap = mvStore.openMap("lobMap", lobMap = mvStore.openMap("lobMap",
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 // TODO currently needed to avoid out of memory,
// because memory usage is only measure in number of pages currently
streamStore.setMaxBlockSize(32 * 1024); streamStore.setMaxBlockSize(32 * 1024);
} }
...@@ -165,13 +167,13 @@ public class LobStorageMap implements LobStorageInterface { ...@@ -165,13 +167,13 @@ public class LobStorageMap implements LobStorageInterface {
throw DbException.convertIOException(e, null); throw DbException.convertIOException(e, null);
} }
} }
private ValueLobDb createLob(InputStream in, int type) throws IOException { private ValueLobDb createLob(InputStream in, int type) throws IOException {
byte[] streamStoreId; byte[] streamStoreId;
try { try {
streamStoreId = streamStore.put(in); streamStoreId = streamStore.put(in);
} catch (Exception e) { } catch (Exception e) {
throw DbException.convertToIOException(e); throw DbException.convertToIOException(e);
} }
long lobId = generateLobId(); long lobId = generateLobId();
long length = streamStore.length(streamStoreId); long length = streamStore.length(streamStoreId);
...@@ -186,7 +188,7 @@ public class LobStorageMap implements LobStorageInterface { ...@@ -186,7 +188,7 @@ public class LobStorageMap implements LobStorageInterface {
} }
return lob; return lob;
} }
private long generateLobId() { private long generateLobId() {
Long id = lobMap.lastKey(); Long id = lobMap.lastKey();
return id == null ? 1 : id + 1; return id == null ? 1 : id + 1;
...@@ -211,7 +213,7 @@ public class LobStorageMap implements LobStorageInterface { ...@@ -211,7 +213,7 @@ public class LobStorageMap implements LobStorageInterface {
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) { if (TRACE) {
trace("copy " + old.getTableId() + "/" + old.getLobId() + " > " + tableId + "/" + lobId); trace("copy " + old.getTableId() + "/" + old.getLobId() + " > " + tableId + "/" + lobId);
} }
return lob; return lob;
} }
...@@ -220,7 +222,7 @@ public class LobStorageMap implements LobStorageInterface { ...@@ -220,7 +222,7 @@ public class LobStorageMap implements LobStorageInterface {
public InputStream getInputStream(ValueLobDb lob, byte[] hmac, long byteCount) public InputStream getInputStream(ValueLobDb lob, byte[] hmac, long byteCount)
throws IOException { throws IOException {
init(); init();
Object[] value = lobMap.get(lob.getLobId()); Object[] value = lobMap.get(lob.getLobId());
byte[] streamStoreId = (byte[]) value[0]; byte[] streamStoreId = (byte[]) value[0];
return streamStore.get(streamStoreId); return streamStore.get(streamStoreId);
} }
...@@ -231,16 +233,17 @@ public class LobStorageMap implements LobStorageInterface { ...@@ -231,16 +233,17 @@ public class LobStorageMap implements LobStorageInterface {
long lobId = lob.getLobId(); long lobId = lob.getLobId();
Object[] value = lobMap.remove(lobId); Object[] value = lobMap.remove(lobId);
if (TRACE) { if (TRACE) {
trace("move " + lob.getTableId() + "/" + lob.getLobId() + " > " + tableId + "/" + lobId); trace("move " + lob.getTableId() + "/" + lob.getLobId() + " > " + tableId + "/" + lobId);
} }
value[1] = tableId; value[1] = tableId;
lobMap.put(lobId, value); lobMap.put(lobId, value);
} }
@Override @Override
public void removeAllForTable(int tableId) { public void removeAllForTable(int tableId) {
init(); init();
// this might not be very efficient - to speed it up, we would need yet another map // this might not be very efficient -
// to speed it up, we would need yet another map
ArrayList<Long> list = New.arrayList(); ArrayList<Long> list = New.arrayList();
for (Entry<Long, Object[]> e : lobMap.entrySet()) { for (Entry<Long, Object[]> e : lobMap.entrySet()) {
Object[] value = e.getValue(); Object[] value = e.getValue();
...@@ -261,10 +264,10 @@ public class LobStorageMap implements LobStorageInterface { ...@@ -261,10 +264,10 @@ public class LobStorageMap implements LobStorageInterface {
long lobId = lob.getLobId(); long lobId = lob.getLobId();
removeLob(tableId, lobId); removeLob(tableId, lobId);
} }
private void removeLob(int tableId, long lobId) { private void removeLob(int tableId, long lobId) {
if (TRACE) { if (TRACE) {
trace("remove " + tableId + "/" + lobId); trace("remove " + tableId + "/" + lobId);
} }
Object[] value = lobMap.remove(lobId); Object[] value = lobMap.remove(lobId);
byte[] streamStoreId = (byte[]) value[0]; byte[] streamStoreId = (byte[]) value[0];
...@@ -284,7 +287,7 @@ public class LobStorageMap implements LobStorageInterface { ...@@ -284,7 +287,7 @@ public class LobStorageMap implements LobStorageInterface {
streamStore.remove(streamStoreId); streamStore.remove(streamStoreId);
} }
} }
private static void trace(String op) { private static void trace(String op) {
System.out.println("LOB " + op); System.out.println("LOB " + op);
} }
......
...@@ -26,7 +26,7 @@ class LobStorageRemoteInputStream extends InputStream { ...@@ -26,7 +26,7 @@ class LobStorageRemoteInputStream extends InputStream {
* The lob id. * The lob id.
*/ */
private final long lob; private final long lob;
private final byte[] hmac; private final byte[] hmac;
/** /**
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论