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.concurrent.atomic.AtomicLong; 022import org.apache.hadoop.conf.Configuration; 023import org.apache.hadoop.fs.FileSystem; 024import org.apache.hadoop.fs.Path; 025import org.apache.hadoop.hbase.io.hfile.CacheConfig; 026import org.apache.hadoop.hbase.regionserver.BloomType; 027import org.apache.hadoop.hbase.regionserver.HStoreFile; 028import org.apache.yetus.audience.InterfaceAudience; 029 030/** 031 * Cached mob file. 032 */ 033@InterfaceAudience.Private 034public class CachedMobFile extends MobFile implements Comparable<CachedMobFile> { 035 036 private long accessCount; 037 private AtomicLong referenceCount = new AtomicLong(0); 038 039 public CachedMobFile(HStoreFile sf) { 040 super(sf); 041 } 042 043 public static CachedMobFile create(FileSystem fs, Path path, Configuration conf, 044 CacheConfig cacheConf) throws IOException { 045 // XXX: primaryReplica is only used for constructing the key of block cache so it is not a 046 // critical problem if we pass the wrong value, so here we always pass true. Need to fix later. 047 HStoreFile sf = new HStoreFile(fs, path, conf, cacheConf, BloomType.NONE, true); 048 return new CachedMobFile(sf); 049 } 050 051 public void access(long accessCount) { 052 this.accessCount = accessCount; 053 } 054 055 @Override 056 public int compareTo(CachedMobFile that) { 057 if (this.accessCount == that.accessCount) return 0; 058 return this.accessCount < that.accessCount ? 1 : -1; 059 } 060 061 @Override 062 public boolean equals(Object obj) { 063 if (this == obj) { 064 return true; 065 } 066 if (obj == null) { 067 return false; 068 } 069 if (!(obj instanceof CachedMobFile)) { 070 return false; 071 } 072 return compareTo((CachedMobFile) obj) == 0; 073 } 074 075 @Override 076 public int hashCode() { 077 return (int) (accessCount ^ (accessCount >>> 32)); 078 } 079 080 /** 081 * Opens the mob file if it's not opened yet and increases the reference. It's not thread-safe. 082 * Use MobFileCache.openFile() instead. The reader of the mob file is just opened when it's not 083 * opened no matter how many times this open() method is invoked. The reference is a counter that 084 * how many times this reader is referenced. When the reference is 0, this reader is closed. 085 */ 086 @Override 087 public void open() throws IOException { 088 super.open(); 089 referenceCount.incrementAndGet(); 090 } 091 092 /** 093 * Decreases the reference of the underlying reader for the mob file. It's not thread-safe. Use 094 * MobFileCache.closeFile() instead. This underlying reader isn't closed until the reference is 0. 095 */ 096 @Override 097 public void close() throws IOException { 098 long refs = referenceCount.decrementAndGet(); 099 if (refs == 0) { 100 super.close(); 101 } 102 } 103 104 /** 105 * Gets the reference of the current mob file. Internal usage, currently it's for testing. 106 * @return The reference of the current mob file. 107 */ 108 public long getReferenceCount() { 109 return this.referenceCount.longValue(); 110 } 111}