use of herddb.utils.Holder in project herddb by diennea.
the class BLinkTest method testScan.
@Test
public void testScan() throws Exception {
BLinkIndexDataStorage<Sized<Long>, Long> storage = new DummyBLinkIndexDataStorage<>();
try (BLink<Sized<Long>, Long> blink = new BLink<>(2048L, new LongSizeEvaluator(), new RandomPageReplacementPolicy(10), storage)) {
final long inserts = 100;
for (long l = 0; l < inserts; l++) {
blink.insert(Sized.valueOf(l), l);
}
BLinkMetadata<Sized<Long>> metadata = blink.checkpoint();
/* Require at least two nodes! */
assertNotEquals(1, metadata.nodes.size());
long offset = 10;
for (long l = 0; l < inserts - offset; l++) {
Stream<Entry<Sized<Long>, Long>> stream = blink.scan(Sized.valueOf(l), Sized.valueOf(l + offset));
Holder<Long> h = new Holder<>(l);
Holder<Long> count = new Holder<>(0L);
StringBuilder builder = new StringBuilder();
/* Check each value */
stream.forEach(entry -> {
assertEquals(h.value, entry.getValue());
h.value++;
count.value++;
builder.append(entry.getValue()).append(", ");
});
builder.setLength(builder.length() - 2);
System.out.println("start " + l + " end " + (l + offset) + " -> " + builder);
assertEquals(offset, (long) count.value);
}
}
}
use of herddb.utils.Holder in project herddb by diennea.
the class TableManager method executeDeleteAsync.
private CompletableFuture<StatementExecutionResult> executeDeleteAsync(DeleteStatement delete, Transaction transaction, StatementEvaluationContext context) {
AtomicInteger updateCount = new AtomicInteger();
Holder<Bytes> lastKey = new Holder<>();
Holder<Bytes> lastValue = new Holder<>();
long transactionId = transaction != null ? transaction.transactionId : 0;
Predicate predicate = delete.getPredicate();
List<CompletableFuture<PendingLogEntryWork>> writes = new ArrayList<>();
Map<String, AbstractIndexManager> indexes = tableSpaceManager.getIndexesOnTable(table.name);
ScanStatement scan = new ScanStatement(table.tablespace, table, predicate);
try {
accessTableData(scan, context, new ScanResultOperation() {
@Override
public void accept(Record current, LockHandle lockHandle) throws StatementExecutionException, LogNotAvailableException, DataStorageManagerException {
// ensure we are holding the write locks on every unique index
List<UniqueIndexLockReference> uniqueIndexes = null;
try {
if (indexes != null || childrenTables != null) {
DataAccessor dataAccessor = current.getDataAccessor(table);
if (childrenTables != null) {
for (Table childTable : childrenTables) {
executeForeignKeyConstraintsAsParentTable(childTable, dataAccessor, context, transaction, true);
}
}
if (indexes != null) {
for (AbstractIndexManager index : indexes.values()) {
if (index.isUnique()) {
Bytes indexKey = RecordSerializer.serializeIndexKey(dataAccessor, index.getIndex(), index.getColumnNames());
if (uniqueIndexes == null) {
uniqueIndexes = new ArrayList<>(1);
}
UniqueIndexLockReference uniqueIndexLock = new UniqueIndexLockReference(index, indexKey);
uniqueIndexes.add(uniqueIndexLock);
LockHandle lockForIndex = lockForWrite(uniqueIndexLock.key, transaction, index.getIndexName(), index.getLockManager());
if (transaction == null) {
uniqueIndexLock.lockHandle = lockForIndex;
}
}
}
}
}
} catch (IllegalArgumentException | herddb.utils.IllegalDataAccessException | StatementExecutionException err) {
locksManager.releaseLock(lockHandle);
StatementExecutionException finalError;
if (!(err instanceof StatementExecutionException)) {
finalError = new StatementExecutionException(err.getMessage(), err);
} else {
finalError = (StatementExecutionException) err;
}
CompletableFuture<PendingLogEntryWork> res = Futures.exception(finalError);
if (uniqueIndexes != null) {
for (UniqueIndexLockReference lock : uniqueIndexes) {
res = releaseWriteLock(res, lockHandle, lock.indexManager.getLockManager());
}
}
writes.add(res);
return;
}
LogEntry entry = LogEntryFactory.delete(table, current.key, transaction);
CommitLogResult pos = log.log(entry, entry.transactionId <= 0);
final List<UniqueIndexLockReference> _uniqueIndexes = uniqueIndexes;
writes.add(pos.logSequenceNumber.thenApply(lsn -> new PendingLogEntryWork(entry, pos, lockHandle, _uniqueIndexes)));
lastKey.value = current.key;
lastValue.value = current.value;
updateCount.incrementAndGet();
}
}, transaction, true, true);
} catch (HerdDBInternalException err) {
LOGGER.log(Level.SEVERE, "bad error during a delete", err);
return Futures.exception(err);
}
if (writes.isEmpty()) {
return CompletableFuture.completedFuture(new DMLStatementExecutionResult(transactionId, 0, null, null));
}
if (writes.size() == 1) {
return writes.get(0).whenCompleteAsync((pending, error) -> {
try {
// apply any of the DML operations
if (error == null) {
apply(pending.pos, pending.entry, false);
}
} finally {
releaseMultiplePendingLogEntryWorks(writes);
}
}, tableSpaceManager.getCallbacksExecutor()).thenApply((pending) -> {
return new DMLStatementExecutionResult(transactionId, updateCount.get(), lastKey.value, delete.isReturnValues() ? lastValue.value : null);
});
} else {
return Futures.collect(writes).whenCompleteAsync((pendings, error) -> {
try {
// apply any of the DML operations
if (error == null) {
for (PendingLogEntryWork pending : pendings) {
apply(pending.pos, pending.entry, false);
}
}
} finally {
releaseMultiplePendingLogEntryWorks(writes);
}
}, tableSpaceManager.getCallbacksExecutor()).thenApply((pendings) -> {
return new DMLStatementExecutionResult(transactionId, updateCount.get(), lastKey.value, delete.isReturnValues() ? lastValue.value : null);
});
}
}
use of herddb.utils.Holder in project herddb by diennea.
the class SimpleClusterTest method test.
@Test
public void test() throws Exception {
{
Record record = new Record(Bytes.from_string("key1"), Bytes.from_string("0"));
InsertStatement st = new InsertStatement(tableSpace, tableName, record);
assertEquals(1, manager.executeUpdate(st, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION).getUpdateCount());
}
assertEquals(0, dataStorageManager.getActualNumberOfPages(tableSpaceUUID, tableName));
manager.checkpoint();
String tableUuid = manager.getTableSpaceManager(tableSpace).getTableManager(tableName).getTable().uuid;
assertNotNull(dataStorageManager.readPage(tableSpaceUUID, tableUuid, 1L));
assertEquals(1, dataStorageManager.getActualNumberOfPages(tableSpaceUUID, tableUuid));
{
GetResult result = manager.get(new GetStatement(tableSpace, tableName, Bytes.from_string("key1"), null, false), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
assertTrue(result.found());
}
manager.checkpoint();
assertEquals(1, dataStorageManager.getActualNumberOfPages(tableSpaceUUID, tableUuid));
{
Record record = new Record(Bytes.from_string("key1"), Bytes.from_string("5"));
UpdateStatement st = new UpdateStatement(tableSpace, tableName, record, null);
assertEquals(1, manager.executeUpdate(st, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION).getUpdateCount());
}
// a new page must be allocated
manager.checkpoint();
assertEquals(1, dataStorageManager.getActualNumberOfPages(tableSpaceUUID, tableUuid));
{
Record record = new Record(Bytes.from_string("key1"), Bytes.from_string("6"));
UpdateStatement st = new UpdateStatement(tableSpace, tableName, record, null);
assertEquals(1, manager.executeUpdate(st, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION).getUpdateCount());
}
{
Record record = new Record(Bytes.from_string("key1"), Bytes.from_string("7"));
UpdateStatement st = new UpdateStatement(tableSpace, tableName, record, null);
assertEquals(1, manager.executeUpdate(st, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION).getUpdateCount());
}
// only a new page must be allocated, not two more
manager.checkpoint();
assertEquals(1, dataStorageManager.getActualNumberOfPages(tableSpaceUUID, tableUuid));
{
DeleteStatement st = new DeleteStatement(tableSpace, tableName, Bytes.from_string("key1"), null);
assertEquals(1, manager.executeUpdate(st, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION).getUpdateCount());
GetResult result = manager.get(new GetStatement(tableSpace, tableName, Bytes.from_string("key1"), null, false), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
assertFalse(result.found());
}
// a delete does not trigger new pages in this case
manager.checkpoint();
assertEquals(0, dataStorageManager.getActualNumberOfPages(tableSpaceUUID, tableUuid));
{
assertEquals(1, manager.executeUpdate(new InsertStatement(tableSpace, tableName, new Record(Bytes.from_string("key2"), Bytes.from_string("50"))), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION).getUpdateCount());
assertEquals(1, manager.executeUpdate(new InsertStatement(tableSpace, tableName, new Record(Bytes.from_string("key3"), Bytes.from_string("60"))), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION).getUpdateCount());
}
manager.checkpoint();
assertEquals(1, dataStorageManager.getActualNumberOfPages(tableSpaceUUID, tableUuid));
{
DeleteStatement st = new DeleteStatement(tableSpace, tableName, Bytes.from_string("key2"), null);
assertEquals(1, manager.executeUpdate(st, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION).getUpdateCount());
}
// a new page, containg the key3 record is needed
manager.checkpoint();
assertEquals(1, dataStorageManager.getActualNumberOfPages(tableSpaceUUID, tableUuid));
Holder<TableStatus> _tableStatus = new Holder<>();
dataStorageManager.fullTableScan(tableSpaceUUID, tableUuid, new FullTableScanConsumer() {
@Override
public void acceptTableStatus(TableStatus tableStatus) {
_tableStatus.value = tableStatus;
}
});
for (long pageId : _tableStatus.value.activePages.keySet()) {
List<Record> records = dataStorageManager.readPage(tableSpaceUUID, tableUuid, pageId);
System.out.println("PAGE #" + pageId + " records :" + records);
}
assertEquals(1, _tableStatus.value.activePages.size());
}
Aggregations