KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > db4o > db4ounit > common > fieldindex > FieldIndexProcessorTestCase


1 /* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com
2
3 This file is part of the db4o open source object database.
4
5 db4o is free software; you can redistribute it and/or modify it under
6 the terms of version 2 of the GNU General Public License as published
7 by the Free Software Foundation and as clarified by db4objects' GPL
8 interpretation policy, available at
9 http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
10 Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
11 Suite 350, San Mateo, CA 94403, USA.
12
13 db4o is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */

21 package com.db4o.db4ounit.common.fieldindex;
22
23 import com.db4o.*;
24 import com.db4o.config.*;
25 import com.db4o.db4ounit.common.btree.BTreeAssert;
26 import com.db4o.db4ounit.common.foundation.IntArrays4;
27 import com.db4o.inside.btree.BTree;
28 import com.db4o.inside.fieldindex.*;
29 import com.db4o.query.*;
30
31 import db4ounit.Assert;
32
33
34 public class FieldIndexProcessorTestCase extends FieldIndexProcessorTestCaseBase {
35     
36     public static void main(String JavaDoc[] args) {
37         new FieldIndexProcessorTestCase().runSolo();
38     }
39     
40     protected void configure(Configuration config) {
41         super.configure(config);
42         indexField(config,NonIndexedFieldIndexItem.class, "indexed");
43     }
44     
45     protected void store() {
46         storeItems(new int[] { 3, 4, 7, 9 });
47         storeComplexItems(
48                         new int[] { 3, 4, 7, 9 },
49                         new int[] { 2, 2, 8, 8 });
50     }
51     
52     public void testIdentity(){
53         Query query = createComplexItemQuery();
54         query.descend("foo").constrain(new Integer JavaDoc(3));
55         ComplexFieldIndexItem item = (ComplexFieldIndexItem) query.execute().next();
56         
57         query = createComplexItemQuery();
58         query.descend("child").constrain(item).identity();
59         assertExpectedFoos(ComplexFieldIndexItem.class, new int[]{4}, query);
60     }
61     
62
63     public void testSingleIndexNotSmaller(){
64         final Query query = createItemQuery();
65         query.descend("foo").constrain(new Integer JavaDoc(5)).smaller().not();
66         assertExpectedFoos(FieldIndexItem.class, new int[]{7, 9}, query);
67     }
68     
69     public void testSingleIndexNotGreater(){
70         final Query query = createItemQuery();
71         query.descend("foo").constrain(new Integer JavaDoc(4)).greater().not();
72         assertExpectedFoos(FieldIndexItem.class, new int[]{3, 4}, query);
73     }
74     
75     public void testSingleIndexSmallerOrEqual() {
76         final Query query = createItemQuery();
77         query.descend("foo").constrain(new Integer JavaDoc(7)).smaller().equal();
78         assertExpectedFoos(FieldIndexItem.class, new int[] { 3,4,7 }, query);
79     }
80
81     public void testSingleIndexGreaterOrEqual() {
82         final Query query = createItemQuery();
83         query.descend("foo").constrain(new Integer JavaDoc(7)).greater().equal();
84         assertExpectedFoos(FieldIndexItem.class, new int[] { 7, 9 }, query);
85     }
86     
87     public void testSingleIndexRange(){
88         final Query query = createItemQuery();
89         query.descend("foo").constrain(new Integer JavaDoc(3)).greater();
90         query.descend("foo").constrain(new Integer JavaDoc(9)).smaller();
91         assertExpectedFoos(FieldIndexItem.class, new int[] { 4, 7 }, query);
92     }
93     
94     public void testSingleIndexAndRange(){
95         final Query query = createItemQuery();
96         Constraint c1 = query.descend("foo").constrain(new Integer JavaDoc(3)).greater();
97         Constraint c2 = query.descend("foo").constrain(new Integer JavaDoc(9)).smaller();
98         c1.and(c2);
99         assertExpectedFoos(FieldIndexItem.class, new int[] { 4, 7 }, query);
100     }
101     
102     public void testSingleIndexOr(){
103         final Query query = createItemQuery();
104         Constraint c1 = query.descend("foo").constrain(new Integer JavaDoc(4)).smaller();
105         Constraint c2 = query.descend("foo").constrain(new Integer JavaDoc(7)).greater();
106         c1.or(c2);
107         assertExpectedFoos(FieldIndexItem.class, new int[] { 3, 9 }, query);
108     }
109     
110     public void testExplicitAndOverOr() {
111         assertAndOverOrQuery(true);
112     }
113     
114     public void testImplicitAndOverOr() {
115         assertAndOverOrQuery(false);
116     }
117
118     private void assertAndOverOrQuery(boolean explicitAnd) {
119         Query query = createItemQuery();
120         Constraint c1 = query.descend("foo").constrain(new Integer JavaDoc(3));
121         Constraint c2 = query.descend("foo").constrain(new Integer JavaDoc(9));
122         Constraint c3 = query.descend("foo").constrain(new Integer JavaDoc(3));
123         Constraint c4 = query.descend("foo").constrain(new Integer JavaDoc(7));
124         Constraint cc1 = c1.or(c2);
125         Constraint cc2 = c3.or(c4);
126         if (explicitAnd) {
127             cc1.and(cc2);
128         }
129         assertExpectedFoos(FieldIndexItem.class, new int[] { 3 }, query);
130     }
131     
132     public void testSingleIndexOrRange() {
133         Query query = createItemQuery();
134         Constraint c1 = query.descend("foo").constrain(new Integer JavaDoc(1)).greater();
135         Constraint c2 = query.descend("foo").constrain(new Integer JavaDoc(4)).smaller();
136         Constraint c3 = query.descend("foo").constrain(new Integer JavaDoc(4)).greater();
137         Constraint c4 = query.descend("foo").constrain(new Integer JavaDoc(10)).smaller();
138         Constraint cc1 = c1.and(c2);
139         Constraint cc2 = c3.and(c4);
140         cc1.or(cc2);
141         assertExpectedFoos(FieldIndexItem.class, new int[] { 3, 7, 9 }, query);
142     }
143     
144     public void testImplicitAndOnOrs() {
145         Query query = createItemQuery();
146         Constraint c1 = query.descend("foo").constrain(new Integer JavaDoc(4)).smaller();
147         Constraint c2 = query.descend("foo").constrain(new Integer JavaDoc(3)).greater();
148         Constraint c3 = query.descend("foo").constrain(new Integer JavaDoc(4)).greater();
149         c1.or(c2);
150         c1.or(c3);
151         
152         assertExpectedFoos(FieldIndexItem.class, new int[] { 3, 4, 7, 9 }, query);
153     }
154     
155     public void testTwoLevelDescendOr() {
156         Query query = createComplexItemQuery();
157         Constraint c1 = query.descend("child").descend("foo").constrain(new Integer JavaDoc(4)).smaller();
158         Constraint c2 = query.descend("child").descend("foo").constrain(new Integer JavaDoc(4)).greater();
159         c1.or(c2);
160         assertExpectedFoos(ComplexFieldIndexItem.class, new int[] { 4, 9 }, query);
161     }
162     
163     public void _testOrOnDifferentFields(){
164         final Query query = createComplexItemQuery();
165         Constraint c1 = query.descend("foo").constrain(new Integer JavaDoc(3));
166         Constraint c2 = query.descend("bar").constrain(new Integer JavaDoc(8));
167         c1.or(c2);
168         assertExpectedFoos(ComplexFieldIndexItem.class, new int[] { 3, 7, 9 }, query);
169     }
170     
171     public void testCantOptimizeOrInvolvingNonIndexedField() {
172         final Query query = createQuery(NonIndexedFieldIndexItem.class);
173         final Constraint c1 = query.descend("indexed").constrain(new Integer JavaDoc(1));
174         final Constraint c2 = query.descend("foo").constrain(new Integer JavaDoc(2));
175         c1.or(c2);
176         assertCantOptimize(query);
177     }
178     
179     public void testCantOptimizeDifferentLevels(){
180         final Query query = createComplexItemQuery();
181         Constraint c1 = query.descend("child").descend("foo").constrain(new Integer JavaDoc(4)).smaller();
182         Constraint c2 = query.descend("foo").constrain(new Integer JavaDoc(7)).greater();
183         c1.or(c2);
184         assertCantOptimize(query);
185     }
186     
187     public void testCantOptimizeJoinOnNonIndexedFields() {
188         final Query query = createQuery(NonIndexedFieldIndexItem.class);
189         final Constraint c1 = query.descend("foo").constrain(new Integer JavaDoc(1));
190         final Constraint c2 = query.descend("foo").constrain(new Integer JavaDoc(2));
191         c1.or(c2);
192         assertCantOptimize(query);
193     }
194     
195     private void assertCantOptimize(Query query) {
196         final FieldIndexProcessorResult result = executeProcessor(query);
197         Assert.areSame(FieldIndexProcessorResult.NO_INDEX_FOUND, result);
198     }
199
200     public void testIndexSelection() {
201         Query query = createComplexItemQuery();
202         query.descend("bar").constrain(new Integer JavaDoc(2));
203         query.descend("foo").constrain(new Integer JavaDoc(3));
204         
205         assertBestIndex("foo", query);
206         
207         query = createComplexItemQuery();
208         query.descend("foo").constrain(new Integer JavaDoc(3));
209         query.descend("bar").constrain(new Integer JavaDoc(2));
210         
211         assertBestIndex("foo", query);
212     }
213
214     private void assertBestIndex(String JavaDoc expectedFieldIndex, final Query query) {
215         IndexedNode node = selectBestIndex(query);
216         assertComplexItemIndex(expectedFieldIndex, node);
217     }
218
219     public void testDoubleDescendingOnQuery() {
220         final Query query = createComplexItemQuery();
221         query.descend("child").descend("foo").constrain(new Integer JavaDoc(3));
222         assertExpectedFoos(ComplexFieldIndexItem.class, new int[] { 4 }, query);
223     }
224     
225     public void testTripleDescendingOnQuery() {
226         final Query query = createComplexItemQuery();
227         query.descend("child").descend("child").descend("foo").constrain(new Integer JavaDoc(3));
228         assertExpectedFoos(ComplexFieldIndexItem.class, new int[] { 7 }, query);
229     }
230
231     public void testMultiTransactionSmallerWithCommit() {
232         final Transaction transaction = newTransaction();
233         fillTransactionWith(transaction, 0);
234         
235         int[] expectedZeros = newBTreeNodeSizedArray(0);
236         assertSmaller(transaction, expectedZeros, 3);
237         
238         transaction.commit();
239         
240         fillTransactionWith(transaction, 5);
241         assertSmaller(IntArrays4.concat(expectedZeros, new int[] { 3, 4 }), 7);
242     }
243
244     public void testMultiTransactionWithRollback() {
245         final Transaction transaction = newTransaction();
246         fillTransactionWith(transaction, 0);
247         
248         int[] expectedZeros = newBTreeNodeSizedArray(0);
249         assertSmaller(transaction, expectedZeros, 3);
250         
251         transaction.rollback();
252         
253         assertSmaller(transaction, new int[0], 3);
254         
255         fillTransactionWith(transaction, 5);
256         assertSmaller(new int[] { 3, 4 }, 7);
257     }
258     
259     public void testMultiTransactionSmaller() {
260         final Transaction transaction = newTransaction();
261         fillTransactionWith(transaction, 0);
262         
263         int[] expected = newBTreeNodeSizedArray(0);
264         assertSmaller(transaction, expected, 3);
265         
266         fillTransactionWith(transaction, 5);
267         assertSmaller(new int[] { 3, 4 }, 7);
268     }
269
270     public void testMultiTransactionGreater() {
271         fillTransactionWith(systemTrans(), 10);
272         fillTransactionWith(systemTrans(), 5);
273         assertGreater(new int[] { 4, 7, 9 }, 3);
274         removeFromTransaction(systemTrans(), 5);
275         assertGreater(new int[] { 4, 7, 9 }, 3);
276         removeFromTransaction(systemTrans(), 10);
277         assertGreater(new int[] { 4, 7, 9 }, 3);
278     }
279     
280     public void testSingleIndexEquals() {
281         final int expectedBar = 3;
282         assertExpectedFoos(FieldIndexItem.class, new int[] { expectedBar }, createQuery(expectedBar));
283     }
284     
285     public void testSingleIndexSmaller() {
286         assertSmaller(new int[] { 3, 4 }, 7);
287     }
288
289     public void testSingleIndexGreater() {
290         assertGreater(new int[] { 4, 7, 9 }, 3);
291     }
292     
293     private void assertGreater(int[] expectedFoos, int greaterThan) {
294         final Query query = createItemQuery();
295         query.descend("foo").constrain(new Integer JavaDoc(greaterThan)).greater();
296         assertExpectedFoos(FieldIndexItem.class, expectedFoos, query);
297     }
298     
299     private void assertExpectedFoos(Class JavaDoc itemClass, final int[] expectedFoos, final Query query) {
300         final Transaction trans = transactionFromQuery(query);
301         final int[] expectedIds = mapToObjectIds(createQuery(trans, itemClass), expectedFoos);
302         assertExpectedIDs(expectedIds, query);
303     }
304     
305     private void assertExpectedIDs(final int[] expectedIds, final Query query) {
306         final FieldIndexProcessorResult result = executeProcessor(query);
307         if (expectedIds.length == 0) {
308             Assert.areSame(FieldIndexProcessorResult.FOUND_INDEX_BUT_NO_MATCH, result);
309             return;
310         }
311                  
312         assertTreeInt(expectedIds, result.toTreeInt());
313     }
314
315     private FieldIndexProcessorResult executeProcessor(final Query query) {
316         return createProcessor(query).run();
317     }
318
319     private Transaction transactionFromQuery(Query query) {
320         return ((QQuery)query).getTransaction();
321     }
322
323     private BTree btree(){
324         return fieldIndexBTree(FieldIndexItem.class, "foo");
325     }
326
327     private void store(final Transaction trans, final FieldIndexItem item) {
328         stream().set(trans, item);
329     }
330     
331     private void fillTransactionWith(Transaction trans, final int bar) {
332         for (int i=0; i<BTreeAssert.fillSize(btree()); ++i) {
333             store(trans, new FieldIndexItem(bar));
334         }
335     }
336
337     private int[] newBTreeNodeSizedArray(int value) {
338         final BTree btree = btree();
339         return BTreeAssert.newBTreeNodeSizedArray(btree, value);
340     }
341
342     private void removeFromTransaction(Transaction trans, final int foo) {
343         final ObjectSet found = createItemQuery(trans).execute();
344         while (found.hasNext()) {
345             FieldIndexItem item = (FieldIndexItem)found.next();
346             if (item.foo == foo) {
347                 stream().delete(trans, item);
348             }
349         }
350     }
351     
352     private void assertSmaller(final int[] expectedFoos, final int smallerThan) {
353         assertSmaller(trans(), expectedFoos, smallerThan);
354     }
355
356     private void assertSmaller(final Transaction transaction, final int[] expectedFoos, final int smallerThan) {
357         final Query query = createItemQuery(transaction);
358         query.descend("foo").constrain(new Integer JavaDoc(smallerThan)).smaller();
359         assertExpectedFoos(FieldIndexItem.class, expectedFoos, query);
360     }
361
362 }
363
Popular Tags