/* * Copyright 2012 Takao Nakaguchi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.trie4j.bv; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import org.junit.Assert; import org.junit.Test; import org.trie4j.util.FastBitSet; public abstract class AbstractSuccinctBitVectorTest { protected abstract SuccinctBitVector create(); protected abstract SuccinctBitVector create(int initialCapacity); protected abstract SuccinctBitVector create(byte[] bytes, int bitsSize); @Test public void test_rank() throws Exception{ SuccinctBitVector bv = create(16); for(int i = 0; i < 2048; i++){ if((i % 2) == 0) bv.append1(); else bv.append0(); Assert.assertEquals(i / 2 + 1, bv.rank1(i)); Assert.assertEquals(i / 2 + i % 2, bv.rank0(i)); } } @Test public void test_select0_1() throws Exception{ SuccinctBitVector bv = create(16); bv.append1(); bv.append1(); bv.append0(); bv.append1(); bv.append1(); bv.append0(); Assert.assertEquals(2, bv.select0(1)); } @Test public void test_select0_2() throws Exception{ SuccinctBitVector bv = create(1); for(int i = 0; i < 2000; i++){ bv.append1(); bv.append1(); bv.append0(); } Assert.assertEquals(14, bv.select0(5)); Assert.assertEquals(59, bv.select0(20)); Assert.assertEquals(89, bv.select0(30)); Assert.assertEquals(104, bv.select0(35)); Assert.assertEquals(299, bv.select0(100)); Assert.assertEquals(1076, bv.select0(359)); Assert.assertEquals(3899, bv.select0(1300)); Assert.assertEquals(-1, bv.select0(2001)); } @Test public void test_select0_3() throws Exception{ SuccinctBitVector bv = create(1); for(int i = 0; i < 64; i++){ bv.append0(); } bv.append1(); Assert.assertEquals(-1, bv.select0(65)); bv.append1(); bv.append1(); bv.append1(); bv.append1(); bv.append1(); bv.append1(); Assert.assertEquals(-1, bv.select0(65)); bv.append0(); Assert.assertEquals(71, bv.select0(65)); Assert.assertEquals(-1, bv.select0(2001)); } @Test public void test_select0_4() throws Exception{ String[] B ={"11111111", "11111111", "11111111", "01010101", "11111111", "11111110", "00000001", "11111111", }; BytesSuccinctBitVector bv = new BytesSuccinctBitVector(); BitVectorUtil.appendBitStrings(bv, B); Assert.assertEquals(4, bv.rank0(31)); Assert.assertEquals(28, bv.rank1(31)); Assert.assertEquals(30, bv.select0(4)); Assert.assertEquals(47, bv.select0(5)); } @Test public void test_select1_1() throws Exception{ SuccinctBitVector bv = create(1); for(int i = 0; i < 2000; i++){ bv.append1(); bv.append1(); bv.append0(); } Assert.assertEquals(0, bv.select1(1)); Assert.assertEquals(4, bv.select1(4)); Assert.assertEquals(10, bv.select1(8)); Assert.assertEquals(16, bv.select1(12)); Assert.assertEquals(1948, bv.select1(1300)); } @Test public void test_select_fail_1() throws Exception{ SuccinctBitVector bv = create(1); Assert.assertEquals(-1, bv.select1(9)); Assert.assertEquals(-1, bv.select0(1)); bv.append0(); Assert.assertEquals(-1, bv.select1(9)); Assert.assertEquals(0, bv.select0(1)); Assert.assertEquals(-1, bv.select0(2)); } @Test public void test_next0_1() throws Exception{ SuccinctBitVector bv = create(); bv.append0(); bv.append0(); Assert.assertEquals(0, bv.next0(0)); Assert.assertEquals(1, bv.next0(1)); } @Test public void test_next0_2() throws Exception{ SuccinctBitVector bv = create(); bv.append1(); bv.append0(); bv.append1(); bv.append0(); Assert.assertEquals(1, bv.next0(0)); Assert.assertEquals(3, bv.next0(2)); } @Test public void test_next0_3() throws Exception{ SuccinctBitVector bv = create(); for(int i = 0; i < 8; i++){ bv.append1(); } bv.append0(); Assert.assertEquals(8, bv.next0(0)); } @Test public void test_next0_4() throws Exception{ SuccinctBitVector bv = create(); for(int i = 0; i < 130; i++){ bv.append1(); } bv.append0(); Assert.assertEquals(130, bv.next0(0)); } @Test public void test_next0_5() throws Exception{ SuccinctBitVector bv = create(); for(int i = 0; i < 63; i++){ bv.append1(); } bv.append0(); bv.append0(); Assert.assertEquals(63, bv.next0(0)); Assert.assertEquals(64, bv.next0(64)); } @Test public void test_hugedata_rank1() throws Exception{ int size = 1000000; SuccinctBitVector bv = create(size); for(int i = 0; i < size; i++){ bv.append1(); } for(int i = 0; i < 100000; i++){ Assert.assertEquals(size, bv.rank1(size - 1)); } } @Test public void test_hugedata_select0() throws Exception{ int size = 1000000; SuccinctBitVector bv = create(size); for(int i = 0; i < size; i++){ bv.append0(); } for(int i = 1; i <= 100000; i++){ Assert.assertEquals(i - 1, bv.select0(i)); } } @Test public void test_write_read() throws Exception{ SuccinctBitVector bv = create(); for(int i = 0; i < 1000; i++){ bv.append0(); bv.append1(); bv.append1(); } ByteArrayOutputStream baos = new ByteArrayOutputStream(); new ObjectOutputStream(baos).writeObject(bv); SuccinctBitVector bv2 = (SuccinctBitVector)new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())).readObject(); for(int i = 0; i < 1000; i++){ Assert.assertEquals(i + 1, bv2.rank0(i * 3)); Assert.assertEquals(i * 2 + 1, bv2.rank1(i * 3 + 1)); Assert.assertEquals(i * 2 + 2, bv2.rank1(i * 3 + 2)); } } @Test public void test_save_load() throws Exception{ SuccinctBitVector bv = create(); for(int i = 0; i < 1000; i++){ bv.append0(); bv.append1(); bv.append1(); } ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(bv); SuccinctBitVector bv2 = (SuccinctBitVector)new ObjectInputStream( new ByteArrayInputStream(baos.toByteArray())) .readObject(); for(int i = 0; i < 1000; i++){ Assert.assertEquals(i + 1, bv2.rank0(i * 3)); Assert.assertEquals(i * 2 + 1, bv2.rank1(i * 3 + 1)); Assert.assertEquals(i * 2 + 2, bv2.rank1(i * 3 + 2)); } } @Test public void test_empty_1() throws Exception{ SuccinctBitVector sbv = create(); Assert.assertEquals(0, sbv.size()); } @Test public void test_append_1() throws Exception{ SuccinctBitVector sbv = create(); sbv.append0(); Assert.assertEquals(1, sbv.rank0(0)); Assert.assertEquals(0, sbv.rank1(0)); } @Test public void test_append_2() throws Exception{ SuccinctBitVector sbv = create(); sbv.append1(); Assert.assertEquals(0, sbv.rank0(0)); Assert.assertEquals(1, sbv.rank1(0)); } @Test public void test_append_3() throws Exception{ SuccinctBitVector sbv = create(); for(int i = 0; i < 8; i++){ sbv.append1(); sbv.append0(); } Assert.assertEquals(8, sbv.rank0(15)); Assert.assertEquals(8, sbv.rank1(15)); } @Test public void test_append_4_append0() throws Exception{ SuccinctBitVector sbv = create(1); for(int i = 0; i < 1000; i++){ sbv.append0(); } } @Test public void test_create_from_bytes_1() throws Exception{ SuccinctBitVector sbv = create(new byte[]{(byte)0xf3, 0x48}, 16); Assert.assertEquals(8, sbv.rank0(15)); Assert.assertEquals(8, sbv.rank1(15)); } @Test public void test_create_from_bytes_2() throws Exception{ FastBitSet bs = new FastBitSet(); int pos = 0; // tib.addEmpty(0); bs.unset(pos++); // 0 //tib.addEmpty(1); bs.unset(pos++); // 1 // tib.add(2, 0, 5); bs.set(pos++); bs.set(pos++); bs.set(pos++); bs.set(pos++); bs.set(pos++); bs.unset(pos++); // 7 // tib.add(3, 5, 9); bs.set(pos++); bs.set(pos++); bs.set(pos++); bs.set(pos++); bs.unset(pos++); // 12 //tib.addEmpty(4); bs.unset(pos++); // 13 // tib.add(5, 9, 12); bs.set(pos++); bs.set(pos++); bs.set(pos++); bs.unset(pos++); // 17 // tib.add(6, 12, 16); bs.set(pos++); bs.set(pos++); bs.set(pos++); bs.set(pos++); bs.unset(pos++); // 22 // tib.add(7, 16, 20); bs.set(pos++); bs.set(pos++); bs.set(pos++); bs.set(pos++); bs.unset(pos++); // 27 SuccinctBitVector sbv = create(bs.getBytes(), bs.size()); Assert.assertEquals(28, bs.size()); Assert.assertEquals(-1, sbv.select0(0)); Assert.assertEquals(0, sbv.select0(1)); Assert.assertEquals(1, sbv.select0(2)); Assert.assertEquals(7, sbv.select0(3)); Assert.assertEquals(12, sbv.select0(4)); Assert.assertEquals(13, sbv.select0(5)); Assert.assertEquals(17, sbv.select0(6)); Assert.assertEquals(22, sbv.select0(7)); Assert.assertEquals(27, sbv.select0(8)); } @Test public void test_append_rank_1() throws Exception{ SuccinctBitVector sbv = create(); sbv.append0(); Assert.assertEquals(1, sbv.rank0(0)); Assert.assertEquals(0, sbv.rank1(0)); } @Test public void test_append_rank_2() throws Exception{ SuccinctBitVector sbv = create(); sbv.append1(); Assert.assertEquals(0, sbv.rank0(0)); Assert.assertEquals(1, sbv.rank1(0)); } @Test public void test_append_rank_3() throws Exception{ SuccinctBitVector sbv = create(); for(int i = 0; i < 8; i++){ sbv.append1(); sbv.append0(); } for(int i = 0; i < 16; i++){ String msg = i + "th"; Assert.assertEquals(msg, i / 2 + i % 2, sbv.rank0(i)); Assert.assertEquals(msg, i / 2 + 1, sbv.rank1(i)); } } @Test public void test_append_rank1_4() throws Exception{ SuccinctBitVector sbv = create(1); for(int i = 0; i < 1000; i++){ sbv.append0(); } for(int i = 0; i < 1000; i++){ Assert.assertEquals(i + 1, sbv.rank0(i)); Assert.assertEquals(0, sbv.rank1(i)); } } @Test public void test_from_bytes_rank_1() throws Exception{ SuccinctBitVector sbv = create( new byte[]{0x01, 0x1f}, 16 ); Assert.assertEquals(0, sbv.rank1(4)); Assert.assertEquals(1, sbv.rank1(8)); Assert.assertEquals(6, sbv.rank1(15)); Assert.assertEquals(5, sbv.rank0(4)); Assert.assertEquals(8, sbv.rank0(8)); Assert.assertEquals(10, sbv.rank0(15)); } @Test public void test_from_bytes_rank_2() throws Exception{ SuccinctBitVector sbv = create( new byte[]{0x01, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0x80}, 68 ); Assert.assertEquals(5, sbv.rank0(4)); Assert.assertEquals(8, sbv.rank0(8)); Assert.assertEquals(10, sbv.rank0(15)); Assert.assertEquals(10 + 48, sbv.rank0(64)); Assert.assertEquals(0, sbv.rank1(4)); Assert.assertEquals(1, sbv.rank1(8)); Assert.assertEquals(6, sbv.rank1(15)); Assert.assertEquals(7, sbv.rank1(64)); } @Test public void test_append_select0_next0_1() throws Exception{ SuccinctBitVector sbv = create(); sbv.append1(); sbv.append0(); sbv.append0(); Assert.assertEquals(-1, sbv.select0(0)); Assert.assertEquals(1, sbv.next0(0)); } @Test public void test_append_select0_1() throws Exception{ SuccinctBitVector sbv = create(); for(int i = 0; i < 1000; i++){ String msg = i + "th"; sbv.append0(); Assert.assertEquals(msg, i, sbv.select0(i + 1)); } } }