use of herddb.log.CommitLogResult in project herddb by diennea.
the class FileCommitLog method log.
@Override
public CommitLogResult log(LogEntry edit, boolean sync) throws LogNotAvailableException {
if (failed) {
throw new LogNotAvailableException("file commit log is failed");
}
boolean hasListeners = isHasListeners();
if (hasListeners) {
sync = true;
}
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.log(Level.FINEST, "log {0}", edit);
}
LogEntryHolderFuture future = new LogEntryHolderFuture(edit, sync);
try {
queueSize.incrementAndGet();
pendingEntries.incrementAndGet();
writeQueue.put(future);
if (!sync) {
return new CommitLogResult(future.ack, false, /* deferred */
false);
} else {
if (hasListeners) {
future.ack.thenAccept((pos) -> {
notifyListeners(pos, edit);
});
}
return new CommitLogResult(future.ack, false, /* deferred */
true);
}
} catch (InterruptedException err) {
Thread.currentThread().interrupt();
throw new LogNotAvailableException(err);
}
}
use of herddb.log.CommitLogResult in project herddb by diennea.
the class BookkeeperCommitLog method log.
@Override
public CommitLogResult log(LogEntry edit, boolean sync) {
CompletableFuture<LogSequenceNumber> res;
CommitFileWriter _writer = null;
try {
_writer = getValidWriter();
} catch (LogNotAvailableException errorWhileRollingLedger) {
LOGGER.log(Level.SEVERE, "Cannot get a valid writer for " + tableSpaceDescription(), errorWhileRollingLedger);
}
if (failed) {
res = FutureUtils.exception(new LogNotAvailableException(new Exception("this commitlog is failed, tablespace " + tableSpaceDescription() + ", node " + this.localNodeId)).fillInStackTrace());
} else if (closed || _writer == null) {
res = FutureUtils.exception(new LogNotAvailableException(new Exception("this commitlog has been closed, tablespace " + tableSpaceDescription() + ", node " + this.localNodeId)).fillInStackTrace());
} else {
res = _writer.writeEntry(edit);
// publish the lastSequenceNumber
// we must return a new CompletableFuture that completes only
// AFTER lastSequenceNumber is updated
// otherwise while doing a checkpoint we could observe
// an old value for lastSequenceNumber
// in case of a slow system
res = res.thenApply((pos) -> {
if (lastLedgerId == pos.ledgerId) {
lastSequenceNumber.accumulateAndGet(pos.offset, EnsureLongIncrementAccumulator.INSTANCE);
}
notifyListeners(pos, edit);
return pos;
});
}
if (!sync) {
// sending a fake completed result
return new CommitLogResult(CompletableFuture.completedFuture(null), true, /*
* deferred
*/
false);
} else {
return new CommitLogResult(res, false, /*
* deferred
*/
true);
}
}
use of herddb.log.CommitLogResult in project herddb by diennea.
the class FileCommitLogTest method testMaxBatchSize.
@Test
public void testMaxBatchSize() throws Exception {
TestStatsProvider testStatsProvider = new TestStatsProvider();
TestStatsProvider.TestStatsLogger statsLogger = testStatsProvider.getStatsLogger("test");
try (FileCommitLogManager manager = new FileCommitLogManager(folder.newFolder().toPath(), ServerConfiguration.PROPERTY_MAX_LOG_FILE_SIZE_DEFAULT, // flush only when we have 2 entries in the queue
2, // no flush by size
Integer.MAX_VALUE, // no flush by time
Integer.MAX_VALUE, true, /* require fsync */
false, /* O_DIRECT */
ServerConfiguration.PROPERTY_DEFERRED_SYNC_PERIOD_DEFAULT, statsLogger)) {
manager.start();
int writeCount = 0;
final long _startWrite = System.currentTimeMillis();
try (FileCommitLog log = manager.createCommitLog("tt", "aa", "nodeid")) {
log.startWriting(1);
CopyOnWriteArrayList<LogSequenceNumber> completed = new CopyOnWriteArrayList<>();
CommitLogResult future = log.log(LogEntryFactory.beginTransaction(0), true);
future.logSequenceNumber.thenAccept(completed::add);
assertFalse(future.logSequenceNumber.isDone());
CommitLogResult future2 = log.log(LogEntryFactory.beginTransaction(0), true);
future2.logSequenceNumber.thenAccept(completed::add);
future.logSequenceNumber.get(10, TimeUnit.SECONDS);
future2.logSequenceNumber.get(10, TimeUnit.SECONDS);
TestUtils.waitForCondition(() -> {
return completed.size() == 2;
}, NOOP, 100);
writeCount = completed.size();
assertTrue(completed.get(1).after(completed.get(0)));
}
final long _endWrite = System.currentTimeMillis();
AtomicInteger readCount = new AtomicInteger();
try (CommitLog log = manager.createCommitLog("tt", "aa", "nodeid")) {
log.recovery(LogSequenceNumber.START_OF_TIME, new BiConsumer<LogSequenceNumber, LogEntry>() {
@Override
public void accept(LogSequenceNumber t, LogEntry u) {
readCount.incrementAndGet();
}
}, true);
}
final long _endRead = System.currentTimeMillis();
assertEquals(writeCount, readCount.get());
System.out.println("Write time: " + (_endWrite - _startWrite) + " ms");
System.out.println("Read time: " + (_endRead - _endWrite) + " ms");
}
}
use of herddb.log.CommitLogResult in project herddb by diennea.
the class TableSpaceManager method dropTable.
private StatementExecutionResult dropTable(DropTableStatement statement, Transaction transaction) throws StatementExecutionException {
generalLock.writeLock().lock();
try {
if (!tables.containsKey(statement.getTable())) {
if (statement.isIfExists()) {
return new DDLStatementExecutionResult(transaction != null ? transaction.transactionId : 0);
}
throw new TableDoesNotExistException("table does not exist " + statement.getTable() + " on tableSpace " + statement.getTableSpace());
}
if (transaction != null && transaction.isTableDropped(statement.getTable())) {
if (statement.isIfExists()) {
return new DDLStatementExecutionResult(transaction.transactionId);
}
throw new TableDoesNotExistException("table does not exist " + statement.getTable() + " on tableSpace " + statement.getTableSpace());
}
Map<String, AbstractIndexManager> indexesOnTable = indexesByTable.get(statement.getTable());
if (indexesOnTable != null) {
for (String index : indexesOnTable.keySet()) {
LogEntry entry = LogEntryFactory.dropIndex(index, transaction);
CommitLogResult pos = log.log(entry, entry.transactionId <= 0);
apply(pos, entry, false);
}
}
LogEntry entry = LogEntryFactory.dropTable(statement.getTable(), transaction);
CommitLogResult pos = log.log(entry, entry.transactionId <= 0);
apply(pos, entry, false);
return new DDLStatementExecutionResult(entry.transactionId);
} catch (DataStorageManagerException | LogNotAvailableException err) {
throw new StatementExecutionException(err);
} finally {
generalLock.writeLock().unlock();
}
}
use of herddb.log.CommitLogResult in project herddb by diennea.
the class TableSpaceManager method createTable.
private StatementExecutionResult createTable(CreateTableStatement statement, Transaction transaction) throws StatementExecutionException {
generalLock.writeLock().lock();
try {
if (tables.containsKey(statement.getTableDefinition().name)) {
throw new TableAlreadyExistsException(statement.getTableDefinition().name);
}
for (Index additionalIndex : statement.getAdditionalIndexes()) {
if (indexes.containsKey(additionalIndex.name)) {
throw new IndexAlreadyExistsException(additionalIndex.name);
}
}
LogEntry entry = LogEntryFactory.createTable(statement.getTableDefinition(), transaction);
CommitLogResult pos = log.log(entry, entry.transactionId <= 0);
apply(pos, entry, false);
for (Index additionalIndex : statement.getAdditionalIndexes()) {
LogEntry index_entry = LogEntryFactory.createIndex(additionalIndex, transaction);
CommitLogResult index_pos = log.log(index_entry, index_entry.transactionId <= 0);
apply(index_pos, index_entry, false);
}
return new DDLStatementExecutionResult(entry.transactionId);
} catch (DataStorageManagerException | LogNotAvailableException err) {
throw new StatementExecutionException(err);
} finally {
generalLock.writeLock().unlock();
}
}
Aggregations