/** * diqube: Distributed Query Base. * * Copyright (C) 2015 Bastian Gloeckle * * This file is part of diqube. * * diqube is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.diqube.loader; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import org.diqube.data.column.ColumnPage; import org.diqube.data.column.ColumnPageFactory; import org.diqube.data.column.ColumnShard; import org.diqube.data.column.ColumnShardFactory; import org.diqube.data.dictionary.Dictionary; import org.diqube.data.types.str.DefaultStringStandardColumnShard; import org.diqube.data.types.str.StringStandardColumnShard; import org.diqube.data.types.str.dict.StringDictionary; import org.diqube.loader.columnshard.ColumnShardBuilder; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.testng.Assert; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; /** * Test for {@link ColumnShardBuilder}. * * @author Bastian Gloeckle */ public class ColumnShardBuilderTest { private static final String TEST_COL_NAME = "testCol"; private ColumnShardBuilder<String> builder; private AnnotationConfigApplicationContext dataContext; @BeforeMethod public void setUp() { dataContext = new AnnotationConfigApplicationContext(); dataContext.scan("org.diqube.data"); dataContext.refresh(); builder = new ColumnShardBuilder<String>(dataContext.getBean(ColumnShardFactory.class), dataContext.getBean(ColumnPageFactory.class), TEST_COL_NAME, 0L); } @AfterMethod public void shutDown() { dataContext.close(); } @Test public void buildSimpleColumnShard() { // GIVEN // simple 10-values column input, with IDs starting low String[] valueArray = generateStringArray(1, 10); builder.addValues(valueArray, 0L); // WHEN // building the shard ColumnShard abstractShard = builder.build(); // THEN Assert.assertEquals(DefaultStringStandardColumnShard.class, abstractShard.getClass(), "StringStandardColumnShard expected"); StringStandardColumnShard shard = (StringStandardColumnShard) abstractShard; Assert.assertEquals(shard.getName(), TEST_COL_NAME, "Correct shard name expected"); Assert.assertEquals(shard.getPages().size(), 1, "Expected exactly one Column page"); ColumnPage page = shard.getPages().values().iterator().next(); Assert.assertEquals(page.getFirstRowId(), 0, "Expected first ID in page to be 1"); Assert.assertEquals(shard.getPages().keySet().iterator().next(), (Long) page.getFirstRowId(), "Expected correct first ID in map from Shard to Page"); Assert.assertEquals(resolveValues(page, shard.getColumnShardDictionary()), new HashSet<String>(Arrays.asList(valueArray)), "Expected correct values to be available in Column"); } @Test public void buildLongColumnShard() { // GIVEN // simple 10-values column input, with IDs starting low String[] valueArray = generateStringArray(1, ColumnShardBuilder.PROPOSAL_ROWS + 1); builder.addValues(valueArray, 0L); // WHEN // building the shard ColumnShard abstractShard = builder.build(); // THEN StringStandardColumnShard shard = (StringStandardColumnShard) abstractShard; Assert.assertEquals(shard.getPages().keySet(), new HashSet<Long>(Arrays.asList(new Long[] { 0L, (long) ColumnShardBuilder.PROPOSAL_ROWS })), "Expected two column pages at specific rowIds"); ColumnPage page1 = shard.getPages().get(0L); ColumnPage page2 = shard.getPages().get((long) ColumnShardBuilder.PROPOSAL_ROWS); Set<String> allValues = resolveValues(page1, shard.getColumnShardDictionary()); allValues.addAll(resolveValues(page2, shard.getColumnShardDictionary())); Assert.assertEquals(allValues, new HashSet<String>(Arrays.asList(valueArray)), "Expected all values 1..5001 to be available in Column"); Assert.assertEquals(page1.size() + page2.size(), ColumnShardBuilder.PROPOSAL_ROWS + 1, "Expected correct number of values to be stored."); } @Test public void buildLongColumnShardReversed() { // GIVEN // simple 10-values column input, with IDs starting low String[] valueArray = generateStringArray(1, ColumnShardBuilder.PROPOSAL_ROWS + 1); for (int i = 0; i < valueArray.length / 2; i++) { String tmp = valueArray[i]; valueArray[i] = valueArray[valueArray.length - 1 - i]; valueArray[valueArray.length - 1 - i] = tmp; } builder.addValues(valueArray, 0L); // WHEN // building the shard ColumnShard abstractShard = builder.build(); // THEN StringStandardColumnShard shard = (StringStandardColumnShard) abstractShard; Assert.assertEquals(shard.getPages().keySet(), new HashSet<Long>(Arrays.asList(new Long[] { 0L, (long) ColumnShardBuilder.PROPOSAL_ROWS })), "Expected two column pages at specific rowIds"); ColumnPage page1 = shard.getPages().get(0L); ColumnPage page2 = shard.getPages().get((long) ColumnShardBuilder.PROPOSAL_ROWS); Set<String> allValues = resolveValues(page1, shard.getColumnShardDictionary()); allValues.addAll(resolveValues(page2, shard.getColumnShardDictionary())); Assert.assertEquals(allValues, new HashSet<String>(Arrays.asList(valueArray)), "Expected all values 1..5001 to be available in Column"); Assert.assertEquals(page1.size() + page2.size(), ColumnShardBuilder.PROPOSAL_ROWS + 1, "Expected correct number of values to be stored."); } private static Set<String> resolveValues(ColumnPage page, Dictionary<?> columnDictionary) { Set<String> res = new HashSet<String>(); StringDictionary<?> dict = (StringDictionary<?>) columnDictionary; for (long pageValueId : page.getValues().decompressedArray()) { long columnValueId = page.getColumnPageDict().decompressValue(pageValueId); String value = dict.decompressValue(columnValueId); res.add(value); } return res; } private static String[] generateStringArray(int start, int length) { String[] res = new String[length]; for (int i = 0; i < length; i++) { res[i] = "s" + Integer.toString(i + start); } return res; } }