1 package org.apache.lucene.util;
3 import java.util.ArrayList;
4 import java.util.HashSet;
6 import java.util.concurrent.atomic.AtomicLong;
7 import org.junit.Before;
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed with
13 * this work for additional information regarding copyright ownership.
14 * The ASF licenses this file to You under the Apache License, Version 2.0
15 * (the "License"); you may not use this file except in compliance with
16 * the License. You may obtain a copy of the License at
18 * http://www.apache.org/licenses/LICENSE-2.0
20 * Unless required by applicable law or agreed to in writing, software
21 * distributed under the License is distributed on an "AS IS" BASIS,
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 * See the License for the specific language governing permissions and
24 * limitations under the License.
28 * Testcase for {@link RecyclingByteBlockAllocator}
30 public class TestRecyclingByteBlockAllocator extends LuceneTestCase {
36 public void setUp() throws Exception {
40 private RecyclingByteBlockAllocator newAllocator() {
41 return new RecyclingByteBlockAllocator(1 << (2 + random.nextInt(15)),
42 random.nextInt(97), new AtomicLong());
46 public void testAllocate() {
47 RecyclingByteBlockAllocator allocator = newAllocator();
48 HashSet<byte[]> set = new HashSet<byte[]>();
49 byte[] block = allocator.getByteBlock();
52 final int size = block.length;
54 int num = atLeast(97);
55 for (int i = 0; i < num; i++) {
56 block = allocator.getByteBlock();
58 assertEquals(size, block.length);
59 assertTrue("block is returned twice", set.add(block));
60 assertEquals(size * (i + 2), allocator.bytesUsed()); // zero based + 1
61 assertEquals(0, allocator.numBufferedBlocks());
66 public void testAllocateAndRecycle() {
67 RecyclingByteBlockAllocator allocator = newAllocator();
68 HashSet<byte[]> allocated = new HashSet<byte[]>();
70 byte[] block = allocator.getByteBlock();
73 final int size = block.length;
75 int numIters = atLeast(97);
76 for (int i = 0; i < numIters; i++) {
77 int num = 1 + random.nextInt(39);
78 for (int j = 0; j < num; j++) {
79 block = allocator.getByteBlock();
81 assertEquals(size, block.length);
82 assertTrue("block is returned twice", allocated.add(block));
83 assertEquals(size * (allocated.size() + allocator.numBufferedBlocks()), allocator
86 byte[][] array = allocated.toArray(new byte[0][]);
87 int begin = random.nextInt(array.length);
88 int end = begin + random.nextInt(array.length - begin);
89 List<byte[]> selected = new ArrayList<byte[]>();
90 for (int j = begin; j < end; j++) {
91 selected.add(array[j]);
93 allocator.recycleByteBlocks(array, begin, end);
94 for (int j = begin; j < end; j++) {
96 byte[] b = selected.remove(0);
97 assertTrue(allocated.remove(b));
103 public void testAllocateAndFree() {
104 RecyclingByteBlockAllocator allocator = newAllocator();
105 HashSet<byte[]> allocated = new HashSet<byte[]>();
106 int freeButAllocated = 0;
107 byte[] block = allocator.getByteBlock();
108 allocated.add(block);
109 assertNotNull(block);
110 final int size = block.length;
112 int numIters = atLeast(97);
113 for (int i = 0; i < numIters; i++) {
114 int num = 1 + random.nextInt(39);
115 for (int j = 0; j < num; j++) {
116 block = allocator.getByteBlock();
117 freeButAllocated = Math.max(0, freeButAllocated - 1);
118 assertNotNull(block);
119 assertEquals(size, block.length);
120 assertTrue("block is returned twice", allocated.add(block));
121 assertEquals(size * (allocated.size() + allocator.numBufferedBlocks()),
122 allocator.bytesUsed());
125 byte[][] array = allocated.toArray(new byte[0][]);
126 int begin = random.nextInt(array.length);
127 int end = begin + random.nextInt(array.length - begin);
128 for (int j = begin; j < end; j++) {
130 assertTrue(allocated.remove(b));
132 allocator.recycleByteBlocks(array, begin, end);
133 for (int j = begin; j < end; j++) {
134 assertNull(array[j]);
136 // randomly free blocks
137 int numFreeBlocks = allocator.numBufferedBlocks();
138 int freeBlocks = allocator.freeBlocks(random.nextInt(7 + allocator
139 .maxBufferedBlocks()));
140 assertEquals(allocator.numBufferedBlocks(), numFreeBlocks - freeBlocks);