コード例 #1
0
 private void testConcurrentStoreAndRemoveMap() throws InterruptedException {
   String fileName = "memFS:testConcurrentStoreAndRemoveMap.h3";
   final MVStore s = openStore(fileName);
   int count = 200;
   for (int i = 0; i < count; i++) {
     MVMap<Integer, Integer> m = s.openMap("d" + i);
     m.put(1, 1);
   }
   final AtomicInteger counter = new AtomicInteger();
   Task task =
       new Task() {
         @Override
         public void call() throws Exception {
           while (!stop) {
             counter.incrementAndGet();
             s.commit();
           }
         }
       };
   task.execute();
   Thread.sleep(1);
   for (int i = 0; i < count || counter.get() < count; i++) {
     MVMap<Integer, Integer> m = s.openMap("d" + i);
     m.put(1, 10);
     s.removeMap(m);
     if (task.isFinished()) {
       break;
     }
   }
   task.get();
   s.close();
   FileUtils.deleteRecursive("memFS:", false);
 }
コード例 #2
0
ファイル: MVMap.java プロジェクト: jackerxff/H2-Research
 /**
  * Add a key-value pair if it does not yet exist.
  *
  * @param key the key (may not be null)
  * @param value the new value
  * @return the old value if the key existed, or null otherwise
  */
 public synchronized V putIfAbsent(K key, V value) {
   V old = get(key);
   if (old == null) {
     put(key, value);
   }
   return old;
 }
コード例 #3
0
 /**
  * Prepare a transaction.
  *
  * @param transactionId the transaction id
  */
 void prepare(Transaction t) {
   storeTransaction(t);
   Object[] old = openTransactions.get(t.getId());
   Object[] v = {Transaction.STATUS_PREPARED, old[1]};
   openTransactions.put(t.getId(), v);
   store.commit();
 }
コード例 #4
0
 void persistMovieSet(MovieSet movieSet) throws Exception {
   String newValue = movieSetObjectWriter.writeValueAsString(movieSet);
   String oldValue = movieMap.get(movieSet.getDbId());
   if (!StringUtils.equals(newValue, oldValue)) {
     movieSetMap.put(movieSet.getDbId(), newValue);
   }
 }
コード例 #5
0
ファイル: MVMap.java プロジェクト: jackerxff/H2-Research
 /**
  * Replace a value for an existing key.
  *
  * @param key the key (may not be null)
  * @param value the new value
  * @return the old value, if the value was replaced, or null
  */
 public synchronized V replace(K key, V value) {
   V old = get(key);
   if (old != null) {
     put(key, value);
     return old;
   }
   return null;
 }
コード例 #6
0
ファイル: MVMap.java プロジェクト: jackerxff/H2-Research
 /**
  * Replace a value for an existing key, if the value matches.
  *
  * @param key the key (may not be null)
  * @param oldValue the expected value
  * @param newValue the new value
  * @return true if the value was replaced
  */
 public synchronized boolean replace(K key, V oldValue, V newValue) {
   V old = get(key);
   if (areValuesEqual(old, oldValue)) {
     put(key, newValue);
     return true;
   }
   return false;
 }
コード例 #7
0
 private void storeTransaction(Transaction t) {
   if (store.getUnsavedPageCount() > MAX_UNSAVED_PAGES) {
     store.commit();
   }
   if (t.isStored()) {
     return;
   }
   t.setStored(true);
   long transactionId = t.getId();
   Object[] v = {t.getStatus(), null};
   openTransactions.put(transactionId, v);
   openTransactionMap.put(transactionId, t);
   if (lastTransactionId > lastTransactionIdStored) {
     lastTransactionIdStored += 32;
     settings.put(LAST_TRANSACTION_ID, "" + lastTransactionIdStored);
   }
 }
コード例 #8
0
  void persistMovie(Movie movie) throws Exception {
    String newValue = movieObjectWriter.writeValueAsString(movie);
    String oldValue = movieMap.get(movie.getDbId());

    if (!StringUtils.equals(newValue, oldValue)) {
      // write movie to DB
      movieMap.put(movie.getDbId(), newValue);
    }
  }
コード例 #9
0
 @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);
 }
コード例 #10
0
 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 = new Object[] {streamStoreId, tableId, length, 0};
   lobMap.put(lobId, value);
   Object[] key = new Object[] {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;
 }
