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;
}
use of herddb.model.Record in project herddb by diennea.
the class TableSpaceDumpFileWriter method receiveTableDataChunk.
@Override
public void receiveTableDataChunk(List<Record> record) throws DataStorageManagerException {
try {
out.writeVInt(record.size());
for (Record r : record) {
out.writeArray(r.key.data);
out.writeArray(r.value.data);
}
tableRecordsCount += record.size();
} catch (IOException err) {
throw new DataStorageManagerException(err);
}
listener.log("receivedata", "table " + currentTable + ", dumped " + tableRecordsCount + " records", Collections.singletonMap("count", tableRecordsCount));
}
use of herddb.model.Record in project herddb by diennea.
the class TableManager method applyInsert.
private void applyInsert(Bytes key, Bytes value, boolean onTransaction) throws DataStorageManagerException {
if (table.auto_increment) {
// the next auto_increment value MUST be greater than every other explict value
long pk_logical_value;
if (table.getColumn(table.primaryKey[0]).type == ColumnTypes.INTEGER) {
pk_logical_value = key.to_int();
} else {
pk_logical_value = key.to_long();
}
nextPrimaryKeyValue.accumulateAndGet(pk_logical_value + 1, EnsureLongIncrementAccumulator.INSTANCE);
}
/*
* New record to be added, it will always added if there aren't DataStorageManagerException thus is
* simpler to create the record now
*/
final Record record = new Record(key, value);
/* Normally we expect this value null or pointing to a temporary modifiable page */
final Long prevPageId = keyToPage.get(key);
final Map<String, AbstractIndexManager> indexes = tableSpaceManager.getIndexesOnTable(table.name);
/*
* When index is enabled we need the old value to update them, we'll force the page load only if that
* record is really needed.
*/
final DataPage prevPage;
final Record previous;
boolean insertedInSamePage = false;
if (prevPageId != null) {
/* Very strage but possible inside a transaction which executes DELETE THEN INSERT */
if (!onTransaction) {
throw new DataStorageManagerException("new record " + key + " already present in keyToPage?");
}
if (indexes == null) {
/* We don't need the page if isn't loaded or isn't a mutable new page*/
prevPage = newPages.get(prevPageId);
previous = null;
if (prevPage != null) {
pageReplacementPolicy.pageHit(prevPage);
}
} else {
/* We really need the page for update index old values */
prevPage = loadPageToMemory(prevPageId, false);
previous = prevPage.get(key);
if (previous == null) {
throw new RuntimeException("insert upon delete record at " + key + " was not found?");
}
}
if (prevPage == null || prevPage.immutable) {
/* Unloaded or immutable, set it as dirty */
pageSet.setPageDirty(prevPageId, previous);
} else {
/* Mutable page, need to check if still modifiable or already unloaded */
final Lock lock = prevPage.pageLock.readLock();
lock.lock();
try {
if (prevPage.writable) {
/* We can try to modify the page directly */
insertedInSamePage = prevPage.put(record);
} else {
/* Unfortunately is not writable (anymore), set it as dirty */
pageSet.setPageDirty(prevPageId, previous);
}
} finally {
lock.unlock();
}
}
} else {
/*
* Initialize previous record to null... Non really needed but otherwise compiler cannot compile
* indexing instructions below.
*/
previous = null;
}
/* Insertion page */
Long insertionPageId;
if (insertedInSamePage) {
/* Inserted in temporary mutable previous page, no need to alter keyToPage too: no record page change */
insertionPageId = prevPageId;
} else {
/* Do real insertion */
insertionPageId = currentDirtyRecordsPage.get();
while (true) {
final DataPage newPage = newPages.get(insertionPageId);
if (newPage != null) {
pageReplacementPolicy.pageHit(newPage);
/* The temporary memory page could have been unloaded and loaded again in meantime */
if (!newPage.immutable) {
/* Mutable page, need to check if still modifiable or already unloaded */
final Lock lock = newPage.pageLock.readLock();
lock.lock();
try {
if (newPage.writable) {
/* We can try to modify the page directly */
if (newPage.put(record)) {
break;
}
}
} finally {
lock.unlock();
}
}
}
/* Try allocate a new page if no already done */
insertionPageId = allocateLivePage(insertionPageId);
}
/* Insert/update the value on keyToPage */
keyToPage.put(key, insertionPageId);
}
if (LOGGER.isLoggable(Level.FINEST)) {
if (prevPageId == null) {
LOGGER.log(Level.FINEST, "Inserted key " + key + " into page " + insertionPageId);
} else {
LOGGER.log(Level.FINEST, "Inserted key " + key + " into page " + insertionPageId + " previously was in page " + prevPageId);
}
}
if (indexes != null) {
if (previous == null) {
/* Standard insert */
DataAccessor values = record.getDataAccessor(table);
for (AbstractIndexManager index : indexes.values()) {
index.recordInserted(key, values);
}
} else {
/* If there is a previous page this is a delete and insert, we really need to update indexes
* from old "deleted" values to the new ones. Previus record has already been loaded */
DataAccessor prevValues = previous.getDataAccessor(table);
DataAccessor newValues = record.getDataAccessor(table);
for (AbstractIndexManager index : indexes.values()) {
index.recordUpdated(key, prevValues, newValues);
}
}
}
}
use of herddb.model.Record in project herddb by diennea.
the class TableManager method applyUpdate.
private void applyUpdate(Bytes key, Bytes value) throws DataStorageManagerException {
/*
* New record to be updated, it will always updated if there aren't errors thus is simpler to create
* the record now
*/
final Record record = new Record(key, value);
/* This could be a normal or a temporary modifiable page */
final Long prevPageId = keyToPage.get(key);
if (prevPageId == null) {
throw new IllegalStateException("corrupted transaction log: key " + key + " is not present in table " + table.name);
}
/*
* We'll try to replace the record if in a writable page, otherwise we'll simply set the old page
* as dirty and continue like a normal insertion
*/
final Map<String, AbstractIndexManager> indexes = tableSpaceManager.getIndexesOnTable(table.name);
/*
* When index is enabled we need the old value to update them, we'll force the page load only if that
* record is really needed.
*/
final DataPage prevPage;
final Record previous;
boolean insertedInSamePage = false;
if (indexes == null) {
/* We don't need the page if isn't loaded or isn't a mutable new page*/
prevPage = newPages.get(prevPageId);
if (prevPage != null) {
pageReplacementPolicy.pageHit(prevPage);
previous = prevPage.get(key);
} else {
previous = null;
}
} else {
/* We really need the page for update index old values */
prevPage = loadPageToMemory(prevPageId, false);
previous = prevPage.get(key);
if (previous == null) {
throw new RuntimeException("updated record at " + key + " was not found?");
}
}
if (prevPage == null || prevPage.immutable) {
/* Unloaded or immutable, set it as dirty */
pageSet.setPageDirty(prevPageId, previous);
} else {
/* Mutable page, need to check if still modifiable or already unloaded */
final Lock lock = prevPage.pageLock.readLock();
lock.lock();
try {
if (prevPage.writable) {
/* We can try to modify the page directly */
insertedInSamePage = prevPage.put(record);
} else {
/* Unfortunately is not writable (anymore), set it as dirty */
pageSet.setPageDirty(prevPageId, previous);
}
} finally {
lock.unlock();
}
}
/* Insertion page */
Long insertionPageId;
if (insertedInSamePage) {
/* Inserted in temporary mutable previous page, no need to alter keyToPage too: no record page change */
insertionPageId = prevPageId;
} else {
/* Do real insertion */
insertionPageId = currentDirtyRecordsPage.get();
while (true) {
final DataPage newPage = newPages.get(insertionPageId);
if (newPage != null) {
pageReplacementPolicy.pageHit(newPage);
/* The temporary memory page could have been unloaded and loaded again in meantime */
if (!newPage.immutable) {
/* Mutable page, need to check if still modifiable or already unloaded */
final Lock lock = newPage.pageLock.readLock();
lock.lock();
try {
if (newPage.writable) {
/* We can try to modify the page directly */
if (newPage.put(record)) {
break;
}
}
} finally {
lock.unlock();
}
}
}
/* Try allocate a new page if no already done */
insertionPageId = allocateLivePage(insertionPageId);
}
/* Update the value on keyToPage */
keyToPage.put(key, insertionPageId);
}
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.log(Level.FINEST, "Updated key " + key + " from page " + prevPageId + " to page " + insertionPageId);
}
if (indexes != null) {
/* If there are indexes e have already forced a page load and previous record has been loaded */
DataAccessor prevValues = previous.getDataAccessor(table);
DataAccessor newValues = record.getDataAccessor(table);
for (AbstractIndexManager index : indexes.values()) {
index.recordUpdated(key, prevValues, newValues);
}
}
}
use of herddb.model.Record in project herddb by diennea.
the class SyscolumnsTableManager method buildVirtualRecordList.
@Override
protected Iterable<Record> buildVirtualRecordList() {
List<Table> tables = tableSpaceManager.getAllCommittedTables();
List<Record> result = new ArrayList<>();
for (Table t : tables) {
int pos = 1;
for (Column c : t.columns) {
boolean pk = t.isPrimaryKeyColumn(c.name);
String data_type = ColumnTypes.typeToString(c.type);
result.add(RecordSerializer.makeRecord(table, "table_name", t.name, "column_name", c.name, "ordinal_position", pos++, "is_nullable", pk ? 0 : 1, "data_type", data_type, "auto_increment", (pk && t.auto_increment) ? 1 : 0));
}
}
return result;
}
Aggregations