use of org.sirix.page.PageReference in project sirix by sirixdb.
the class PageReadTrxImpl method getSnapshotPages.
/**
* Dereference key/value page reference and get all leaves, the {@link KeyValuePage}s from the
* revision-trees.
*
* @param recordPageKey key of node page
* @param pageKind kind of page, that is the type of tree to dereference
* @param index index number or {@code -1}, if it's a regular record page
* @param pageReference optional page reference pointing to the first page
* @return dereferenced pages
*
* @throws SirixIOException if an I/O-error occurs within the creation process
*/
final <K extends Comparable<? super K>, V extends Record, T extends KeyValuePage<K, V>> List<T> getSnapshotPages(final PageReference pageReference) {
assert pageReference != null;
final ResourceConfiguration config = mResourceManager.getResourceConfig();
final int revsToRestore = config.mRevisionsToRestore;
final int[] revisionsToRead = config.mRevisionKind.getRevisionRoots(mRootPage.getRevision(), revsToRestore);
final List<T> pages = new ArrayList<>(revisionsToRead.length);
boolean first = true;
for (int i = 0; i < revisionsToRead.length; i++) {
long refKeyToRecordPage = Constants.NULL_ID_LONG;
if (first) {
first = false;
refKeyToRecordPage = pageReference.getKey();
} else {
refKeyToRecordPage = pages.get(pages.size() - 1).getPreviousReferenceKey();
}
if (refKeyToRecordPage != Constants.NULL_ID_LONG) {
final PageReference reference = new PageReference().setKey(refKeyToRecordPage);
if (reference.getKey() != Constants.NULL_ID_LONG) {
@SuppressWarnings("unchecked") final T page = (T) mPageReader.read(reference, this);
pages.add(page);
if (page.size() == Constants.NDP_NODE_COUNT) {
// versions.
break;
}
}
} else {
break;
}
}
return pages;
}
use of org.sirix.page.PageReference in project sirix by sirixdb.
the class PageReadTrxImpl method getRecordPageContainer.
@Override
public <K extends Comparable<? super K>, V extends Record, T extends KeyValuePage<K, V>> PageContainer getRecordPageContainer(@Nonnegative final Long recordPageKey, final int index, final PageKind pageKind) throws SirixIOException {
assertNotClosed();
checkArgument(recordPageKey >= 0, "recordPageKey must not be negative!");
final Optional<PageReference> pageReferenceToRecordPage = getLeafPageReference(checkNotNull(recordPageKey), index, checkNotNull(pageKind));
if (!pageReferenceToRecordPage.isPresent()) {
return PageContainer.emptyInstance();
}
// Try to get from resource buffer manager.
final PageContainer recordPageContainerFromBuffer = mResourceBufferManager.getRecordPageCache().get(pageReferenceToRecordPage.get());
if (recordPageContainerFromBuffer != null) {
return recordPageContainerFromBuffer;
}
// Load list of page "fragments" from persistent storage.
final List<T> pages = getSnapshotPages(pageReferenceToRecordPage.get());
if (pages.isEmpty()) {
return PageContainer.emptyInstance();
}
final int mileStoneRevision = mResourceConfig.mRevisionsToRestore;
final Versioning revisioning = mResourceConfig.mRevisionKind;
final Page completePage = revisioning.combineRecordPages(pages, mileStoneRevision, this);
final PageContainer recordPageContainer = new PageContainer(completePage, clone(completePage));
if (mTrxIntentLog == null)
mResourceBufferManager.getRecordPageCache().put(pageReferenceToRecordPage.get(), recordPageContainer);
return recordPageContainer;
}
use of org.sirix.page.PageReference in project sirix by sirixdb.
the class PageWriteTrxImpl method preparePreviousRevisionRootPage.
/**
* Prepare the previous revision root page and retrieve the next {@link RevisionRootPage}.
*
* @param baseRevision base revision
* @param representRevision the revision to represent
* @return new {@link RevisionRootPage} instance
* @throws SirixIOException if an I/O error occurs
*/
private RevisionRootPage preparePreviousRevisionRootPage(@Nonnegative final int baseRevision, @Nonnegative final int representRevision) throws SirixIOException {
if (getUberPage().isBootstrap()) {
final RevisionRootPage revisionRootPage = mPageRtx.loadRevRoot(baseRevision);
// appendLogRecord(new PageContainer(revisionRootPage, revisionRootPage));
return revisionRootPage;
} else {
// Prepare revision root nodePageReference.
final RevisionRootPage revisionRootPage = new RevisionRootPage(mPageRtx.loadRevRoot(baseRevision), representRevision + 1);
// Prepare indirect tree to hold reference to prepared revision root nodePageReference.
final PageReference revisionRootPageReference = prepareLeafOfTree(getUberPage().getIndirectPageReference(), getUberPage().getRevisionNumber(), -1, PageKind.UBERPAGE);
// Link the prepared revision root nodePageReference with the prepared indirect tree.
appendLogRecord(revisionRootPageReference, new PageContainer(revisionRootPage, revisionRootPage));
// Return prepared revision root nodePageReference.
return revisionRootPage;
}
}
use of org.sirix.page.PageReference in project sirix by sirixdb.
the class PageWriteTrxImpl method prepareLeafOfTree.
/**
* Prepare the leaf of a tree, namely the reference to a {@link UnorderedKeyValuePage}.
*
* @param startReference start reference
* @param key page key to lookup
* @param index the index number or {@code -1} if a regular record page should be prepared
* @return {@link PageReference} instance pointing to the right {@link UnorderedKeyValuePage} with
* the {@code pKey}
* @throws SirixIOException if an I/O error occured
*/
private PageReference prepareLeafOfTree(final PageReference startReference, @Nonnegative final long key, final int index, final PageKind pageKind) throws SirixIOException {
// Initial state pointing to the indirect nodePageReference of level 0.
PageReference reference = startReference;
int offset = 0;
long levelKey = key;
final int[] inpLevelPageCountExp = mPageRtx.getUberPage().getPageCountExp(pageKind);
// Iterate through all levels.
for (int level = 0, height = inpLevelPageCountExp.length; level < height; level++) {
offset = (int) (levelKey >> inpLevelPageCountExp[level]);
levelKey -= offset << inpLevelPageCountExp[level];
final IndirectPage page = prepareIndirectPage(reference);
reference = page.getReference(offset);
}
// Return reference to leaf of indirect tree.
return reference;
}
use of org.sirix.page.PageReference in project sirix by sirixdb.
the class ResourceStore method openResource.
/**
* Open a resource, that is get an instance of a {@link ResourceManager} in order to read/write
* from the resource.
*
* @param database The database.
* @param resourceConfig The resource configuration.
* @param resourceManagerConfig The resource manager configuration.
* @param bufferManager The buffer manager.
* @param resourceFile The resource to open.
* @return A resource manager.
*/
public ResourceManager openResource(@Nonnull final DatabaseImpl database, @Nonnull final ResourceConfiguration resourceConfig, @Nonnull final ResourceManagerConfiguration resourceManagerConfig, @Nonnull final BufferManager bufferManager, @Nonnull final Path resourceFile) {
checkNotNull(database);
checkNotNull(resourceConfig);
return mResourceManagers.computeIfAbsent(resourceFile, k -> {
final Storage storage = StorageType.getStorage(resourceConfig);
final UberPage uberPage;
if (storage.exists()) {
try (final Reader reader = storage.createReader()) {
final PageReference firstRef = reader.readUberPageReference();
if (firstRef.getPage() == null) {
uberPage = (UberPage) reader.read(firstRef, null);
} else {
uberPage = (UberPage) firstRef.getPage();
}
}
} else {
// Bootstrap uber page and make sure there already is a root node.
uberPage = new UberPage();
}
final ResourceManager resourceManager = new XdmResourceManager(database, this, resourceConfig, resourceManagerConfig, bufferManager, StorageType.getStorage(resourceConfig), uberPage, mReadSemaphore, mWriteSempahore);
Databases.putResourceManager(resourceFile, resourceManager);
return resourceManager;
});
}
Aggregations