/*
* Copyright (C) 2015 SoftIndex LLC.
*
* 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 io.datakernel.aggregation;
import com.google.common.base.MoreObjects;
import io.datakernel.async.IgnoreCompletionCallback;
import io.datakernel.codegen.DefiningClassLoader;
import io.datakernel.eventloop.Eventloop;
import io.datakernel.stream.StreamConsumers;
import io.datakernel.stream.StreamProducers;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.nio.file.Path;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static com.google.common.collect.Sets.newHashSet;
import static io.datakernel.aggregation.fieldtype.FieldTypes.ofInt;
import static io.datakernel.aggregation.fieldtype.FieldTypes.ofString;
import static io.datakernel.aggregation.measure.Measures.union;
import static io.datakernel.eventloop.FatalErrorHandlers.rethrowOnAnyError;
import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
public class InvertedIndexTest {
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
public static class InvertedIndexQueryResult {
public String word;
public Set<Integer> documents;
public InvertedIndexQueryResult() {
}
public InvertedIndexQueryResult(String word, Set<Integer> documents) {
this.word = word;
this.documents = documents;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
InvertedIndexQueryResult that = (InvertedIndexQueryResult) o;
if (word != null ? !word.equals(that.word) : that.word != null) return false;
return !(documents != null ? !documents.equals(that.documents) : that.documents != null);
}
@Override
public int hashCode() {
int result = word != null ? word.hashCode() : 0;
result = 31 * result + (documents != null ? documents.hashCode() : 0);
return result;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("word", word)
.add("documents", documents)
.toString();
}
}
@Test
public void testInvertedIndex() throws Exception {
ExecutorService executorService = Executors.newCachedThreadPool();
Eventloop eventloop = Eventloop.create().withFatalErrorHandler(rethrowOnAnyError());
DefiningClassLoader classLoader = DefiningClassLoader.create();
AggregationMetadataStorageStub metadataStorage = new AggregationMetadataStorageStub(eventloop);
Path path = temporaryFolder.newFolder().toPath();
AggregationChunkStorage aggregationChunkStorage = LocalFsChunkStorage.create(eventloop, executorService, path);
Aggregation aggregation = Aggregation.create(eventloop, executorService, classLoader, metadataStorage, aggregationChunkStorage)
.withKey("word", ofString())
.withMeasure("documents", union(ofInt()));
StreamProducers.ofIterable(eventloop, asList(new InvertedIndexRecord("fox", 1), new InvertedIndexRecord("brown", 2), new InvertedIndexRecord("fox", 3)))
.streamTo(aggregation.consumer(InvertedIndexRecord.class, metadataStorage.createSaveCallback()));
eventloop.run();
aggregation.loadChunks(IgnoreCompletionCallback.create());
eventloop.run();
StreamProducers.ofIterable(eventloop, asList(new InvertedIndexRecord("brown", 3), new InvertedIndexRecord("lazy", 4), new InvertedIndexRecord("dog", 1)))
.streamTo(aggregation.consumer(InvertedIndexRecord.class, metadataStorage.createSaveCallback()));
eventloop.run();
StreamProducers.ofIterable(eventloop, asList(new InvertedIndexRecord("quick", 1), new InvertedIndexRecord("fox", 4), new InvertedIndexRecord("brown", 10)))
.streamTo(aggregation.consumer(InvertedIndexRecord.class, metadataStorage.createSaveCallback()));
eventloop.run();
aggregation.loadChunks(IgnoreCompletionCallback.create());
eventloop.run();
AggregationQuery query = AggregationQuery.create()
.withKeys("word")
.withMeasures("documents");
StreamConsumers.ToList<InvertedIndexQueryResult> consumerToList = StreamConsumers.toList(eventloop);
aggregation.query(query, InvertedIndexQueryResult.class, DefiningClassLoader.create(classLoader)).streamTo(consumerToList);
eventloop.run();
System.out.println(consumerToList.getList());
List<InvertedIndexQueryResult> expectedResult = asList(new InvertedIndexQueryResult("brown", newHashSet(2, 3, 10)),
new InvertedIndexQueryResult("dog", newHashSet(1)), new InvertedIndexQueryResult("fox", newHashSet(1, 3, 4)),
new InvertedIndexQueryResult("lazy", newHashSet(4)), new InvertedIndexQueryResult("quick", newHashSet(1)));
List<InvertedIndexQueryResult> actualResult = consumerToList.getList();
assertEquals(expectedResult, actualResult);
}
}