001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.mob;
019
020import static org.junit.Assert.assertEquals;
021
022import org.apache.hadoop.conf.Configuration;
023import org.apache.hadoop.fs.FileSystem;
024import org.apache.hadoop.fs.Path;
025import org.apache.hadoop.hbase.Cell;
026import org.apache.hadoop.hbase.HBaseClassTestRule;
027import org.apache.hadoop.hbase.HBaseTestingUtil;
028import org.apache.hadoop.hbase.KeyValue;
029import org.apache.hadoop.hbase.KeyValue.Type;
030import org.apache.hadoop.hbase.io.hfile.CacheConfig;
031import org.apache.hadoop.hbase.io.hfile.HFileContext;
032import org.apache.hadoop.hbase.io.hfile.HFileContextBuilder;
033import org.apache.hadoop.hbase.regionserver.BloomType;
034import org.apache.hadoop.hbase.regionserver.HStoreFile;
035import org.apache.hadoop.hbase.regionserver.StoreFileInfo;
036import org.apache.hadoop.hbase.regionserver.StoreFileWriter;
037import org.apache.hadoop.hbase.testclassification.SmallTests;
038import org.apache.hadoop.hbase.util.Bytes;
039import org.junit.Assert;
040import org.junit.ClassRule;
041import org.junit.Rule;
042import org.junit.Test;
043import org.junit.experimental.categories.Category;
044import org.junit.rules.TestName;
045import org.slf4j.Logger;
046import org.slf4j.LoggerFactory;
047
048@Category(SmallTests.class)
049public class TestCachedMobFile {
050
051  @ClassRule
052  public static final HBaseClassTestRule CLASS_RULE =
053    HBaseClassTestRule.forClass(TestCachedMobFile.class);
054
055  static final Logger LOG = LoggerFactory.getLogger(TestCachedMobFile.class);
056  private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
057  private Configuration conf = TEST_UTIL.getConfiguration();
058  private CacheConfig cacheConf = new CacheConfig(conf);
059  private static final String FAMILY1 = "familyName1";
060  private static final String FAMILY2 = "familyName2";
061  private static final long EXPECTED_REFERENCE_ZERO = 0;
062  private static final long EXPECTED_REFERENCE_ONE = 1;
063  private static final long EXPECTED_REFERENCE_TWO = 2;
064  @Rule
065  public TestName testName = new TestName();
066
067  @Test
068  public void testOpenClose() throws Exception {
069    String caseName = testName.getMethodName();
070    Path testDir = TEST_UTIL.getDataTestDir();
071    FileSystem fs = testDir.getFileSystem(conf);
072    HFileContext meta = new HFileContextBuilder().withBlockSize(8 * 1024).build();
073    StoreFileWriter writer = new StoreFileWriter.Builder(conf, cacheConf, fs).withOutputDir(testDir)
074      .withFileContext(meta).build();
075    StoreFileInfo storeFileInfo =
076      StoreFileInfo.createStoreFileInfoForHFile(conf, fs, writer.getPath(), true);
077    MobTestUtil.writeStoreFile(writer, caseName);
078    CachedMobFile cachedMobFile =
079      new CachedMobFile(new HStoreFile(storeFileInfo, BloomType.NONE, cacheConf));
080    assertEquals(EXPECTED_REFERENCE_ZERO, cachedMobFile.getReferenceCount());
081    cachedMobFile.open();
082    assertEquals(EXPECTED_REFERENCE_ONE, cachedMobFile.getReferenceCount());
083    cachedMobFile.open();
084    assertEquals(EXPECTED_REFERENCE_TWO, cachedMobFile.getReferenceCount());
085    cachedMobFile.close();
086    assertEquals(EXPECTED_REFERENCE_ONE, cachedMobFile.getReferenceCount());
087    cachedMobFile.close();
088    assertEquals(EXPECTED_REFERENCE_ZERO, cachedMobFile.getReferenceCount());
089  }
090
091  @SuppressWarnings("SelfComparison")
092  @Test
093  public void testCompare() throws Exception {
094    String caseName = testName.getMethodName();
095    Path testDir = TEST_UTIL.getDataTestDir();
096    FileSystem fs = testDir.getFileSystem(conf);
097    Path outputDir1 = new Path(testDir, FAMILY1);
098    HFileContext meta = new HFileContextBuilder().withBlockSize(8 * 1024).build();
099    StoreFileWriter writer1 = new StoreFileWriter.Builder(conf, cacheConf, fs)
100      .withOutputDir(outputDir1).withFileContext(meta).build();
101    MobTestUtil.writeStoreFile(writer1, caseName);
102    StoreFileInfo storeFileInfo1 =
103      StoreFileInfo.createStoreFileInfoForHFile(conf, fs, writer1.getPath(), true);
104    CachedMobFile cachedMobFile1 =
105      new CachedMobFile(new HStoreFile(storeFileInfo1, BloomType.NONE, cacheConf));
106    Path outputDir2 = new Path(testDir, FAMILY2);
107    StoreFileWriter writer2 = new StoreFileWriter.Builder(conf, cacheConf, fs)
108      .withOutputDir(outputDir2).withFileContext(meta).build();
109    MobTestUtil.writeStoreFile(writer2, caseName);
110    StoreFileInfo storeFileInfo2 =
111      StoreFileInfo.createStoreFileInfoForHFile(conf, fs, writer2.getPath(), true);
112    CachedMobFile cachedMobFile2 =
113      new CachedMobFile(new HStoreFile(storeFileInfo2, BloomType.NONE, cacheConf));
114    cachedMobFile1.access(1);
115    cachedMobFile2.access(2);
116    assertEquals(1, cachedMobFile1.compareTo(cachedMobFile2));
117    assertEquals(-1, cachedMobFile2.compareTo(cachedMobFile1));
118    assertEquals(0, cachedMobFile1.compareTo(cachedMobFile1));
119  }
120
121  @Test
122  public void testReadKeyValue() throws Exception {
123    Path testDir = TEST_UTIL.getDataTestDir();
124    FileSystem fs = testDir.getFileSystem(conf);
125    HFileContext meta = new HFileContextBuilder().withBlockSize(8 * 1024).build();
126    StoreFileWriter writer = new StoreFileWriter.Builder(conf, cacheConf, fs).withOutputDir(testDir)
127      .withFileContext(meta).build();
128    String caseName = testName.getMethodName();
129    MobTestUtil.writeStoreFile(writer, caseName);
130    StoreFileInfo storeFileInfo =
131      StoreFileInfo.createStoreFileInfoForHFile(conf, fs, writer.getPath(), true);
132    CachedMobFile cachedMobFile =
133      new CachedMobFile(new HStoreFile(storeFileInfo, BloomType.NONE, cacheConf));
134    byte[] family = Bytes.toBytes(caseName);
135    byte[] qualify = Bytes.toBytes(caseName);
136    // Test the start key
137    byte[] startKey = Bytes.toBytes("aa"); // The start key bytes
138    KeyValue expectedKey =
139      new KeyValue(startKey, family, qualify, Long.MAX_VALUE, Type.Put, startKey);
140    KeyValue seekKey = expectedKey.createKeyOnly(false);
141    Cell cell = cachedMobFile.readCell(seekKey, false).getCell();
142    MobTestUtil.assertCellEquals(expectedKey, cell);
143
144    // Test the end key
145    byte[] endKey = Bytes.toBytes("zz"); // The end key bytes
146    expectedKey = new KeyValue(endKey, family, qualify, Long.MAX_VALUE, Type.Put, endKey);
147    seekKey = expectedKey.createKeyOnly(false);
148    cell = cachedMobFile.readCell(seekKey, false).getCell();
149    MobTestUtil.assertCellEquals(expectedKey, cell);
150
151    // Test the random key
152    byte[] randomKey = Bytes.toBytes(MobTestUtil.generateRandomString(2));
153    expectedKey = new KeyValue(randomKey, family, qualify, Long.MAX_VALUE, Type.Put, randomKey);
154    seekKey = expectedKey.createKeyOnly(false);
155    cell = cachedMobFile.readCell(seekKey, false).getCell();
156    MobTestUtil.assertCellEquals(expectedKey, cell);
157
158    // Test the key which is less than the start key
159    byte[] lowerKey = Bytes.toBytes("a1"); // Smaller than "aa"
160    expectedKey = new KeyValue(startKey, family, qualify, Long.MAX_VALUE, Type.Put, startKey);
161    seekKey = new KeyValue(lowerKey, family, qualify, Long.MAX_VALUE, Type.Put, lowerKey);
162    cell = cachedMobFile.readCell(seekKey, false).getCell();
163    MobTestUtil.assertCellEquals(expectedKey, cell);
164
165    // Test the key which is more than the end key
166    byte[] upperKey = Bytes.toBytes("z{"); // Bigger than "zz"
167    seekKey = new KeyValue(upperKey, family, qualify, Long.MAX_VALUE, Type.Put, upperKey);
168    Assert.assertNull(cachedMobFile.readCell(seekKey, false));
169  }
170}