/** * Getting the data related to the given data key. * * @param pDataKey searched for * @return the related data * @throws TTIOException if the read to the persistent storage fails */ public IData getData(final long pDataKey) throws TTIOException { checkArgument(pDataKey >= 0); checkState(!mClose, "Transaction already closed"); // Calculate bucket and data part for given datakey. final long seqBucketKey = pDataKey >> IConstants.INDIRECT_BUCKET_COUNT[3]; final int dataBucketOffset = dataBucketOffset(pDataKey); DataBucket bucket = mCache.getIfPresent(seqBucketKey); if (bucket == null) { final List<DataBucket> listRevs = getSnapshotBuckets(seqBucketKey); final DataBucket[] revs = listRevs.toArray(new DataBucket[listRevs.size()]); checkState(revs.length > 0, "Number of Buckets to reconstruct must be larger than 0"); // Build up the complete bucket. final IRevisioning revision = mSession.getConfig().mRevision; bucket = revision.combineBuckets(revs); mCache.put(seqBucketKey, bucket); } final IData returnVal = bucket.getData(dataBucketOffset); // root-fsys is excluded from the checkagainst deletion based on the necesssity of the // data-layer to // reference against this data while creation of the transaction if (pDataKey == 0) { return returnVal; } else { return checkItemIfDeleted(returnVal); } }
/** * Closing this Readtransaction. * * @throws TTIOException if the closing to the persistent storage fails. */ public boolean close() throws TTIOException { if (!mClose) { mSession.deregisterBucketTrx(this); mBucketReader.close(); mClose = true; return true; } else { return false; } }
/** * Dereference data bucket reference. * * @param pSeqDataBucketKey Key of data bucket. * @return Dereferenced bucket. * @throws TTIOException if something odd happens within the creation process. */ protected final List<DataBucket> getSnapshotBuckets(final long pSeqDataBucketKey) throws TTIOException { // Return Value, since the revision iterates a flexible number of version, this has to be a list // first. final List<DataBucket> dataBuckets = new ArrayList<DataBucket>(); // Getting the keys for the revRoots final long[] pathToRoot = BucketReadTrx.dereferenceLeafOfTree( mBucketReader, mUberBucket.getReferenceKeys()[IReferenceBucket.GUARANTEED_INDIRECT_OFFSET], mRootBucket.getRevision()); final RevisionRootBucket rootBucket = (RevisionRootBucket) mBucketReader.read(pathToRoot[IConstants.INDIRECT_BUCKET_COUNT.length]); final int numbersToRestore = Integer.parseInt( mSession.getConfig().mProperties.getProperty(ConstructorProps.NUMBERTORESTORE)); // starting from the current databucket final long[] pathToRecentBucket = dereferenceLeafOfTree( mBucketReader, rootBucket.getReferenceKeys()[IReferenceBucket.GUARANTEED_INDIRECT_OFFSET], pSeqDataBucketKey); DataBucket bucket; long bucketKey = pathToRecentBucket[IConstants.INDIRECT_BUCKET_COUNT.length]; // jumping through the databuckets based on the pointers while (dataBuckets.size() < numbersToRestore && bucketKey > -1) { bucket = (DataBucket) mBucketReader.read(bucketKey); dataBuckets.add(bucket); bucketKey = bucket.getLastBucketPointer(); } // check if bucket was ever written before to perform check if (bucketKey > -1) { checkStructure(mBucketReader, pathToRecentBucket, rootBucket, pSeqDataBucketKey); checkStructure(mBucketReader, pathToRoot, mUberBucket, mRootBucket.getRevision()); } return dataBuckets; }