1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.regionserver;
20
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertTrue;
23
24 import java.util.List;
25 import java.util.Random;
26
27 import org.apache.hadoop.conf.Configuration;
28 import org.apache.hadoop.hbase.KeyValue;
29 import org.apache.hadoop.hbase.testclassification.SmallTests;
30 import org.apache.hadoop.hbase.util.ByteRange;
31 import org.apache.hadoop.hbase.util.Bytes;
32 import org.junit.AfterClass;
33 import org.junit.Before;
34 import org.junit.BeforeClass;
35 import org.junit.Test;
36 import org.junit.experimental.categories.Category;
37
38
39
40
41 @Category(SmallTests.class)
42 public class TestMemStoreChunkPool {
43 private final static Configuration conf = new Configuration();
44 private static MemStoreChunkPool chunkPool;
45 private static boolean chunkPoolDisabledBeforeTest;
46
47 @BeforeClass
48 public static void setUpBeforeClass() throws Exception {
49 conf.setBoolean(DefaultMemStore.USEMSLAB_KEY, true);
50 conf.setFloat(MemStoreChunkPool.CHUNK_POOL_MAXSIZE_KEY, 0.2f);
51 chunkPoolDisabledBeforeTest = MemStoreChunkPool.chunkPoolDisabled;
52 MemStoreChunkPool.chunkPoolDisabled = false;
53 chunkPool = MemStoreChunkPool.getPool(conf);
54 assertTrue(chunkPool != null);
55 }
56
57 @AfterClass
58 public static void tearDownAfterClass() throws Exception {
59 MemStoreChunkPool.chunkPoolDisabled = chunkPoolDisabledBeforeTest;
60 }
61
62 @Before
63 public void tearDown() throws Exception {
64 chunkPool.clearChunks();
65 }
66
67 @Test
68 public void testReusingChunks() {
69 Random rand = new Random();
70 MemStoreLAB mslab = new HeapMemStoreLAB(conf);
71 int expectedOff = 0;
72 byte[] lastBuffer = null;
73
74 for (int i = 0; i < 100; i++) {
75 int size = rand.nextInt(1000);
76 ByteRange alloc = mslab.allocateBytes(size);
77
78 if (alloc.getBytes() != lastBuffer) {
79 expectedOff = 0;
80 lastBuffer = alloc.getBytes();
81 }
82 assertEquals(expectedOff, alloc.getOffset());
83 assertTrue("Allocation overruns buffer", alloc.getOffset()
84 + size <= alloc.getBytes().length);
85 expectedOff += size;
86 }
87
88 mslab.close();
89 int chunkCount = chunkPool.getPoolSize();
90 assertTrue(chunkCount > 0);
91
92 mslab = new HeapMemStoreLAB(conf);
93
94 mslab.allocateBytes(1000);
95 assertEquals(chunkCount - 1, chunkPool.getPoolSize());
96 }
97
98 @Test
99 public void testPuttingBackChunksAfterFlushing() throws UnexpectedStateException {
100 byte[] row = Bytes.toBytes("testrow");
101 byte[] fam = Bytes.toBytes("testfamily");
102 byte[] qf1 = Bytes.toBytes("testqualifier1");
103 byte[] qf2 = Bytes.toBytes("testqualifier2");
104 byte[] qf3 = Bytes.toBytes("testqualifier3");
105 byte[] qf4 = Bytes.toBytes("testqualifier4");
106 byte[] qf5 = Bytes.toBytes("testqualifier5");
107 byte[] val = Bytes.toBytes("testval");
108
109 DefaultMemStore memstore = new DefaultMemStore();
110
111
112 memstore.add(new KeyValue(row, fam, qf1, val));
113 memstore.add(new KeyValue(row, fam, qf2, val));
114 memstore.add(new KeyValue(row, fam, qf3, val));
115
116
117 MemStoreSnapshot snapshot = memstore.snapshot();
118 assertEquals(3, memstore.snapshot.size());
119
120
121 assertEquals(0, memstore.cellSet.size());
122 memstore.add(new KeyValue(row, fam, qf4, val));
123 memstore.add(new KeyValue(row, fam, qf5, val));
124 assertEquals(2, memstore.cellSet.size());
125 memstore.clearSnapshot(snapshot.getId());
126
127 int chunkCount = chunkPool.getPoolSize();
128 assertTrue(chunkCount > 0);
129
130 }
131
132 @Test
133 public void testPuttingBackChunksWithOpeningScanner()
134 throws UnexpectedStateException {
135 byte[] row = Bytes.toBytes("testrow");
136 byte[] fam = Bytes.toBytes("testfamily");
137 byte[] qf1 = Bytes.toBytes("testqualifier1");
138 byte[] qf2 = Bytes.toBytes("testqualifier2");
139 byte[] qf3 = Bytes.toBytes("testqualifier3");
140 byte[] qf4 = Bytes.toBytes("testqualifier4");
141 byte[] qf5 = Bytes.toBytes("testqualifier5");
142 byte[] qf6 = Bytes.toBytes("testqualifier6");
143 byte[] qf7 = Bytes.toBytes("testqualifier7");
144 byte[] val = Bytes.toBytes("testval");
145
146 DefaultMemStore memstore = new DefaultMemStore();
147
148
149 memstore.add(new KeyValue(row, fam, qf1, val));
150 memstore.add(new KeyValue(row, fam, qf2, val));
151 memstore.add(new KeyValue(row, fam, qf3, val));
152
153
154 MemStoreSnapshot snapshot = memstore.snapshot();
155 assertEquals(3, memstore.snapshot.size());
156
157
158 assertEquals(0, memstore.cellSet.size());
159 memstore.add(new KeyValue(row, fam, qf4, val));
160 memstore.add(new KeyValue(row, fam, qf5, val));
161 assertEquals(2, memstore.cellSet.size());
162
163
164 List<KeyValueScanner> scanners = memstore.getScanners(0);
165
166
167 memstore.clearSnapshot(snapshot.getId());
168
169 assertTrue(chunkPool.getPoolSize() == 0);
170
171
172 for (KeyValueScanner scanner : scanners) {
173 scanner.close();
174 }
175 assertTrue(chunkPool.getPoolSize() > 0);
176
177
178 chunkPool.clearChunks();
179
180
181 snapshot = memstore.snapshot();
182
183 memstore.add(new KeyValue(row, fam, qf6, val));
184 memstore.add(new KeyValue(row, fam, qf7, val));
185
186 scanners = memstore.getScanners(0);
187
188 for (KeyValueScanner scanner : scanners) {
189 scanner.close();
190 }
191
192
193 memstore.clearSnapshot(snapshot.getId());
194 assertTrue(chunkPool.getPoolSize() > 0);
195 }
196
197 }