@Override public long getRowCount(Session session) { TransactionMap<Value, Value> map = getMap(session); return map.sizeAsLong(); }
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(); }