private void removeLob(int tableId, long lobId) {
   if (TRACE) {
     trace("remove " + tableId + "/" + lobId);
   }
   Object[] value = lobMap.remove(lobId);
   if (value == null) {
     // already removed
     return;
   }
   byte[] streamStoreId = (byte[]) value[0];
   Object[] key = new Object[] {streamStoreId, lobId};
   refMap.remove(key);
   // check if there are more entries for this streamStoreId
   key = new Object[] {streamStoreId, 0L};
   value = refMap.ceilingKey(key);
   boolean hasMoreEntries = false;
   if (value != null) {
     byte[] s2 = (byte[]) value[0];
     if (Arrays.equals(streamStoreId, s2)) {
       hasMoreEntries = true;
     }
   }
   if (!hasMoreEntries) {
     streamStore.remove(streamStoreId);
   }
 }
Beispiel #2
0
 /**
  * Remove a key-value pair if the value matches the stored one.
  *
  * @param key the key (may not be null)
  * @param value the expected value
  * @return true if the item was removed
  */
 public synchronized boolean remove(Object key, Object value) {
   V old = get(key);
   if (areValuesEqual(old, value)) {
     remove(key);
     return true;
   }
   return false;
 }
 /**
  * Rollback to an old savepoint.
  *
  * @param t the transaction
  * @param maxLogId the last log id
  * @param toLogId the log id to roll back to
  */
 void rollbackTo(Transaction t, long maxLogId, long toLogId) {
   for (long logId = maxLogId - 1; logId >= toLogId; logId--) {
     Object[] op = undoLog.get(new long[] {t.getId(), logId});
     int mapId = ((Integer) op[1]).intValue();
     Map<String, String> meta = store.getMetaMap();
     String m = meta.get("map." + mapId);
     String mapName = DataUtils.parseMap(m).get("name");
     MVMap<Object, Object[]> map = store.openMap(mapName);
     Object key = op[2];
     Object[] oldValue = (Object[]) op[3];
     if (oldValue == null) {
       // this transaction added the value
       map.remove(key);
     } else {
       // this transaction updated the value
       map.put(key, oldValue);
     }
     undoLog.remove(op);
   }
 }
 @Override
 public void setTable(ValueLobDb lob, int tableId) {
   init();
   long lobId = lob.getLobId();
   Object[] value = lobMap.remove(lobId);
   if (TRACE) {
     trace("move " + lob.getTableId() + "/" + lob.getLobId() + " > " + tableId + "/" + lobId);
   }
   value[1] = tableId;
   lobMap.put(lobId, value);
 }
 @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 the last referenced block
   // (a lob may not have any referenced blocks if data is kept inline,
   // so we need to loop)
   long lastUsedKey = -1;
   Long lobId = lobMap.lastKey();
   while (lobId != null) {
     Object[] v = lobMap.get(lobId);
     byte[] id = (byte[]) v[0];
     lastUsedKey = streamStore.getMaxBlockKey(id);
     if (lastUsedKey >= 0) {
       break;
     }
     lobId = lobMap.lowerKey(lobId);
   }
   // delete all blocks that are newer
   while (true) {
     Long last = dataMap.lastKey();
     if (last == null || last <= lastUsedKey) {
       break;
     }
     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);
   }
 }
 /** Test the concurrent map implementation. */
 private void testConcurrentMap() throws InterruptedException {
   final MVStore s = openStore(null);
   final MVMap<Integer, Integer> m =
       s.openMap("data", new MVMapConcurrent.Builder<Integer, Integer>());
   final int size = 20;
   final Random rand = new Random(1);
   Task task =
       new Task() {
         @Override
         public void call() throws Exception {
           try {
             while (!stop) {
               if (rand.nextBoolean()) {
                 m.put(rand.nextInt(size), 1);
               } else {
                 m.remove(rand.nextInt(size));
               }
               m.get(rand.nextInt(size));
               m.firstKey();
               m.lastKey();
               m.ceilingKey(5);
               m.floorKey(5);
               m.higherKey(5);
               m.lowerKey(5);
               for (Iterator<Integer> it = m.keyIterator(null); it.hasNext(); ) {
                 it.next();
               }
             }
           } catch (Exception e) {
             e.printStackTrace();
           }
         }
       };
   task.execute();
   Thread.sleep(1);
   for (int j = 0; j < 100; j++) {
     for (int i = 0; i < 100; i++) {
       if (rand.nextBoolean()) {
         m.put(rand.nextInt(size), 2);
       } else {
         m.remove(rand.nextInt(size));
       }
       m.get(rand.nextInt(size));
     }
     s.commit();
     Thread.sleep(1);
   }
   task.get();
   s.close();
 }
 /**
  * Commit a transaction.
  *
  * @param t the transaction
  * @param maxLogId the last log id
  */
 void commit(Transaction t, long maxLogId) {
   for (long logId = 0; logId < maxLogId; logId++) {
     long[] undoKey = new long[] {t.getId(), logId};
     Object[] op = undoLog.get(undoKey);
     int opType = (Integer) op[0];
     if (opType == Transaction.OP_REMOVE) {
       int mapId = (Integer) op[1];
       Map<String, String> meta = store.getMetaMap();
       String m = meta.get("map." + mapId);
       String mapName = DataUtils.parseMap(m).get("name");
       MVMap<Object, Object[]> map = store.openMap(mapName);
       Object key = op[2];
       Object[] value = map.get(key);
       // possibly the entry was added later on
       // so we have to check
       if (value[2] == null) {
         // remove the value
         map.remove(key);
       }
     }
     undoLog.remove(undoKey);
   }
   endTransaction(t);
 }
 private void endTransaction(Transaction t) {
   openTransactions.remove(t.getId());
   openTransactionMap.remove(t.getId());
 }
 private void testConcurrentWrite(final AtomicInteger detected, final AtomicInteger notDetected)
     throws InterruptedException {
   final MVStore s = openStore(null);
   final MVMap<Integer, Integer> m = s.openMap("data");
   final int size = 20;
   final Random rand = new Random(1);
   Task task =
       new Task() {
         @Override
         public void call() throws Exception {
           while (!stop) {
             try {
               if (rand.nextBoolean()) {
                 m.put(rand.nextInt(size), 1);
               } else {
                 m.remove(rand.nextInt(size));
               }
               m.get(rand.nextInt(size));
             } catch (ConcurrentModificationException e) {
               detected.incrementAndGet();
             } catch (NegativeArraySizeException e) {
               notDetected.incrementAndGet();
             } catch (ArrayIndexOutOfBoundsException e) {
               notDetected.incrementAndGet();
             } catch (IllegalArgumentException e) {
               notDetected.incrementAndGet();
             } catch (NullPointerException e) {
               notDetected.incrementAndGet();
             }
           }
         }
       };
   task.execute();
   Thread.sleep(1);
   for (int j = 0; j < 10; j++) {
     for (int i = 0; i < 10; i++) {
       try {
         if (rand.nextBoolean()) {
           m.put(rand.nextInt(size), 2);
         } else {
           m.remove(rand.nextInt(size));
         }
         m.get(rand.nextInt(size));
       } catch (ConcurrentModificationException e) {
         detected.incrementAndGet();
       } catch (NegativeArraySizeException e) {
         notDetected.incrementAndGet();
       } catch (ArrayIndexOutOfBoundsException e) {
         notDetected.incrementAndGet();
       } catch (IllegalArgumentException e) {
         notDetected.incrementAndGet();
       } catch (NullPointerException e) {
         notDetected.incrementAndGet();
       }
     }
     s.commit();
     Thread.sleep(1);
   }
   task.get();
   s.close();
 }
 void removeMovieSetFromDb(MovieSet movieSet) throws Exception {
   movieSetMap.remove(movieSet.getDbId());
 }
 void removeMovieFromDb(Movie movie) throws Exception {
   movieMap.remove(movie.getDbId());
 }