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