Class BucketEntry
java.lang.Object
org.apache.hadoop.hbase.io.hfile.bucket.BucketEntry
- All Implemented Interfaces:
HBaseReferenceCounted,org.apache.hbase.thirdparty.io.netty.util.ReferenceCounted
Item in cache. We expect this to be where most memory goes. Java uses 8 bytes just for object
headers; after this, we want to use as little as possible - so we only use 8 bytes, but in order
to do so we end up messing around with all this Java casting stuff. Offset stored as 5 bytes that
make up the long. Doubt we'll see devices this big for ages. Offsets are divided by 256. So 5
bytes gives us 256TB or so.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescription(package private) static interface -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate long(package private) final ByteBuffAllocatorprivate longTime this block was cached.(package private) static final Comparator<BucketEntry>(package private) byteThe index of the deserializer that can deserialize this BucketEntry content.private int(package private) final AtomicBooleanprivate byteprivate intprivate intprivate BlockPriorityprivate final RefCntThe RefCnt means how many paths are referring theBucketEntry, there are two cases: 1.If theIOEngine.usesSharedMemory()is false(eg.FileIOEngine),the refCnt is always 1 until thisBucketEntryis evicted fromBucketCache.backingMap.Even if the correspondingHFileBlockis referenced by RPC reading, the refCnt should not increase. -
Constructor Summary
ConstructorsConstructorDescriptionBucketEntry(long offset, int length, int onDiskSizeWithHeader, long accessCounter, boolean inMemory, Function<BucketEntry, ByteBuffAllocator.Recycler> createRecycler, ByteBuffAllocator allocator) BucketEntry(long offset, int length, int onDiskSizeWithHeader, long accessCounter, long cachedTime, boolean inMemory, Function<BucketEntry, ByteBuffAllocator.Recycler> createRecycler, ByteBuffAllocator allocator) -
Method Summary
Modifier and TypeMethodDescription(package private) voidaccess(long accessCounter) Block has been accessed.(package private) CacheableDeserializer<Cacheable>(package private) longlongintint(package private) booleanisRpcRef()Check whether have some RPC patch referring this block.
ForIOEngine.usesSharedMemory()is true(eg.ByteBufferIOEngine), there're two case:
1.(package private) booleanTheBucketCachewill try to release its reference to this BucketEntry many times.(package private) longoffset()intrefCnt()booleanrelease()We've three cases to release refCnt now:
1.retain()(package private) voidsetDeserializerReference(CacheableDeserializer<Cacheable> deserializer) private voidsetOffset(long value) (package private) <T> TwithWriteLock(IdReadWriteLock<Long> offsetLock, BucketEntry.BucketEntryHandler<T> handler) (package private) CacheablewrapAsCacheable(ByteBuffer[] buffers) (package private) CacheablewrapAsCacheable(ByteBuff buf) Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface org.apache.hadoop.hbase.nio.HBaseReferenceCounted
release, retain, touch, touch
-
Field Details
-
COMPARATOR
-
offsetBase
-
length
-
onDiskSizeWithHeader
-
offset1
-
deserializerIndex
byte deserializerIndexThe index of the deserializer that can deserialize this BucketEntry content. SeeCacheableDeserializerIdManagerfor hosting of index to serializers. -
accessCounter
-
priority
-
refCnt
The RefCnt means how many paths are referring the
BucketEntry, there are two cases: 1.If theIOEngine.usesSharedMemory()is false(eg.FileIOEngine),the refCnt is always 1 until thisBucketEntryis evicted fromBucketCache.backingMap.Even if the correspondingHFileBlockis referenced by RPC reading, the refCnt should not increase. 2.If theIOEngine.usesSharedMemory()is true(eg.ByteBufferIOEngine),each RPC reading path is considering as one path, theBucketCache.backingMapreference is also considered a path. NOTICE that if two read RPC path hit the sameBucketEntry, then theHFileBlocks the two RPC referred will share the same refCnt instance with theBucketEntry,so the refCnt will increase or decrease as the following: (1) when writerThread flush the block into IOEngine and add the bucketEntry into backingMap, the refCnt ++; (2) If BucketCache evict the block and move the bucketEntry out of backingMap, the refCnt--; it usually happen when HFile is closing or someone call the clearBucketCache by force. (3) The read RPC path start to refer the block which is backend by the memory area in bucketEntry, then refCnt ++ ; (4) The read RPC patch shipped the response, and release the block. then refCnt--; Once the refCnt decrease to zero, then theBucketAllocatorwill free the block area. -
markedAsEvicted
-
allocator
-
cachedTime
Time this block was cached. Presumes we are created just before we are added to the cache.
-
-
Constructor Details
-
BucketEntry
BucketEntry(long offset, int length, int onDiskSizeWithHeader, long accessCounter, boolean inMemory, Function<BucketEntry, ByteBuffAllocator.Recycler> createRecycler, ByteBuffAllocator allocator) - Parameters:
createRecycler- used to free thisBucketEntrywhenrefCntbecoming 0. NOTICE thatByteBuffAllocator.NONEcould only be used for test.
-
BucketEntry
BucketEntry(long offset, int length, int onDiskSizeWithHeader, long accessCounter, long cachedTime, boolean inMemory, Function<BucketEntry, ByteBuffAllocator.Recycler> createRecycler, ByteBuffAllocator allocator)
-
-
Method Details
-
offset
long offset() -
setOffset
-
getLength
-
deserializerReference
-
setDeserializerReference
-
getAccessCounter
long getAccessCounter() -
access
Block has been accessed. Update its local access counter. -
getPriority
-
getCachedTime
-
getOnDiskSizeWithHeader
-
markAsEvicted
boolean markAsEvicted()TheBucketCachewill try to release its reference to this BucketEntry many times. we must make sure the idempotent, otherwise it'll decrease the RPC's reference count in advance, then for RPC memory leak happen.- Returns:
- true if we deallocate this entry successfully.
-
isRpcRef
boolean isRpcRef()Check whether have some RPC patch referring this block.
ForIOEngine.usesSharedMemory()is true(eg.ByteBufferIOEngine), there're two case:
1. If current refCnt is greater than 1, there must be at least one referring RPC path;
2. If current refCnt is equal to 1 and the markedAtEvicted is true, the it means backingMap has released its reference, the remaining reference can only be from RPC path.
We use this check to decide whether we can free the block area: when cached size exceed the acceptable size, our eviction policy will choose those stale blocks without any RPC reference and the RPC referred block will be excluded.
ForIOEngine.usesSharedMemory()is false(eg.FileIOEngine),refCntis always 1 until it is evicted fromBucketCache.backingMap, soisRpcRef()is always return false.- Returns:
- true to indicate there're some RPC referring the block.
-
wrapAsCacheable
- Throws:
IOException
-
wrapAsCacheable
- Throws:
IOException
-
withWriteLock
-
refCnt
- Specified by:
refCntin interfaceorg.apache.hbase.thirdparty.io.netty.util.ReferenceCounted
-
retain
- Specified by:
retainin interfaceorg.apache.hbase.thirdparty.io.netty.util.ReferenceCounted
-
release
We've three cases to release refCnt now:
1. BucketCache#evictBlock, it will release the backingMap's reference by force because we're closing file or clear the bucket cache or some corruption happen. when all rpc references gone, then free the area in bucketAllocator.
2. BucketCache#returnBlock . when rpc shipped, we'll release the block, only when backingMap also release its refCnt (case.1 will do this) and no other rpc reference, then it will free the area in bucketAllocator.
3.evict those block without any rpc reference if cache size exceeded. we'll only free those blocks with zero rpc reference count.- Specified by:
releasein interfaceorg.apache.hbase.thirdparty.io.netty.util.ReferenceCounted- Returns:
- true to indicate we've decreased to zero and do the de-allocation.
-