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.io.hfile; 019 020import static org.junit.jupiter.api.Assertions.assertEquals; 021 022import java.nio.ByteBuffer; 023import org.apache.hadoop.hbase.testclassification.IOTests; 024import org.apache.hadoop.hbase.testclassification.SmallTests; 025import org.junit.jupiter.api.Tag; 026import org.junit.jupiter.api.Test; 027 028@Tag(IOTests.TAG) 029@Tag(SmallTests.TAG) 030public class TestCachedBlockQueue { 031 032 @Test 033 public void testQueue() throws Exception { 034 CachedBlock cb1 = new CachedBlock(1000, "cb1", 1); 035 CachedBlock cb2 = new CachedBlock(1500, "cb2", 2); 036 CachedBlock cb3 = new CachedBlock(1000, "cb3", 3); 037 CachedBlock cb4 = new CachedBlock(1500, "cb4", 4); 038 CachedBlock cb5 = new CachedBlock(1000, "cb5", 5); 039 CachedBlock cb6 = new CachedBlock(1750, "cb6", 6); 040 CachedBlock cb7 = new CachedBlock(1000, "cb7", 7); 041 CachedBlock cb8 = new CachedBlock(1500, "cb8", 8); 042 CachedBlock cb9 = new CachedBlock(1000, "cb9", 9); 043 CachedBlock cb10 = new CachedBlock(1500, "cb10", 10); 044 045 LruCachedBlockQueue queue = new LruCachedBlockQueue(10000, 1000); 046 047 queue.add(cb1); 048 queue.add(cb2); 049 queue.add(cb3); 050 queue.add(cb4); 051 queue.add(cb5); 052 queue.add(cb6); 053 queue.add(cb7); 054 queue.add(cb8); 055 queue.add(cb9); 056 queue.add(cb10); 057 058 // We expect cb1 through cb8 to be in the queue 059 long expectedSize = cb1.heapSize() + cb2.heapSize() + cb3.heapSize() + cb4.heapSize() 060 + cb5.heapSize() + cb6.heapSize() + cb7.heapSize() + cb8.heapSize(); 061 062 assertEquals(queue.heapSize(), expectedSize); 063 064 for (int i = 1; i <= 8; i++) { 065 assertEquals(queue.pollLast().getCacheKey().getHfileName(), "cb" + i); 066 } 067 } 068 069 @Test 070 public void testQueueSmallBlockEdgeCase() throws Exception { 071 CachedBlock cb1 = new CachedBlock(1000, "cb1", 1); 072 CachedBlock cb2 = new CachedBlock(1500, "cb2", 2); 073 CachedBlock cb3 = new CachedBlock(1000, "cb3", 3); 074 CachedBlock cb4 = new CachedBlock(1500, "cb4", 4); 075 CachedBlock cb5 = new CachedBlock(1000, "cb5", 5); 076 CachedBlock cb6 = new CachedBlock(1750, "cb6", 6); 077 CachedBlock cb7 = new CachedBlock(1000, "cb7", 7); 078 CachedBlock cb8 = new CachedBlock(1500, "cb8", 8); 079 CachedBlock cb9 = new CachedBlock(1000, "cb9", 9); 080 CachedBlock cb10 = new CachedBlock(1500, "cb10", 10); 081 082 LruCachedBlockQueue queue = new LruCachedBlockQueue(10000, 1000); 083 084 queue.add(cb1); 085 queue.add(cb2); 086 queue.add(cb3); 087 queue.add(cb4); 088 queue.add(cb5); 089 queue.add(cb6); 090 queue.add(cb7); 091 queue.add(cb8); 092 queue.add(cb9); 093 queue.add(cb10); 094 095 CachedBlock cb0 = new CachedBlock(10 + CachedBlock.PER_BLOCK_OVERHEAD, "cb0", 0); 096 queue.add(cb0); 097 098 // This is older so we must include it, but it will not end up kicking 099 // anything out because (heapSize - cb8.heapSize + cb0.heapSize < maxSize) 100 // and we must always maintain heapSize >= maxSize once we achieve it. 101 102 // We expect cb0 through cb8 to be in the queue 103 long expectedSize = cb1.heapSize() + cb2.heapSize() + cb3.heapSize() + cb4.heapSize() 104 + cb5.heapSize() + cb6.heapSize() + cb7.heapSize() + cb8.heapSize() + cb0.heapSize(); 105 106 assertEquals(queue.heapSize(), expectedSize); 107 108 for (int i = 0; i <= 8; i++) { 109 assertEquals(queue.pollLast().getCacheKey().getHfileName(), "cb" + i); 110 } 111 } 112 113 private static class CachedBlock extends org.apache.hadoop.hbase.io.hfile.LruCachedBlock { 114 public CachedBlock(final long heapSize, String name, long accessTime) { 115 super(new BlockCacheKey(name, 0), new Cacheable() { 116 @Override 117 public long heapSize() { 118 return ((int) (heapSize - CachedBlock.PER_BLOCK_OVERHEAD)); 119 } 120 121 @Override 122 public int getSerializedLength() { 123 return 0; 124 } 125 126 @Override 127 public void serialize(ByteBuffer destination, boolean includeNextBlockMetadata) { 128 } 129 130 @Override 131 public CacheableDeserializer<Cacheable> getDeserializer() { 132 return null; 133 } 134 135 @Override 136 public BlockType getBlockType() { 137 return BlockType.DATA; 138 } 139 140 }, accessTime, false); 141 } 142 } 143}