| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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 org.apache.hadoop.hbase.regionserver; |
| |
| import java.io.IOException; |
| import java.util.Arrays; |
| import java.util.Map; |
| import java.util.Optional; |
| import java.util.OptionalLong; |
| import java.util.TreeMap; |
| |
| import org.apache.hadoop.fs.Path; |
| import org.apache.hadoop.hbase.Cell; |
| import org.apache.hadoop.hbase.CellBuilderFactory; |
| import org.apache.hadoop.hbase.CellBuilderType; |
| import org.apache.hadoop.hbase.HBaseTestingUtility; |
| import org.apache.hadoop.hbase.HDFSBlocksDistribution; |
| import org.apache.hadoop.hbase.io.hfile.CacheConfig; |
| import org.apache.hadoop.hbase.util.Bytes; |
| import org.apache.hadoop.hbase.util.DNS; |
| import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; |
| import org.apache.yetus.audience.InterfaceAudience; |
| |
| /** A mock used so our tests don't deal with actual StoreFiles */ |
| @InterfaceAudience.Private |
| public class MockHStoreFile extends HStoreFile { |
| long length = 0; |
| boolean isRef = false; |
| long ageInDisk; |
| long sequenceid; |
| private Map<byte[], byte[]> metadata = new TreeMap<>(Bytes.BYTES_COMPARATOR); |
| byte[] splitPoint = null; |
| TimeRangeTracker timeRangeTracker; |
| long entryCount; |
| boolean isMajor; |
| HDFSBlocksDistribution hdfsBlocksDistribution; |
| long modificationTime; |
| boolean compactedAway; |
| |
| MockHStoreFile(HBaseTestingUtility testUtil, Path testPath, |
| long length, long ageInDisk, boolean isRef, long sequenceid) throws IOException { |
| super(testUtil.getTestFileSystem(), testPath, testUtil.getConfiguration(), |
| new CacheConfig(testUtil.getConfiguration()), BloomType.NONE, true); |
| this.length = length; |
| this.isRef = isRef; |
| this.ageInDisk = ageInDisk; |
| this.sequenceid = sequenceid; |
| this.isMajor = false; |
| hdfsBlocksDistribution = new HDFSBlocksDistribution(); |
| hdfsBlocksDistribution.addHostsAndBlockWeight(new String[] |
| { DNS.getHostname(testUtil.getConfiguration(), DNS.ServerType.REGIONSERVER) }, 1); |
| modificationTime = EnvironmentEdgeManager.currentTime(); |
| } |
| |
| void setLength(long newLen) { |
| this.length = newLen; |
| } |
| |
| @Override |
| public long getMaxSequenceId() { |
| return sequenceid; |
| } |
| |
| @Override |
| public boolean isMajorCompactionResult() { |
| return isMajor; |
| } |
| |
| public void setIsMajor(boolean isMajor) { |
| this.isMajor = isMajor; |
| } |
| |
| @Override |
| public boolean isReference() { |
| return this.isRef; |
| } |
| |
| @Override |
| public boolean isBulkLoadResult() { |
| return false; |
| } |
| |
| @Override |
| public byte[] getMetadataValue(byte[] key) { |
| return this.metadata.get(key); |
| } |
| |
| public void setMetadataValue(byte[] key, byte[] value) { |
| this.metadata.put(key, value); |
| } |
| |
| void setTimeRangeTracker(TimeRangeTracker timeRangeTracker) { |
| this.timeRangeTracker = timeRangeTracker; |
| } |
| |
| void setEntries(long entryCount) { |
| this.entryCount = entryCount; |
| } |
| |
| @Override |
| public OptionalLong getMinimumTimestamp() { |
| return timeRangeTracker == null ? OptionalLong.empty() |
| : OptionalLong.of(timeRangeTracker.getMin()); |
| } |
| |
| @Override |
| public OptionalLong getMaximumTimestamp() { |
| return timeRangeTracker == null ? OptionalLong.empty() |
| : OptionalLong.of(timeRangeTracker.getMax()); |
| } |
| |
| @Override |
| public void markCompactedAway() { |
| this.compactedAway = true; |
| } |
| |
| @Override |
| public boolean isCompactedAway() { |
| return compactedAway; |
| } |
| |
| @Override |
| public long getModificationTimestamp() { |
| return modificationTime; |
| } |
| |
| @Override |
| public HDFSBlocksDistribution getHDFSBlockDistribution() { |
| return hdfsBlocksDistribution; |
| } |
| |
| @Override |
| public void initReader() throws IOException { |
| } |
| |
| @Override |
| public StoreFileScanner getPreadScanner(boolean cacheBlocks, long readPt, long scannerOrder, |
| boolean canOptimizeForNonNullColumn) { |
| return getReader().getStoreFileScanner(cacheBlocks, true, false, readPt, scannerOrder, |
| canOptimizeForNonNullColumn); |
| } |
| |
| @Override |
| public StoreFileScanner getStreamScanner(boolean canUseDropBehind, boolean cacheBlocks, |
| boolean isCompaction, long readPt, long scannerOrder, boolean canOptimizeForNonNullColumn) |
| throws IOException { |
| return getReader().getStoreFileScanner(cacheBlocks, false, isCompaction, readPt, scannerOrder, |
| canOptimizeForNonNullColumn); |
| } |
| |
| @Override |
| public StoreFileReader getReader() { |
| final long len = this.length; |
| final TimeRangeTracker timeRangeTracker = this.timeRangeTracker; |
| final long entries = this.entryCount; |
| return new StoreFileReader() { |
| @Override |
| public long length() { |
| return len; |
| } |
| |
| @Override |
| public long getMaxTimestamp() { |
| return timeRange == null? Long.MAX_VALUE: timeRangeTracker.getMax(); |
| } |
| |
| @Override |
| public long getEntries() { |
| return entries; |
| } |
| |
| @Override |
| public void close(boolean evictOnClose) throws IOException { |
| // no-op |
| } |
| |
| @Override |
| public Optional<Cell> getLastKey() { |
| if (splitPoint != null) { |
| return Optional.of(CellBuilderFactory.create(CellBuilderType.DEEP_COPY) |
| .setType(Cell.Type.Put) |
| .setRow(Arrays.copyOf(splitPoint, splitPoint.length + 1)).build()); |
| } else { |
| return Optional.empty(); |
| } |
| } |
| |
| @Override |
| public Optional<Cell> midKey() throws IOException { |
| if (splitPoint != null) { |
| return Optional.of(CellBuilderFactory.create(CellBuilderType.DEEP_COPY) |
| .setType(Cell.Type.Put).setRow(splitPoint).build()); |
| } else { |
| return Optional.empty(); |
| } |
| } |
| |
| @Override |
| public Optional<Cell> getFirstKey() { |
| if (splitPoint != null) { |
| return Optional.of(CellBuilderFactory.create(CellBuilderType.DEEP_COPY) |
| .setType(Cell.Type.Put).setRow(splitPoint, 0, splitPoint.length - 1) |
| .build()); |
| } else { |
| return Optional.empty(); |
| } |
| } |
| }; |
| } |
| |
| @Override |
| public OptionalLong getBulkLoadTimestamp() { |
| // we always return false for isBulkLoadResult so we do not have a bulk load timestamp |
| return OptionalLong.empty(); |
| } |
| } |