use of herddb.model.Record in project herddb by diennea.
the class TableManager method flushNewPage.
/**
* Remove the page from {@link #newPages}, set it as "unloaded" and write it to disk
* <p>
* Add as much spare data as possible to fillup the page. If added must change key to page pointers too for spare
* data
* </p>
*
* @param page new page to flush
* @param spareData old spare data to fit in the new page if possible
* @return spare memory size used (and removed), {@code 0} if no spare used,
* {@code -1L} if no flush has been done because the page isn't writable anymore
*/
private long flushNewPage(DataPage page, Map<Bytes, Record> spareData) {
if (page.immutable) {
LOGGER.log(Level.SEVERE, "Attempt to flush an immutable page " + page.pageId + " as it was mutable");
throw new IllegalStateException("page " + page.pageId + " is not a new page!");
}
page.pageLock.readLock().lock();
try {
if (!page.writable) {
return -1L;
}
} finally {
page.pageLock.readLock().unlock();
}
/*
* We need to keep the page lock just to write the unloaded flag... after that write any other
* thread that check the page will avoid writes (thus using page data is safe).
*/
final Lock lock = page.pageLock.writeLock();
lock.lock();
try {
if (!page.writable) {
LOGGER.log(Level.INFO, "Mutable page " + page.pageId + " already flushed in a concurrent thread");
return -1L;
}
/*
* NewPages removal technically could be done before current write lock but
* doing it in lock permit to check safely if a page has been removed. Without
* lock we can't known if no page has been removed because already removed by a
* concurrent thread or because it wasn't present in the first place.
*/
/* Remove it from "new" pages */
DataPage remove = newPages.remove(page.pageId);
if (remove == null) {
LOGGER.log(Level.SEVERE, "Detected concurrent flush of page " + page.pageId + ", writable: " + page.writable);
throw new IllegalStateException("page " + page.pageId + " is not a new page!");
}
/* Set the new page as a fully active page */
pageSet.pageCreated(page.pageId, page);
page.writable = false;
} finally {
lock.unlock();
}
long usedMemory = page.getUsedMemory();
/* Flag to enable spare data addition to currently flushed page */
boolean add = true;
final Iterator<Record> records = spareData.values().iterator();
while (add && records.hasNext()) {
Record record = records.next();
add = page.put(record);
if (add) {
keyToPage.put(record.key, page.pageId);
records.remove();
}
}
long spareUsedMemory = page.getUsedMemory() - usedMemory;
LOGGER.log(Level.FINER, "flushNewPage table {0}, pageId={1} with {2} records, {3} logical page size", new Object[] { table.name, page.pageId, page.size(), page.getUsedMemory() });
dataStorageManager.writePage(tableSpaceUUID, table.uuid, page.pageId, page.data.values());
return spareUsedMemory;
}
use of herddb.model.Record in project herddb by diennea.
the class TableManager method executeGet.
private StatementExecutionResult executeGet(GetStatement get, Transaction transaction, StatementEvaluationContext context) throws StatementExecutionException, DataStorageManagerException {
Bytes key = new Bytes(get.getKey().computeNewValue(null, context, tableContext));
Predicate predicate = get.getPredicate();
boolean requireLock = get.isRequireLock();
long transactionId = transaction != null ? transaction.transactionId : 0;
LockHandle lock = (transaction != null || requireLock) ? lockForRead(key, transaction) : null;
try {
if (transaction != null) {
if (transaction.recordDeleted(table.name, key)) {
return GetResult.NOT_FOUND(transactionId);
}
Record loadedInTransaction = transaction.recordUpdated(table.name, key);
if (loadedInTransaction != null) {
if (predicate != null && !predicate.evaluate(loadedInTransaction, context)) {
return GetResult.NOT_FOUND(transactionId);
}
return new GetResult(transactionId, loadedInTransaction, table);
}
loadedInTransaction = transaction.recordInserted(table.name, key);
if (loadedInTransaction != null) {
if (predicate != null && !predicate.evaluate(loadedInTransaction, context)) {
return GetResult.NOT_FOUND(transactionId);
}
return new GetResult(transactionId, loadedInTransaction, table);
}
}
Long pageId = keyToPage.get(key);
if (pageId == null) {
return GetResult.NOT_FOUND(transactionId);
}
Record loaded = fetchRecord(key, pageId, null);
if (loaded == null || (predicate != null && !predicate.evaluate(loaded, context))) {
return GetResult.NOT_FOUND(transactionId);
}
return new GetResult(transactionId, loaded, table);
} finally {
if (transaction == null && lock != null) {
locksManager.releaseReadLockForKey(key, lock);
}
}
}
use of herddb.model.Record in project herddb by diennea.
the class SystablespacereplicastateTableManager method buildVirtualRecordList.
@Override
protected Iterable<Record> buildVirtualRecordList() throws StatementExecutionException {
try {
Collection<String> names = tableSpaceManager.getMetadataStorageManager().listTableSpaces();
long now = System.currentTimeMillis();
List<Record> result = new ArrayList<>();
for (String name : names) {
TableSpace t = tableSpaceManager.getMetadataStorageManager().describeTableSpace(name);
if (t != null) {
List<TableSpaceReplicaState> tableSpaceReplicaStates = tableSpaceManager.getMetadataStorageManager().getTableSpaceReplicaState(t.uuid);
for (TableSpaceReplicaState state : tableSpaceReplicaStates) {
result.add(RecordSerializer.makeRecord(table, "tablespace_name", t.name, "uuid", t.uuid, "nodeid", state.nodeId, "timestamp", new java.sql.Timestamp(state.timestamp), "maxleaderinactivitytime", t.maxLeaderInactivityTime, "inactivitytime", now - state.timestamp, "mode", TableSpaceReplicaState.modeToSQLString(state.mode)));
}
}
}
return result;
} catch (MetadataStorageManagerException error) {
throw new StatementExecutionException(error);
}
}
use of herddb.model.Record in project herddb by diennea.
the class SystablespacesTableManager method buildVirtualRecordList.
@Override
protected Iterable<Record> buildVirtualRecordList() throws StatementExecutionException {
try {
Collection<String> names = tableSpaceManager.getMetadataStorageManager().listTableSpaces();
List<Record> result = new ArrayList<>();
for (String name : names) {
TableSpace t = tableSpaceManager.getMetadataStorageManager().describeTableSpace(name);
if (t != null) {
result.add(RecordSerializer.makeRecord(table, "tablespace_name", t.name, "uuid", t.uuid, "leader", t.leaderId, "expectedreplicacount", t.expectedReplicaCount, "maxleaderinactivitytime", t.maxLeaderInactivityTime, "replica", t.replicas.stream().collect(Collectors.joining(","))));
}
}
return result;
} catch (MetadataStorageManagerException error) {
throw new StatementExecutionException(error);
}
}
use of herddb.model.Record in project herddb by diennea.
the class SystransactionsTableManager method buildVirtualRecordList.
@Override
protected Iterable<Record> buildVirtualRecordList() {
List<Transaction> transactions = tableSpaceManager.getTransactions();
List<Record> result = new ArrayList<>();
for (Transaction tx : transactions) {
result.add(RecordSerializer.makeRecord(table, "tablespace", tableSpaceManager.getTableSpaceName(), "txid", tx.transactionId, "creationtimestamp", new java.sql.Timestamp(tx.localCreationTimestamp)));
}
return result;
}
Aggregations