예제 #1
0
 @Override
 public long getRowCount(Session session) {
   TransactionMap<Value, Value> map = getMap(session);
   return map.sizeAsLong();
 }
예제 #2
0
  private void testCompareWithPostgreSQL() throws Exception {
    ArrayList<Statement> statements = New.arrayList();
    ArrayList<Transaction> transactions = New.arrayList();
    ArrayList<TransactionMap<Integer, String>> maps = New.arrayList();
    int connectionCount = 3, opCount = 1000, rowCount = 10;
    try {
      Class.forName("org.postgresql.Driver");
      for (int i = 0; i < connectionCount; i++) {
        Connection conn = DriverManager.getConnection("jdbc:postgresql:test", "sa", "sa");
        statements.add(conn.createStatement());
      }
    } catch (Exception e) {
      // database not installed - ok
      return;
    }
    statements.get(0).execute("drop table if exists test cascade");
    statements.get(0).execute("create table test(id int primary key, name varchar(255))");

    MVStore s = MVStore.open(null);
    TransactionStore ts = new TransactionStore(s);
    for (int i = 0; i < connectionCount; i++) {
      Statement stat = statements.get(i);
      // 100 ms to avoid blocking (the test is single threaded)
      stat.execute("set statement_timeout to 100");
      Connection c = stat.getConnection();
      c.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
      c.setAutoCommit(false);
      Transaction transaction = ts.begin();
      transactions.add(transaction);
      TransactionMap<Integer, String> map;
      map = transaction.openMap("test");
      maps.add(map);
    }
    StringBuilder buff = new StringBuilder();

    Random r = new Random(1);
    try {
      for (int i = 0; i < opCount; i++) {
        int connIndex = r.nextInt(connectionCount);
        Statement stat = statements.get(connIndex);
        Transaction transaction = transactions.get(connIndex);
        TransactionMap<Integer, String> map = maps.get(connIndex);
        if (transaction == null) {
          transaction = ts.begin();
          map = transaction.openMap("test");
          transactions.set(connIndex, transaction);
          maps.set(connIndex, map);

          // read all data, to get a snapshot
          ResultSet rs = stat.executeQuery("select * from test order by id");
          buff.append(i).append(": [" + connIndex + "]=");
          int size = 0;
          while (rs.next()) {
            buff.append(' ');
            int k = rs.getInt(1);
            String v = rs.getString(2);
            buff.append(k).append(':').append(v);
            assertEquals(v, map.get(k));
            size++;
          }
          buff.append('\n');
          if (size != map.sizeAsLong()) {
            assertEquals(size, map.sizeAsLong());
          }
        }
        int x = r.nextInt(rowCount);
        int y = r.nextInt(rowCount);
        buff.append(i).append(": [" + connIndex + "]: ");
        ResultSet rs = null;
        switch (r.nextInt(7)) {
          case 0:
            buff.append("commit");
            stat.getConnection().commit();
            transaction.commit();
            transactions.set(connIndex, null);
            break;
          case 1:
            buff.append("rollback");
            stat.getConnection().rollback();
            transaction.rollback();
            transactions.set(connIndex, null);
            break;
          case 2:
            // insert or update
            String old = map.get(x);
            if (old == null) {
              buff.append("insert " + x + "=" + y);
              if (map.tryPut(x, "" + y)) {
                stat.execute("insert into test values(" + x + ", '" + y + "')");
              } else {
                buff.append(" -> row was locked");
                // the statement would time out in PostgreSQL
                // TODO test sometimes if timeout occurs
              }
            } else {
              buff.append("update " + x + "=" + y + " (old:" + old + ")");
              if (map.tryPut(x, "" + y)) {
                int c = stat.executeUpdate("update test set name = '" + y + "' where id = " + x);
                assertEquals(1, c);
              } else {
                buff.append(" -> row was locked");
                // the statement would time out in PostgreSQL
                // TODO test sometimes if timeout occurs
              }
            }
            break;
          case 3:
            buff.append("delete " + x);
            try {
              int c = stat.executeUpdate("delete from test where id = " + x);
              if (c == 1) {
                map.remove(x);
              } else {
                assertNull(map.get(x));
              }
            } catch (SQLException e) {
              assertTrue(map.get(x) != null);
              assertFalse(map.tryRemove(x));
              // PostgreSQL needs to rollback
              buff.append(" -> rollback");
              stat.getConnection().rollback();
              transaction.rollback();
              transactions.set(connIndex, null);
            }
            break;
          case 4:
          case 5:
          case 6:
            rs = stat.executeQuery("select * from test where id = " + x);
            String expected = rs.next() ? rs.getString(2) : null;
            buff.append("select " + x + "=" + expected);
            assertEquals("i:" + i, expected, map.get(x));
            break;
        }
        buff.append('\n');
      }
    } catch (Exception e) {
      e.printStackTrace();
      fail(buff.toString());
    }
    for (Statement stat : statements) {
      stat.getConnection().close();
    }
    ts.close();
    s.close();
  }