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 java.io.IOException;
021import java.util.ArrayList;
022import java.util.Collections;
023import java.util.List;
024import org.apache.hadoop.conf.Configuration;
025import org.apache.hadoop.fs.FileSystem;
026import org.apache.hadoop.fs.Path;
027import org.apache.hadoop.hbase.ExtendedCell;
028import org.apache.hadoop.hbase.io.hfile.CacheConfig;
029import org.apache.hadoop.hbase.regionserver.BloomType;
030import org.apache.hadoop.hbase.regionserver.HStoreFile;
031import org.apache.hadoop.hbase.regionserver.StoreFileScanner;
032import org.apache.hadoop.hbase.regionserver.storefiletracker.StoreFileTracker;
033import org.apache.yetus.audience.InterfaceAudience;
034
035/**
036 * The mob file.
037 */
038@InterfaceAudience.Private
039public class MobFile {
040
041  private HStoreFile sf;
042
043  // internal use only for sub classes
044  protected MobFile() {
045  }
046
047  protected MobFile(HStoreFile sf) {
048    this.sf = sf;
049  }
050
051  /**
052   * Internal use only. This is used by the sweeper.
053   * @return The store file scanner.
054   */
055  public StoreFileScanner getScanner() throws IOException {
056    List<HStoreFile> sfs = new ArrayList<>();
057    sfs.add(sf);
058    List<StoreFileScanner> sfScanners = StoreFileScanner.getScannersForStoreFiles(sfs, false, true,
059      false, false, sf.getMaxMemStoreTS());
060
061    return sfScanners.get(0);
062  }
063
064  /**
065   * Reads a cell from the mob file.
066   * @param search         The cell need to be searched in the mob file.
067   * @param cacheMobBlocks Should this scanner cache blocks.
068   * @return The cell in the mob file.
069   */
070  public MobCell readCell(ExtendedCell search, boolean cacheMobBlocks) throws IOException {
071    return readCell(search, cacheMobBlocks, sf.getMaxMemStoreTS());
072  }
073
074  /**
075   * Reads a cell from the mob file.
076   * @param search         The cell need to be searched in the mob file.
077   * @param cacheMobBlocks Should this scanner cache blocks.
078   * @param readPt         the read point.
079   * @return The cell in the mob file.
080   */
081  public MobCell readCell(ExtendedCell search, boolean cacheMobBlocks, long readPt)
082    throws IOException {
083    StoreFileScanner scanner = null;
084    boolean succ = false;
085    try {
086      List<StoreFileScanner> sfScanners = StoreFileScanner.getScannersForStoreFiles(
087        Collections.singletonList(sf), cacheMobBlocks, true, false, false, readPt);
088      if (!sfScanners.isEmpty()) {
089        scanner = sfScanners.get(0);
090        if (scanner.seek(search)) {
091          MobCell mobCell = new MobCell(scanner.peek(), scanner);
092          succ = true;
093          return mobCell;
094        }
095      }
096      return null;
097    } finally {
098      if (scanner != null && !succ) {
099        scanner.close();
100      }
101    }
102  }
103
104  /**
105   * Gets the file name.
106   * @return The file name.
107   */
108  public String getFileName() {
109    return sf.getPath().getName();
110  }
111
112  /**
113   * Opens the underlying reader. It's not thread-safe. Use MobFileCache.openFile() instead.
114   */
115  public void open() throws IOException {
116    sf.initReader();
117  }
118
119  /**
120   * Closes the underlying reader, but do no evict blocks belonging to this file. It's not
121   * thread-safe. Use MobFileCache.closeFile() instead.
122   */
123  public void close() throws IOException {
124    if (sf != null) {
125      sf.closeStoreFile(false);
126      sf = null;
127    }
128  }
129
130  /**
131   * Creates an instance of the MobFile.
132   * @param fs        The file system.
133   * @param path      The path of the underlying StoreFile.
134   * @param conf      The configuration.
135   * @param cacheConf The CacheConfig.
136   * @return An instance of the MobFile.
137   */
138  public static MobFile create(FileSystem fs, Path path, Configuration conf, CacheConfig cacheConf,
139    StoreFileTracker sft) throws IOException {
140    // XXX: primaryReplica is only used for constructing the key of block cache so it is not a
141    // critical problem if we pass the wrong value, so here we always pass true. Need to fix later.
142    HStoreFile sf = new HStoreFile(fs, path, conf, cacheConf, BloomType.NONE, true, sft);
143    return new MobFile(sf);
144  }
145}