1 package org.apache.lucene.facet.taxonomy.lucene;
5 import org.apache.lucene.store.Directory;
8 import org.apache.lucene.util.IOUtils;
9 import org.apache.lucene.util.LuceneTestCase;
10 import org.apache.lucene.util._TestUtil;
11 import org.apache.lucene.facet.taxonomy.CategoryPath;
12 import org.apache.lucene.facet.taxonomy.TaxonomyReader;
13 import org.apache.lucene.facet.taxonomy.lucene.LuceneTaxonomyReader;
14 import org.apache.lucene.facet.taxonomy.lucene.LuceneTaxonomyWriter;
15 import org.apache.lucene.facet.taxonomy.lucene.LuceneTaxonomyWriter.DiskOrdinalMap;
16 import org.apache.lucene.facet.taxonomy.lucene.LuceneTaxonomyWriter.MemoryOrdinalMap;
17 import org.apache.lucene.facet.taxonomy.lucene.LuceneTaxonomyWriter.OrdinalMap;
20 * Licensed to the Apache Software Foundation (ASF) under one or more
21 * contributor license agreements. See the NOTICE file distributed with
22 * this work for additional information regarding copyright ownership.
23 * The ASF licenses this file to You under the Apache License, Version 2.0
24 * (the "License"); you may not use this file except in compliance with
25 * the License. You may obtain a copy of the License at
27 * http://www.apache.org/licenses/LICENSE-2.0
29 * Unless required by applicable law or agreed to in writing, software
30 * distributed under the License is distributed on an "AS IS" BASIS,
31 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32 * See the License for the specific language governing permissions and
33 * limitations under the License.
36 public class TestAddTaxonomies extends LuceneTestCase {
39 public void test1() throws Exception {
40 Directory dir1 = newDirectory();
41 LuceneTaxonomyWriter tw1 = new LuceneTaxonomyWriter(dir1);
42 tw1.addCategory(new CategoryPath("Author", "Mark Twain"));
43 tw1.addCategory(new CategoryPath("Animals", "Dog"));
44 Directory dir2 = newDirectory();
45 LuceneTaxonomyWriter tw2 = new LuceneTaxonomyWriter(dir2);
46 tw2.addCategory(new CategoryPath("Author", "Rob Pike"));
47 tw2.addCategory(new CategoryPath("Aardvarks", "Bob"));
49 Directory dir3 = newDirectory();
50 LuceneTaxonomyWriter tw3 = new LuceneTaxonomyWriter(dir3);
51 tw3.addCategory(new CategoryPath("Author", "Zebra Smith"));
52 tw3.addCategory(new CategoryPath("Aardvarks", "Bob"));
53 tw3.addCategory(new CategoryPath("Aardvarks", "Aaron"));
56 MemoryOrdinalMap[] maps = new MemoryOrdinalMap[2];
57 maps[0] = new MemoryOrdinalMap();
58 maps[1] = new MemoryOrdinalMap();
60 tw1.addTaxonomies(new Directory[] { dir2, dir3 }, maps);
63 TaxonomyReader tr = new LuceneTaxonomyReader(dir1);
65 // Test that the merged taxonomy now contains what we expect:
66 // First all the categories of the original taxonomy, in their original order:
67 assertEquals(tr.getPath(0).toString(), "");
68 assertEquals(tr.getPath(1).toString(), "Author");
69 assertEquals(tr.getPath(2).toString(), "Author/Mark Twain");
70 assertEquals(tr.getPath(3).toString(), "Animals");
71 assertEquals(tr.getPath(4).toString(), "Animals/Dog");
72 // Then the categories new in the new taxonomy, in alphabetical order:
73 assertEquals(tr.getPath(5).toString(), "Aardvarks");
74 assertEquals(tr.getPath(6).toString(), "Aardvarks/Aaron");
75 assertEquals(tr.getPath(7).toString(), "Aardvarks/Bob");
76 assertEquals(tr.getPath(8).toString(), "Author/Rob Pike");
77 assertEquals(tr.getPath(9).toString(), "Author/Zebra Smith");
78 assertEquals(tr.getSize(), 10);
80 // Test that the maps contain what we expect
81 int[] map0 = maps[0].getMap();
82 assertEquals(5, map0.length);
83 assertEquals(0, map0[0]);
84 assertEquals(1, map0[1]);
85 assertEquals(8, map0[2]);
86 assertEquals(5, map0[3]);
87 assertEquals(7, map0[4]);
89 int[] map1 = maps[1].getMap();
90 assertEquals(6, map1.length);
91 assertEquals(0, map1[0]);
92 assertEquals(1, map1[1]);
93 assertEquals(9, map1[2]);
94 assertEquals(5, map1[3]);
95 assertEquals(7, map1[4]);
96 assertEquals(6, map1[5]);
104 // a reasonable random test
105 public void testmedium() throws Exception {
106 int numTests = atLeast(3);
107 for (int i = 0; i < numTests; i++) {
108 dotest(_TestUtil.nextInt(random, 1, 10),
109 _TestUtil.nextInt(random, 1, 100),
110 _TestUtil.nextInt(random, 100, 1000),
111 random.nextBoolean());
115 // A more comprehensive and big random test.
117 public void testbig() throws Exception {
118 dotest(2, 1000, 5000, false);
119 dotest(10, 10000, 100, false);
120 dotest(50, 20, 100, false);
121 dotest(10, 1000, 10000, false);
122 dotest(50, 20, 10000, false);
123 dotest(1, 20, 10000, false);
124 dotest(10, 1, 10000, false);
125 dotest(10, 1000, 20000, true);
128 private void dotest(int ntaxonomies, int ncats, int range, boolean disk) throws Exception {
129 Directory dirs[] = new Directory[ntaxonomies];
130 Directory copydirs[] = new Directory[ntaxonomies];
132 for (int i=0; i<ntaxonomies; i++) {
133 dirs[i] = newDirectory();
134 copydirs[i] = newDirectory();
135 LuceneTaxonomyWriter tw = new LuceneTaxonomyWriter(dirs[i]);
136 LuceneTaxonomyWriter copytw = new LuceneTaxonomyWriter(copydirs[i]);
137 for (int j=0; j<ncats; j++) {
138 String cat = Integer.toString(random.nextInt(range));
139 tw.addCategory(new CategoryPath("a",cat));
140 copytw.addCategory(new CategoryPath("a",cat));
142 // System.err.println("Taxonomy "+i+": "+tw.getSize());
147 LuceneTaxonomyWriter tw = new LuceneTaxonomyWriter(dirs[0]);
148 Directory otherdirs[] = new Directory[ntaxonomies-1];
149 System.arraycopy(dirs, 1, otherdirs, 0, ntaxonomies-1);
151 OrdinalMap[] maps = new OrdinalMap[ntaxonomies-1];
153 for (int i=0; i<ntaxonomies-1; i++) {
155 // TODO: use a LTC tempfile
156 maps[i] = new DiskOrdinalMap(new File(System.getProperty("java.io.tmpdir"),
159 maps[i] = new MemoryOrdinalMap();
164 tw.addTaxonomies(otherdirs, maps);
165 // System.err.println("Merged axonomy: "+tw.getSize());
168 // Check that all original categories in the main taxonomy remain in
169 // unchanged, and the rest of the taxonomies are completely unchanged.
170 for (int i=0; i<ntaxonomies; i++) {
171 TaxonomyReader tr = new LuceneTaxonomyReader(dirs[i]);
172 TaxonomyReader copytr = new LuceneTaxonomyReader(copydirs[i]);
174 assertTrue(tr.getSize() >= copytr.getSize());
176 assertEquals(copytr.getSize(), tr.getSize());
178 for (int j=0; j<copytr.getSize(); j++) {
179 String expected = copytr.getPath(j).toString();
180 String got = tr.getPath(j).toString();
181 assertTrue("Comparing category "+j+" of taxonomy "+i+": expected "+expected+", got "+got,
182 expected.equals(got));
188 // Check that all the new categories in the main taxonomy are in
189 // lexicographic order. This isn't a requirement of our API, but happens
190 // this way in our current implementation.
191 TaxonomyReader tr = new LuceneTaxonomyReader(dirs[0]);
192 TaxonomyReader copytr = new LuceneTaxonomyReader(copydirs[0]);
193 if (tr.getSize() > copytr.getSize()) {
194 String prev = tr.getPath(copytr.getSize()).toString();
195 for (int j=copytr.getSize()+1; j<tr.getSize(); j++) {
196 String n = tr.getPath(j).toString();
197 assertTrue(prev.compareTo(n)<0);
201 int oldsize = copytr.getSize(); // remember for later
205 // Check that all the categories from other taxonomies exist in the new
207 TaxonomyReader main = new LuceneTaxonomyReader(dirs[0]);
208 for (int i=1; i<ntaxonomies; i++) {
209 TaxonomyReader other = new LuceneTaxonomyReader(dirs[i]);
210 for (int j=0; j<other.getSize(); j++) {
211 int otherord = main.getOrdinal(other.getPath(j));
212 assertTrue(otherord != TaxonomyReader.INVALID_ORDINAL);
217 // Check that all the new categories in the merged taxonomy exist in
218 // one of the added taxonomies.
219 TaxonomyReader[] others = new TaxonomyReader[ntaxonomies-1];
220 for (int i=1; i<ntaxonomies; i++) {
221 others[i-1] = new LuceneTaxonomyReader(dirs[i]);
223 for (int j=oldsize; j<main.getSize(); j++) {
225 CategoryPath path = main.getPath(j);
226 for (int i=1; i<ntaxonomies; i++) {
227 if (others[i-1].getOrdinal(path) != TaxonomyReader.INVALID_ORDINAL) {
233 fail("Found category "+j+" ("+path+") in merged taxonomy not in any of the separate ones");
237 // Check that all the maps are correct
238 for (int i=0; i<ntaxonomies-1; i++) {
239 int[] map = maps[i].getMap();
240 for (int j=0; j<map.length; j++) {
241 assertEquals(map[j], main.getOrdinal(others[i].getPath(j)));
245 for (int i=1; i<ntaxonomies; i++) {
251 IOUtils.close(copydirs);