1   /**
2    * Copyright 2009 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  package org.apache.hadoop.hbase.io.hfile;
21  
22  import java.nio.ByteBuffer;
23  import java.util.LinkedList;
24  
25  import junit.framework.TestCase;
26  
27  public class TestCachedBlockQueue extends TestCase {
28  
29    public void testQueue() throws Exception {
30  
31      CachedBlock cb1 = new CachedBlock(1000, "cb1", 1);
32      CachedBlock cb2 = new CachedBlock(1500, "cb2", 2);
33      CachedBlock cb3 = new CachedBlock(1000, "cb3", 3);
34      CachedBlock cb4 = new CachedBlock(1500, "cb4", 4);
35      CachedBlock cb5 = new CachedBlock(1000, "cb5", 5);
36      CachedBlock cb6 = new CachedBlock(1750, "cb6", 6);
37      CachedBlock cb7 = new CachedBlock(1000, "cb7", 7);
38      CachedBlock cb8 = new CachedBlock(1500, "cb8", 8);
39      CachedBlock cb9 = new CachedBlock(1000, "cb9", 9);
40      CachedBlock cb10 = new CachedBlock(1500, "cb10", 10);
41  
42      CachedBlockQueue queue = new CachedBlockQueue(10000,1000);
43  
44      queue.add(cb1);
45      queue.add(cb2);
46      queue.add(cb3);
47      queue.add(cb4);
48      queue.add(cb5);
49      queue.add(cb6);
50      queue.add(cb7);
51      queue.add(cb8);
52      queue.add(cb9);
53      queue.add(cb10);
54  
55      // We expect cb1 through cb8 to be in the queue
56      long expectedSize = cb1.heapSize() + cb2.heapSize() + cb3.heapSize() +
57        cb4.heapSize() + cb5.heapSize() + cb6.heapSize() + cb7.heapSize() +
58        cb8.heapSize();
59  
60      assertEquals(queue.heapSize(), expectedSize);
61  
62      LinkedList<org.apache.hadoop.hbase.io.hfile.CachedBlock> blocks =
63        queue.get();
64      assertEquals(blocks.poll().getName(), "cb1");
65      assertEquals(blocks.poll().getName(), "cb2");
66      assertEquals(blocks.poll().getName(), "cb3");
67      assertEquals(blocks.poll().getName(), "cb4");
68      assertEquals(blocks.poll().getName(), "cb5");
69      assertEquals(blocks.poll().getName(), "cb6");
70      assertEquals(blocks.poll().getName(), "cb7");
71      assertEquals(blocks.poll().getName(), "cb8");
72  
73    }
74  
75    public void testQueueSmallBlockEdgeCase() throws Exception {
76  
77      CachedBlock cb1 = new CachedBlock(1000, "cb1", 1);
78      CachedBlock cb2 = new CachedBlock(1500, "cb2", 2);
79      CachedBlock cb3 = new CachedBlock(1000, "cb3", 3);
80      CachedBlock cb4 = new CachedBlock(1500, "cb4", 4);
81      CachedBlock cb5 = new CachedBlock(1000, "cb5", 5);
82      CachedBlock cb6 = new CachedBlock(1750, "cb6", 6);
83      CachedBlock cb7 = new CachedBlock(1000, "cb7", 7);
84      CachedBlock cb8 = new CachedBlock(1500, "cb8", 8);
85      CachedBlock cb9 = new CachedBlock(1000, "cb9", 9);
86      CachedBlock cb10 = new CachedBlock(1500, "cb10", 10);
87  
88      CachedBlockQueue queue = new CachedBlockQueue(10000,1000);
89  
90      queue.add(cb1);
91      queue.add(cb2);
92      queue.add(cb3);
93      queue.add(cb4);
94      queue.add(cb5);
95      queue.add(cb6);
96      queue.add(cb7);
97      queue.add(cb8);
98      queue.add(cb9);
99      queue.add(cb10);
100 
101     CachedBlock cb0 = new CachedBlock(10 + CachedBlock.PER_BLOCK_OVERHEAD, "cb0", 0);
102     queue.add(cb0);
103 
104     // This is older so we must include it, but it will not end up kicking
105     // anything out because (heapSize - cb8.heapSize + cb0.heapSize < maxSize)
106     // and we must always maintain heapSize >= maxSize once we achieve it.
107 
108     // We expect cb0 through cb8 to be in the queue
109     long expectedSize = cb1.heapSize() + cb2.heapSize() + cb3.heapSize() +
110       cb4.heapSize() + cb5.heapSize() + cb6.heapSize() + cb7.heapSize() +
111       cb8.heapSize() + cb0.heapSize();
112 
113     assertEquals(queue.heapSize(), expectedSize);
114 
115     LinkedList<org.apache.hadoop.hbase.io.hfile.CachedBlock> blocks = queue.get();
116     assertEquals(blocks.poll().getName(), "cb0");
117     assertEquals(blocks.poll().getName(), "cb1");
118     assertEquals(blocks.poll().getName(), "cb2");
119     assertEquals(blocks.poll().getName(), "cb3");
120     assertEquals(blocks.poll().getName(), "cb4");
121     assertEquals(blocks.poll().getName(), "cb5");
122     assertEquals(blocks.poll().getName(), "cb6");
123     assertEquals(blocks.poll().getName(), "cb7");
124     assertEquals(blocks.poll().getName(), "cb8");
125 
126   }
127 
128   private static class CachedBlock extends org.apache.hadoop.hbase.io.hfile.CachedBlock
129   {
130     public CachedBlock(long heapSize, String name, long accessTime) {
131       super(name,
132           ByteBuffer.allocate((int)(heapSize - CachedBlock.PER_BLOCK_OVERHEAD)),
133           accessTime,false);
134     }
135   }
136 }