/**
  * 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;
  }