/* * Licensed to Elasticsearch under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch licenses this file to you 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.elasticsearch.action.allterms; import org.apache.lucene.analysis.core.WhitespaceAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.TextField; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.NoMergePolicy; import org.apache.lucene.index.NoMergeScheduler; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.store.Directory; import org.apache.lucene.util.BytesRef; import org.elasticsearch.test.ESTestCase; import org.junit.After; import org.junit.Before; import java.io.IOException; import java.util.ArrayList; import java.util.List; import static org.elasticsearch.action.allterms.TransportAllTermsShardAction.getTermsEnums; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.core.IsEqual.equalTo; public class AllTermsTests extends ESTestCase { private static final String FIELD = "field"; private Directory dir; private IndexWriter w; private DirectoryReader reader; @Before public void initSearcher() throws IOException { dir = newDirectory(); IndexWriterConfig indexWriterConfig = newIndexWriterConfig(new WhitespaceAnalyzer()); indexWriterConfig.setMergeScheduler(NoMergeScheduler.INSTANCE); indexWriterConfig.setMergePolicy(NoMergePolicy.INSTANCE); w = new IndexWriter(dir, indexWriterConfig); Document d = new Document(); d.add(new TextField(FIELD, "don't be", Field.Store.YES)); d.add(new TextField("_uid", "1", Field.Store.YES)); w.addDocument(d); w.commit(); d = new Document(); d.add(new TextField(FIELD, "ever always forget be", Field.Store.YES)); d.add(new TextField("_uid", "2", Field.Store.YES)); w.addDocument(d); w.commit(); d = new Document(); d.add(new TextField(FIELD, "careful careful", Field.Store.YES)); d.add(new TextField("_uid", "3", Field.Store.YES)); w.addDocument(d); w.commit(); d = new Document(); d.add(new TextField(FIELD, "ever always careful careful don't be forget be", Field.Store.YES)); d.add(new TextField("_uid", "4", Field.Store.YES)); w.addDocument(d); w.commit(); reader = DirectoryReader.open(w, true, true); } @After public void closeAllTheReaders() throws IOException { w.close(); reader.close(); dir.close(); } public void testReader() { assertThat(reader.leaves().size(), equalTo(4)); } public void testFindSmallestTermAfterExistingTerm() throws IOException { SmallestTermAndExhausted smallestTermAndExhausted = getSmallestTermAndExhausted("careful"); BytesRef smallestTerm = smallestTermAndExhausted.getSmallestTerm(); int[] exhausted = smallestTermAndExhausted.getExhausted(); assertThat(smallestTerm.utf8ToString(), equalTo("don't")); int i = -1; int numExhausted = 0; for (TermsEnum termsEnum : smallestTermAndExhausted.getTermsIters()) { i++; if (exhausted[i] == 1) { numExhausted++; } else { assertThat(termsEnum.term().utf8ToString().compareTo("careful"), greaterThan(0)); } } assertThat(numExhausted, equalTo(1)); } public void testFindSmallestTermFromBeginning() throws IOException { SmallestTermAndExhausted smallestTermAndExhausted = getSmallestTermAndExhausted(null); BytesRef smallestTerm = smallestTermAndExhausted.getSmallestTerm(); int[] exhausted = smallestTermAndExhausted.getExhausted(); assertThat(smallestTerm.utf8ToString(), equalTo("always")); int i = -1; int numExhausted = 0; for (TermsEnum termsEnum : smallestTermAndExhausted.getTermsIters()) { i++; if (exhausted[i] == 1) { numExhausted++; } else { assertThat(termsEnum.term().utf8ToString().compareTo("always"), greaterThanOrEqualTo(0)); } } assertThat(numExhausted, equalTo(0)); } public void testFindSmallestTermFromNotExistentTerm() throws IOException { SmallestTermAndExhausted smallestTermAndExhausted = getSmallestTermAndExhausted("foo"); BytesRef smallestTerm = smallestTermAndExhausted.getSmallestTerm(); int[] exhausted = smallestTermAndExhausted.getExhausted(); assertThat(smallestTerm.utf8ToString(), equalTo("forget")); int i = -1; int numExhausted = 0; for (TermsEnum termsEnum : smallestTermAndExhausted.getTermsIters()) { i++; if (exhausted[i] == 1) { numExhausted++; } else { assertThat(termsEnum.term().utf8ToString().compareTo("foo"), greaterThanOrEqualTo(0)); } } assertThat(numExhausted, equalTo(2)); } public void testFindSmallestAllExhausted() throws IOException { SmallestTermAndExhausted smallestTermAndExhausted = getSmallestTermAndExhausted("zonk"); BytesRef smallestTerm = smallestTermAndExhausted.getSmallestTerm(); int[] exhausted = smallestTermAndExhausted.getExhausted(); assertThat(smallestTerm, equalTo(null)); for (int i = 0; i < 4; i++) { assertThat(exhausted[i], equalTo(1)); } } private SmallestTermAndExhausted getSmallestTermAndExhausted(String from) throws IOException { AllTermsShardRequest request = new AllTermsShardRequest(new AllTermsRequest(), "index", 0, "field", 1, from, 0); List<TermsEnum> termIters = getTermsEnums(request, reader.leaves()); assertThat(termIters.size(), equalTo(4)); BytesRef smallestTerm = null; int[] exhausted = new int[termIters.size()]; smallestTerm = TransportAllTermsShardAction.findSmallestTermAfter(request, termIters, smallestTerm, exhausted); return new SmallestTermAndExhausted(smallestTerm, exhausted, termIters); } private class SmallestTermAndExhausted { private BytesRef smallestTerm; private int[] exhausted; private List<TermsEnum> termsIters; public BytesRef getSmallestTerm() { return smallestTerm; } public int[] getExhausted() { return exhausted; } SmallestTermAndExhausted(BytesRef smallestTerm, int[] exhausted, List<TermsEnum> termsIters) { this.smallestTerm = smallestTerm; this.exhausted = exhausted; this.termsIters = termsIters; } public List<TermsEnum> getTermsIters() { return termsIters; } } public void testDocFreqForExistingTerm() throws IOException { SmallestTermAndExhausted smallestTermAndExhausted = getSmallestTermAndExhausted("careful"); BytesRef smallestTerm = smallestTermAndExhausted.getSmallestTerm(); int[] exhausted = smallestTermAndExhausted.getExhausted(); assertThat(TransportAllTermsShardAction.getDocFreq(smallestTermAndExhausted.getTermsIters(), smallestTerm, exhausted), equalTo(2L)); } public void testDocFreqForNotExistingTerm() throws IOException { SmallestTermAndExhausted smallestTermAndExhausted = getSmallestTermAndExhausted("careful"); BytesRef smallestTerm = new BytesRef("do"); int[] exhausted = smallestTermAndExhausted.getExhausted(); assertThat(TransportAllTermsShardAction.getDocFreq(smallestTermAndExhausted.getTermsIters(), smallestTerm, exhausted), equalTo(0L)); } public void testMoveIterators() throws IOException { SmallestTermAndExhausted smallestTermAndExhausted = getSmallestTermAndExhausted("a"); BytesRef smallestTerm = new BytesRef(smallestTermAndExhausted.getSmallestTerm().utf8ToString()); TransportAllTermsShardAction.moveIterators(smallestTermAndExhausted.exhausted, smallestTermAndExhausted.getTermsIters(), smallestTerm); for (int i = 0; i < 4; i++) { assertThat(smallestTermAndExhausted.getTermsIters().get(i).term(), greaterThan(smallestTerm)); } } public void testMoveIteratorsWithSomeExhaustion() throws IOException { SmallestTermAndExhausted smallestTermAndExhausted = getSmallestTermAndExhausted("careful"); BytesRef smallestTerm = new BytesRef(smallestTermAndExhausted.getSmallestTerm().utf8ToString()); TransportAllTermsShardAction.moveIterators(smallestTermAndExhausted.exhausted, smallestTermAndExhausted.getTermsIters(), smallestTerm); int exhausted = 0; for (int i = 0; i < 4; i++) { if (smallestTermAndExhausted.getExhausted()[i] != 1) { assertThat(smallestTermAndExhausted.getTermsIters().get(i).term(), greaterThan(smallestTerm)); } else { exhausted++; } } assertThat(exhausted, equalTo(2)); } public void testFindSmallestTerm() throws IOException { SmallestTermAndExhausted smallestTermAndExhausted = getSmallestTermAndExhausted("careful"); BytesRef smallestTerm = new BytesRef(smallestTermAndExhausted.getSmallestTerm().utf8ToString()); BytesRef newSmallestTerm = TransportAllTermsShardAction.findMinimum(smallestTermAndExhausted.exhausted, smallestTermAndExhausted.getTermsIters()); assertThat(newSmallestTerm.utf8ToString(), equalTo(smallestTerm.utf8ToString())); } public void testGetAllTermsFromBeginning() throws IOException { AllTermsShardRequest request = new AllTermsShardRequest(new AllTermsRequest(), "index", 0, "field", 10, null, 0); List<String> terms = new ArrayList<>(); TransportAllTermsShardAction.getTerms(request, terms, reader.leaves()); assertArrayEquals(terms.toArray(new String[6]), new String[]{"always", "be", "careful", "don't", "ever", "forget"}); } public void testGetAllTermsFromBeginningExact() throws IOException { AllTermsShardRequest request = new AllTermsShardRequest(new AllTermsRequest(), "index", 0, "field", 6, null, 0); List<String> terms = new ArrayList<>(); TransportAllTermsShardAction.getTerms(request, terms, reader.leaves()); assertArrayEquals(terms.toArray(new String[6]), new String[]{"always", "be", "careful", "don't", "ever", "forget"}); } public void testGetSomeTerms() throws IOException { AllTermsShardRequest request = new AllTermsShardRequest(new AllTermsRequest(), "index", 0, "field", 3, null, 0); List<String> terms = new ArrayList<>(); TransportAllTermsShardAction.getTerms(request, terms, reader.leaves()); assertArrayEquals(terms.toArray(new String[3]), new String[]{"always", "be", "careful"}); } public void testGetSomeTermsFrom() throws IOException { AllTermsShardRequest request = new AllTermsShardRequest(new AllTermsRequest(), "index", 0, "field", 3, "careful", 0); List<String> terms = new ArrayList<>(); TransportAllTermsShardAction.getTerms(request, terms, reader.leaves()); assertArrayEquals(terms.toArray(new String[3]), new String[]{"don't", "ever", "forget"}); } }