All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.datarouter.filesystem.snapshot.reader.SnapshotIdReader Maven / Gradle / Ivy

The newest version!
/*
 * Copyright © 2009 HotPads ([email protected])
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.datarouter.filesystem.snapshot.reader;

import io.datarouter.bytes.Bytes;
import io.datarouter.filesystem.snapshot.block.BlockKey;
import io.datarouter.filesystem.snapshot.block.branch.BranchBlock;
import io.datarouter.filesystem.snapshot.block.leaf.LeafBlock;
import io.datarouter.filesystem.snapshot.block.leaf.LeafBlock.ValueLocation;
import io.datarouter.filesystem.snapshot.block.root.RootBlock;
import io.datarouter.filesystem.snapshot.block.value.ValueBlock;
import io.datarouter.filesystem.snapshot.cache.LatestBlockCache;
import io.datarouter.filesystem.snapshot.key.SnapshotKey;
import io.datarouter.filesystem.snapshot.reader.block.BlockLoader;
import io.datarouter.filesystem.snapshot.reader.record.SnapshotLeafRecord;
import io.datarouter.filesystem.snapshot.reader.record.SnapshotRecord;

/**
 * Not thread-safe because of LatestBlockCache
 */
public class SnapshotIdReader{

	private final SnapshotKey snapshotKey;
	private final BlockLoader blockLoader;
	private final RootBlock rootBlock;

	public SnapshotIdReader(SnapshotKey snapshotKey, BlockLoader blockLoader){
		this.snapshotKey = snapshotKey;
		// always add LatestBlockCache as it's essential for performance
		this.blockLoader = new LatestBlockCache(snapshotKey, blockLoader);
		this.rootBlock = blockLoader.root(BlockKey.root(snapshotKey));
	}

	public SnapshotLeafRecord leafRecord(long recordId){
		LeafBlock leafBlock = leafBlock(recordId);
		return leafBlock.snapshotLeafRecord(recordId);
	}

	public SnapshotRecord getRecord(long recordId){
		LeafBlock leafBlock = leafBlock(recordId);
		Bytes key = leafBlock.snapshotKey(recordId);
		Bytes value = leafBlock.snapshotValue(recordId);
		int numColumns = rootBlock.numColumns();
		byte[][] columnValues = new byte[numColumns][];
		for(int column = 0; column < numColumns; ++column){
			ValueLocation valueLocation = leafBlock.getValueBlock(column, recordId);
			BlockKey valueBlockKey = leafBlock.valueBlockKey(
					snapshotKey,
					column,
					valueLocation.valueBlockId);
			ValueBlock valueBlock = blockLoader.value(valueBlockKey);
			Bytes columnValue = valueBlock.value(valueLocation.valueIndex);
			columnValues[column] = columnValue.toArray();
		}
		return new SnapshotRecord(recordId, key.toArray(), value.toArray(), columnValues);
	}

	private LeafBlock leafBlock(long recordId){
		BlockKey rootBranchBlockKey = rootBlock.rootBranchBlockKey(snapshotKey);
		BranchBlock branchBlock = blockLoader.branch(rootBranchBlockKey);
		for(int level = rootBlock.maxBranchLevel() - 1; level >= 0; --level){
			int childBlockIndex = branchBlock.findChildBlockIndex(recordId);
			int childBlockId = branchBlock.childBlock(childBlockIndex);
			BlockKey branchBlockKey = branchBlock.childBranchBlockKey(
					snapshotKey,
					childBlockId);
			branchBlock = blockLoader.branch(branchBlockKey);
		}
		int leafBlockIndex = branchBlock.findChildBlockIndex(recordId);
		int leafBlockId = branchBlock.childBlock(leafBlockIndex);
		BlockKey leafBlockKey = branchBlock.leafBlockKey(snapshotKey, leafBlockId);
		return blockLoader.leaf(leafBlockKey);
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy