add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / contrib / facet / src / test / org / apache / lucene / facet / taxonomy / lucene / TestAddTaxonomies.java
1 package org.apache.lucene.facet.taxonomy.lucene;
2
3 import java.io.File;
4
5 import org.apache.lucene.store.Directory;
6 import org.junit.Test;
7
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;
18
19 /**
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
26  *
27  *     http://www.apache.org/licenses/LICENSE-2.0
28  *
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.
34  */
35
36 public class TestAddTaxonomies extends LuceneTestCase {
37
38   @Test
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"));
48     tw2.close();
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"));
54     tw3.close();
55
56     MemoryOrdinalMap[] maps = new MemoryOrdinalMap[2];
57     maps[0] = new MemoryOrdinalMap();
58     maps[1] = new MemoryOrdinalMap();
59
60     tw1.addTaxonomies(new Directory[] { dir2, dir3 }, maps);
61     tw1.close();
62
63     TaxonomyReader tr = new LuceneTaxonomyReader(dir1);
64
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);
79
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]);
88
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]);
97     
98     tr.close();
99     dir1.close();
100     dir2.close();
101     dir3.close();
102   }
103
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());
112     }
113   }
114
115   // A more comprehensive and big random test.
116   @Test @Nightly
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);
126   }
127
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];
131
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));
141       }
142       // System.err.println("Taxonomy "+i+": "+tw.getSize());
143       tw.close();
144       copytw.close();
145     }
146
147     LuceneTaxonomyWriter tw = new LuceneTaxonomyWriter(dirs[0]);
148     Directory otherdirs[] = new Directory[ntaxonomies-1];
149     System.arraycopy(dirs, 1, otherdirs, 0, ntaxonomies-1);
150
151     OrdinalMap[] maps = new OrdinalMap[ntaxonomies-1];
152     if (ntaxonomies>1) {
153       for (int i=0; i<ntaxonomies-1; i++) {
154         if (disk) {
155           // TODO: use a LTC tempfile
156           maps[i] = new DiskOrdinalMap(new File(System.getProperty("java.io.tmpdir"),
157               "tmpmap"+i));
158         } else {
159           maps[i] = new MemoryOrdinalMap();
160         }
161       }
162     }
163
164     tw.addTaxonomies(otherdirs, maps);
165     // System.err.println("Merged axonomy: "+tw.getSize());
166     tw.close();
167
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]);
173       if (i==0) {
174         assertTrue(tr.getSize() >= copytr.getSize());
175       } else {
176         assertEquals(copytr.getSize(), tr.getSize());
177       }
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));
183       }
184       tr.close();
185       copytr.close();
186     }
187
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);
198         prev=n;
199       }
200     }
201     int oldsize = copytr.getSize(); // remember for later
202     tr.close();
203     copytr.close();
204
205     // Check that all the categories from other taxonomies exist in the new
206     // taxonomy.
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);
213       }
214       other.close();
215     }
216
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]);
222     }
223     for (int j=oldsize; j<main.getSize(); j++) {
224       boolean found=false;
225       CategoryPath path = main.getPath(j);
226       for (int i=1; i<ntaxonomies; i++) {
227         if (others[i-1].getOrdinal(path) != TaxonomyReader.INVALID_ORDINAL) {
228           found=true;
229           break;
230         }
231       }
232       if (!found) {
233         fail("Found category "+j+" ("+path+") in merged taxonomy not in any of the separate ones");
234       }
235     }
236
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)));
242       }
243     }
244
245     for (int i=1; i<ntaxonomies; i++) {
246       others[i-1].close();
247     }
248
249     main.close();
250     IOUtils.close(dirs);
251     IOUtils.close(copydirs);
252   }
253
254 }