/*
* Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.store;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import org.h2.mvstore.FreeSpaceBitSet;
import org.h2.test.TestBase;
import org.h2.util.Utils;
/**
* Tests the free space list.
*/
public class TestFreeSpace extends TestBase {
/**
* Run just this test.
*
* @param a ignored
*/
public static void main(String... a) throws Exception {
TestBase.createCaller().init().test();
testMemoryUsage();
testPerformance();
}
@Override
public void test() throws Exception {
testSimple();
testRandomized();
}
private static void testPerformance() {
for (int i = 0; i < 10; i++) {
long t = System.nanoTime();
FreeSpaceBitSet f = new FreeSpaceBitSet(0, 4096);
// 75 ms
// FreeSpaceList f = new FreeSpaceList(0, 4096);
// 13868 ms
// FreeSpaceTree f = new FreeSpaceTree(0, 4096);
// 56 ms
for (int j = 0; j < 100000; j++) {
f.markUsed(j * 2 * 4096, 4096);
}
for (int j = 0; j < 100000; j++) {
f.free(j * 2 * 4096, 4096);
}
for (int j = 0; j < 100000; j++) {
f.allocate(4096 * 2);
}
System.out.println(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - t));
}
}
private static void testMemoryUsage() {
// 16 GB file size
long size = 16L * 1024 * 1024 * 1024;
System.gc();
System.gc();
long first = Utils.getMemoryUsed();
FreeSpaceBitSet f = new FreeSpaceBitSet(0, 4096);
// 512 KB
// FreeSpaceTree f = new FreeSpaceTree(0, 4096);
// 64 MB
// FreeSpaceList f = new FreeSpaceList(0, 4096);
// too slow
for (long j = size; j > 0; j -= 4 * 4096) {
f.markUsed(j, 4096);
}
System.gc();
System.gc();
long mem = Utils.getMemoryUsed() - first;
System.out.println("Memory used: " + mem);
System.out.println("f: " + f.toString().length());
}
private void testSimple() {
FreeSpaceBitSet f1 = new FreeSpaceBitSet(2, 1024);
FreeSpaceList f2 = new FreeSpaceList(2, 1024);
FreeSpaceTree f3 = new FreeSpaceTree(2, 1024);
assertEquals(f1.toString(), f2.toString());
assertEquals(f1.toString(), f3.toString());
assertEquals(2 * 1024, f1.allocate(10240));
assertEquals(2 * 1024, f2.allocate(10240));
assertEquals(2 * 1024, f3.allocate(10240));
assertEquals(f1.toString(), f2.toString());
assertEquals(f1.toString(), f3.toString());
f1.markUsed(20480, 1024);
f2.markUsed(20480, 1024);
f3.markUsed(20480, 1024);
assertEquals(f1.toString(), f2.toString());
assertEquals(f1.toString(), f3.toString());
}
private void testRandomized() {
FreeSpaceBitSet f1 = new FreeSpaceBitSet(2, 8);
FreeSpaceList f2 = new FreeSpaceList(2, 8);
Random r = new Random(1);
StringBuilder log = new StringBuilder();
for (int i = 0; i < 100000; i++) {
long pos = r.nextInt(1024);
int length = 1 + r.nextInt(8 * 128);
switch (r.nextInt(3)) {
case 0: {
log.append("allocate(" + length + ");\n");
long a = f1.allocate(length);
long b = f2.allocate(length);
assertEquals(a, b);
break;
}
case 1:
if (f1.isUsed(pos, length)) {
log.append("free(" + pos + ", " + length + ");\n");
f1.free(pos, length);
f2.free(pos, length);
}
break;
case 2:
if (f1.isFree(pos, length)) {
log.append("markUsed(" + pos + ", " + length + ");\n");
f1.markUsed(pos, length);
f2.markUsed(pos, length);
}
break;
}
assertEquals(f1.toString(), f2.toString());
}
}
}