コード例 #11
0
 private void testConcurrentRead() throws InterruptedException {
   final MVStore s = openStore(null);
   final MVMap<Integer, Integer> m = s.openMap("data");
   final int size = 3;
   int x = (int) s.getCurrentVersion();
   for (int i = 0; i < size; i++) {
     m.put(i, x);
   }
   s.commit();
   Task task =
       new Task() {
         @Override
         public void call() throws Exception {
           while (!stop) {
             long v = s.getCurrentVersion() - 1;
             Map<Integer, Integer> old = m.openVersion(v);
             for (int i = 0; i < size; i++) {
               Integer x = old.get(i);
               if (x == null || (int) v != x) {
                 Map<Integer, Integer> old2 = m.openVersion(v);
                 throw new AssertionError(x + "<>" + v + " at " + i + " " + old2);
               }
             }
           }
         }
       };
   task.execute();
   Thread.sleep(1);
   for (int j = 0; j < 100; j++) {
     x = (int) s.getCurrentVersion();
     for (int i = 0; i < size; i++) {
       m.put(i, x);
     }
     s.commit();
     Thread.sleep(1);
   }
   task.get();
   s.close();
 }
コード例 #12
0
 @Override
 public ValueLobDb copyLob(ValueLobDb old, int tableId, long length) {
   init();
   int type = old.getType();
   long oldLobId = old.getLobId();
   long oldLength = old.getPrecision();
   if (oldLength != length) {
     throw DbException.throwInternalError("Length is different");
   }
   Object[] value = lobMap.get(oldLobId);
   value = value.clone();
   byte[] streamStoreId = (byte[]) value[0];
   long lobId = generateLobId();
   value[1] = tableId;
   lobMap.put(lobId, value);
   Object[] key = new Object[] {streamStoreId, lobId};
   refMap.put(key, Boolean.TRUE);
   ValueLobDb lob = ValueLobDb.create(type, database, tableId, lobId, null, length);
   if (TRACE) {
     trace("copy " + old.getTableId() + "/" + old.getLobId() + " > " + tableId + "/" + lobId);
   }
   return lob;
 }
コード例 #13
0
 /** 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();
 }
コード例 #14
0
 /**
  * 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);
   }
 }
コード例 #15
0
  private void testConcurrentFree() throws InterruptedException {
    String fileName = "memFS:testConcurrentFree.h3";
    for (int test = 0; test < 10; test++) {
      FileUtils.delete(fileName);
      final MVStore s1 = new MVStore.Builder().fileName(fileName).autoCommitDisabled().open();
      s1.setRetentionTime(0);
      final int count = 200;
      for (int i = 0; i < count; i++) {
        MVMap<Integer, Integer> m = s1.openMap("d" + i);
        m.put(1, 1);
        if (i % 2 == 0) {
          s1.commit();
        }
      }
      s1.close();
      final MVStore s = new MVStore.Builder().fileName(fileName).autoCommitDisabled().open();
      s.setRetentionTime(0);
      final ArrayList<MVMap<Integer, Integer>> list = New.arrayList();
      for (int i = 0; i < count; i++) {
        MVMap<Integer, Integer> m = s.openMap("d" + i);
        list.add(m);
      }

      final AtomicInteger counter = new AtomicInteger();
      Task task =
          new Task() {
            @Override
            public void call() throws Exception {
              while (!stop) {
                int x = counter.getAndIncrement();
                if (x >= count) {
                  break;
                }
                MVMap<Integer, Integer> m = list.get(x);
                m.clear();
                s.removeMap(m);
              }
            }
          };
      task.execute();
      Thread.sleep(1);
      while (true) {
        int x = counter.getAndIncrement();
        if (x >= count) {
          break;
        }
        MVMap<Integer, Integer> m = list.get(x);
        m.clear();
        s.removeMap(m);
        if (x % 5 == 0) {
          s.commit();
        }
      }
      task.get();
      s.commit();

      MVMap<String, String> meta = s.getMetaMap();
      int chunkCount = 0;
      for (String k : meta.keyList()) {
        if (k.startsWith("chunk.")) {
          chunkCount++;
        }
      }
      assertEquals(1, chunkCount);
      s.close();
    }
    FileUtils.deleteRecursive("memFS:", false);
  }
コード例 #16
0
 /**
  * Set the name of a transaction.
  *
  * @param t the transaction
  * @param name the new name
  */
 void setTransactionName(Transaction t, String name) {
   storeTransaction(t);
   Object[] old = openTransactions.get(t.getId());
   Object[] v = {old[0], name};
   openTransactions.put(t.getId(), v);
 }
コード例 #17
0
 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();
 }
コード例 #18
0
 /**
  * Log an entry.
  *
  * @param t the transaction
  * @param logId the log id
  * @param opType the operation type
  * @param mapId the map id
  * @param key the key
  * @param oldValue the old value
  */
 void log(Transaction t, long logId, int opType, int mapId, Object key, Object oldValue) {
   storeTransaction(t);
   long[] undoKey = {t.getId(), logId};
   Object[] log = new Object[] {opType, mapId, key, oldValue};
   undoLog.put(undoKey, log);
 }
コード例 #19
0
 /** Close the transaction store. */
 public synchronized void close() {
   // to avoid losing transaction ids
   settings.put(LAST_TRANSACTION_ID, "" + lastTransactionId);
   store.commit();
 }