KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jofti > btree > BTOperations


1 /*
2  * BTOperations.java
3  *
4  * Created on 26 May 2003, 08:53
5  */

6
7 package com.jofti.btree;
8
9
10 import java.util.ArrayList JavaDoc;
11 import java.util.Collection JavaDoc;
12 import java.util.LinkedHashMap JavaDoc;
13 import java.util.List JavaDoc;
14 import java.util.Map JavaDoc;
15
16 import com.jofti.exception.JoftiException;
17 import com.jofti.locking.LockManager;
18 import com.jofti.util.OpenHashMap;
19
20 /**
21  * Provides the group of low level operations that can be performed on the BTree. All
22  * operations on the BTree are performed by this class ,rather than directly on the tree.<p>
23  * <p>
24  * The class is essentially an encapsulation of the functional update,search, contains and remove variants used
25  * by the TreeIndex. The class does not retain a handle to any particular {@link BTree} and so the same instance can be used
26  * for the transactional {@link BTree} instances found in some Tree instances.
27  * </p>
28  *
29  *
30  * @author Steve Woodcock<br>
31  * @version 1.31
32  */

33 public class BTOperations {
34
35     private static NodeFactory factory = NodeFactory.getInstance();
36
37     /** Creates a new instance of BTOperations */
38     private BTOperations() {
39     }
40
41     /** approximate size of average results returned for map sizing*/
42     private static int avRangeResults = 100;
43     
44     /**
45      * Inserts a value in the tree using a specific dimension. The key/value/dimension are
46      * grouped into a leaf node entry as a single entity. <p>
47      *
48      * This method delegates the insert to the {@link BTree} insert method.
49      * <p>
50      * @param tree - the tree to insert the value into<br>
51      * @param key - the key to use as the unique id<br>
52      * @param object - the value to be inserted into the tree. This must be Comparable.<br>
53      * @param dimension - the dimension that this value is part of.<br>
54      * <br>
55      * @throws JoftiException a wrapping exception to trap errors in the tree.
56      */

57     public static void insertValue(BTree tree, Comparable JavaDoc key,
58             Comparable JavaDoc object, int dimension) throws JoftiException {
59
60         LeafNodeEntry entry = factory.createLeafNodeEntry(key, new ValueObject(dimension, object));
61         tree.insert(entry);
62     }
63
64     
65     /**
66      * Inserts a key and the object attributes in the tree using a specific key dimension. The key/attributes/dimension are
67      * grouped into a leaf node entry. <p>
68      *
69      * This method delegates the insert to the BTree insert method.
70      * <p>
71      * @param tree - the tree to insert the value into<br>
72      * @param key - the key to use as the unique id<br>
73      * @param object - the value to be inserted into the tree. This must be Comparable.<br>
74      * @param dimension - the dimension that this value is part of.<br>
75      * <br>
76      * @throws JoftiException a wrapping exception to trap errors in the tree.
77      */

78     public static void insertKeyValue(BTree tree, Comparable JavaDoc key,
79             Map JavaDoc attributes, int dimension) throws JoftiException {
80
81         LeafNodeEntry entry = factory.createLeafNodeEntry(key, new KeyValueObject(dimension, key, attributes));
82     
83         tree.insert(entry);
84     }
85
86     /**
87      * Removes a particular uniqueId from the tree if it is indexed with that value and dimension. If the value
88      * exists but the uniqueId is not stored with the value then no remove is performed. Otherwise the
89      * the uniqueid is removed from the value's id set.
90      * <p>
91      * @param tree - the tree to operate on.<br>
92      * @param uniqueId - the uniqueId to remove<br>
93      * @param object - the value to look for in the tree<br>
94      * @param dimension - the dimension that the value is in.<br>
95      * @throws JoftiException
96      */

97     public static void removeValue(BTree tree, Object JavaDoc uniqueId,
98             Comparable JavaDoc object, int dimension) throws JoftiException {
99         removeValueObject(tree, uniqueId, new ValueObject(dimension, object));
100     }
101
102     /**
103      * Removes a particular uniqueId from the tree if it is indexed with that
104      * valueObject. If the value
105      * exists but the uniqueId is not stored with the value then no remove is performed. Otherwise the
106      * the uniqueid is removed from the value's id set.<p>
107      *
108      * @param tree - the tree to operate on.<br>
109      * @param uniqueId - the uniqueId to remove<br>
110      * @param object - the value to look for in the tree<br>
111      * @throws JoftiException
112      */

113
114     public static void removeValueObject(BTree tree, Object JavaDoc uniqueId,
115             Comparable JavaDoc object) throws JoftiException {
116
117         LeafNodeEntry entry = factory.createLeafNodeEntry(uniqueId,object);
118         tree.removeEntry(entry);
119     }
120
121     /**
122      * Retrieves the matching uniqueIds for a particular value and dimension (if any).
123      * Failure to find a match returns an empty Map.<p>
124      *
125      * @param tree - the tree to perform the search upon.<br>
126      * @param obj - the object to search for.<br>
127      * @param dimension - the dimension that the value is in.<br>
128      * @return the Map of results.<br>
129      * @throws JoftiException
130      *
131      */

132     public static Map JavaDoc match(BTree tree, Comparable JavaDoc obj, int dimension) throws JoftiException{
133         return tree.matchDirect(new ValueObject(dimension, obj), null, null);
134     }
135     
136     /**
137      * Retrieves the matching uniqueIds for a particular value and dimension (if any). The valueReturn object is used to specify what field alias we should
138      * be looking for against this ID.
139      * Failure to find a match returns an empty Map.<p>
140      *
141      * @param tree - the tree to perform the search upon.<br>
142      * @param obj - the object to search for.<br>
143      * @param dimension - the dimension that the value is in.<br>
144      * @param valueReturn - The alias value of the object to return or null if we do not want to indicate a return restriction.<br>
145      * @return the Map of results.<br>
146      * @throws JoftiException
147      *
148      */

149     public static Map JavaDoc match(BTree tree, Comparable JavaDoc obj, int dimension, Object JavaDoc valueReturn) throws JoftiException{
150         return tree.matchDirect(new ValueObject(dimension, obj), null, valueReturn);
151     }
152
153     /**
154      * Retrieves the matching uniqueIds for a particular array of values and dimension (if any).
155      * Failure to find a match returns an empty Map.<p>
156      *
157      * @param tree - the tree to perofrm the search upon.<br>
158      * @param obj - the object to search for.<br>
159      * @param dimension - the dimension that the value is in.<br>
160      * @return the Map of results.<br>
161      * @throws JoftiException
162      *
163      */

164     public static Map JavaDoc match(BTree tree, Comparable JavaDoc[] obj, int dimension) throws JoftiException{
165         return match(tree, obj, dimension,null);
166         
167     }
168     
169     /**
170      * Retrieves the matching uniqueIds for a particular array of values and dimension (if any).
171      * The alias is used to pecify which alis we should use for the id. Failure to find a match returns an empty Map.<p>
172      *
173      * @param tree - the tree to perform the search upon.<br>
174      * @param obj - the object array containing the objects to search for.<br>
175      * @param dimension - the dimension that the value is in.<br>
176      * @param alias - The alias value of the object to return or null if we do not want to indicate a return restriction.<br>
177      * @return the Map of results.<br>
178      * @throws JoftiException
179      *
180      */

181     public static Map JavaDoc match(BTree tree, Comparable JavaDoc[] obj, int dimension, Object JavaDoc alias) throws JoftiException{
182         
183         OpenHashMap map = null;
184         for (int i =obj.length-1;i>=0;i--){
185             map = tree.matchDirect(new ValueObject(dimension, obj[i]), map,alias);
186         }
187         return map;
188     }
189     
190     /**
191      * Returns the keys that are mapped against the comparable value.
192      * @param tree
193      * @param obj
194      * @param dimension
195      * @return
196      * @throws JoftiException
197      */

198     public static Collection JavaDoc getKeyAttributes(BTree tree, Comparable JavaDoc obj,
199             int dimension) throws JoftiException {
200         
201         return tree.getAttributesDirect(new ValueObject(dimension, obj));
202     }
203     
204     
205
206     /**
207      * Checks if the tree contains a particular value in a dimension. This does not check if any
208      * uniqueIds are stored against the value.<p>
209      *
210      * @param tree - the tree to perform the search upon.<br>
211      * @param obj - the object to search for.<br>
212      * @param dimension - the dimension that the value is in.<br>
213      * @return the Map of results.<br>
214      * @throws JoftiException
215      */

216     public static boolean contains(BTree tree, Comparable JavaDoc obj, int dimension)
217             throws JoftiException {
218         return tree.containsDirect(new ValueObject(dimension, obj));
219
220     }
221
222     
223     
224     private static INode getContainingNode(BTree tree, Comparable JavaDoc obj,
225             int dimension) throws JoftiException {
226
227         //first get the node we think the entry should be in
228
ValueObject temp = new ValueObject(dimension, obj);
229         INode result = (INode) tree.search(temp);
230         if (result == null) {
231             return null;
232         }
233         // now get the entry - is it exists from the node
234
LeafNodeEntry val = ((IResultNode) result).getEntry(temp);
235         if (val == null) {
236             return null;
237         } else {
238             return ((ResultNode) result).getDelegate();
239         }
240     }
241
242     /**
243      * Gets a collection of all value/dimension matches in the tree for a specific uniqueid.
244      * This method is used when we have a uniqueId and no object left in the cache (due to expiry etc)
245      * and so the only alternative is a scan of the leaf nodes to find matches. This is very inefficient
246      * if there are a lot of values in the tree but some cache implementations leave us with no alternative, as there are
247      * no callbacks for some events.<p>
248      * @param tree - the Tree to search
249      * @param obj - the unique id to look for
250      * @param startDimension - the dimension where the key is by type.
251      * @return - a Collection of all the matching values that has the uniqueId
252      * @throws JoftiException
253      */

254     public static Collection JavaDoc getAllValuesForKey(BTree tree, Comparable JavaDoc obj,
255             int startDimension) throws JoftiException {
256         // get the start point in the tree for the key dimension in the tree
257
INode result = getContainingNode(tree, obj, startDimension);
258         if (result != null) {
259             // scan along the leaves if we find a key mapping
260
Collection JavaDoc col = getAllValuesInTree(tree, result, obj,
261                     startDimension);
262             return col;
263
264         } else {
265             // otherwise we should not have any entries ifthere is no key mapping
266
return new ArrayList JavaDoc();
267         }
268     }
269
270     /**
271      * Gets a collection of all value/dimension matches in the tree for a specific uniqueid.
272      * This method is used when we have a unique and no object left in the cache (due to expiry etc)
273      * and so the only alternative is a scan of the leaf nodes to find matches. This is very inefficient
274      * if there are a lot of values in the tree but some caches leave us with no alternative, as there are
275      * no callbacks for some events.<p>
276      * @param tree - the Tree to search
277      * @param realNode - the initial node for the first value.
278      * @param obj - the unique id to look for
279      * @param startDimension - the dimension where the key is by type.
280      * @return - a Collection of all the matching values that has the uniqueId
281      * @throws JoftiException
282      */

283
284     private static Collection JavaDoc getAllValuesInTree(BTree tree, INode realNode,
285             Comparable JavaDoc obj, int startDimension) throws JoftiException {
286
287         List JavaDoc resultList = new ArrayList JavaDoc();
288         // gives us the containing node of this value
289

290         if (realNode != null) {
291
292             // get a read lock on this node
293
try {
294                 boolean foundInDimension = false;
295                 boolean dimensionEnd = false;
296                 LockManager.acquireLock((Node) realNode, LockManager.READ_LOCK);
297                 boolean notEnd = true;
298
299                 while (notEnd) {
300                     Object JavaDoc[] entries = realNode.getEntries();
301                     for (int i = 0; i < entries.length; i++) {
302                         LeafNodeEntry entry = (LeafNodeEntry) entries[i];
303
304                         if (entry != BTree.MAX_LEAF_ENTRY) {
305                             if (entry.getUniqueIdSet().contains(obj)
306                                     && ((ValueObject) entry.getValue())
307                                             .getDimension() == startDimension) {
308
309                                 resultList.add(entry.getValue());
310                                 foundInDimension = true;
311                                 if (entries[entries.length - 1] != BTree.MAX_LEAF_ENTRY) {
312                                     break;
313                                 }
314                             } else if (((ValueObject) entry.getValue())
315                                     .getDimension() > startDimension) {
316
317                                 dimensionEnd = true;
318                                 break;
319                             }
320
321                         } else {
322                             notEnd = false;
323
324                         }
325                     }
326                     if (notEnd) {
327                         INode nextNode = null;
328                         if (foundInDimension || dimensionEnd) {
329
330                             nextNode = getLowestNodeForDimension(tree,
331                                     ++startDimension);
332
333                             foundInDimension = false;
334                             dimensionEnd = false;
335                         } else {
336                             nextNode = realNode.getLinkNode().getNode();
337
338                         }
339
340                         LockManager.releaseLock((Node) realNode,
341                                 LockManager.READ_LOCK);
342                         LockManager.acquireLock((Node) nextNode,
343                                 LockManager.READ_LOCK);
344
345                         realNode = nextNode;
346
347                     }
348                 }
349
350             } finally {
351                 LockManager.releaseLock((Node) realNode, LockManager.READ_LOCK);
352
353             }
354         }
355
356         return (Collection JavaDoc) resultList;
357
358     }
359
360     /**
361      * Gets a collection of all uniqueIds in tree for a specific dimension.<p>
362      
363      * @param tree - the Tree to search
364      * @param dimension - the dimension where the key is by type.
365      * @return - a Collection of all the matching values
366      * @throws JoftiException
367      */

368     public static Map JavaDoc getAllResultsForDimension(BTree tree, int dimension)
369             throws JoftiException {
370
371         return range(tree, ValueObject.MIN_COMAPARBLE_VALUE,
372                 ValueObject.MAX_COMAPARBLE_VALUE, dimension, true);
373
374     }
375
376     /**
377      * Gets the node containing the first entry for a dimension.<p>
378      
379      * @param tree - the Tree to search
380      * @param dimension - the dimension where the key is by type.
381      * @return - the starting node
382      * @throws JoftiException
383      */

384     public static INode getLowestNodeForDimension(BTree tree, int dimension)
385             throws JoftiException {
386         ValueObject temp = new ValueObject(dimension,
387                 ValueObject.MIN_COMAPARBLE_VALUE);
388
389         IResultNode result = (IResultNode) tree.search(temp);
390
391         return ((ResultNode) result).getDelegate();
392     }
393
394     /**
395      * Gets the node containing the last entry for a dimension.<p>
396      
397      * @param tree - the Tree to search
398      * @param dimension - the dimension where the key is by type.
399      * @return - the starting node
400      * @throws JoftiException
401      */

402     public static INode getHighestNodeForDimension(BTree tree, int dimension)
403             throws JoftiException {
404         ValueObject temp = new ValueObject(dimension,
405                 ValueObject.MAX_COMAPARBLE_VALUE);
406
407         IResultNode result = (IResultNode) tree.search(temp);
408
409         return ((ResultNode) result).getDelegate();
410     }
411
412     /**
413      * Gets all the uniqueIds that fall between the two objects for a dimension. If the startObj is NULL
414      * it is assumed that the lower range starts from the first value in the dimension. Similarly, if the endObj is NULL
415      * it is assumed the upper bound is the maximum value in the dimension. <p>
416      
417      * @param tree - the Tree to search
418      * @param startObj - the starting value for the range search
419      * @param endObj - the end value for the range search
420      * @param dimension - the dimension where the key is by type.
421      * @param inclusive - sets whether the range search should be inclusive of the start and end objects.
422      * @return - A Map of the results.
423      * @throws JoftiException
424      */

425      public static Map JavaDoc range(BTree tree, Comparable JavaDoc startObj, Comparable JavaDoc endObj,
426                 int dimension, boolean inclusive) throws JoftiException {
427
428          return rangeArray(tree, startObj,endObj,dimension,dimension, inclusive, null);
429      }
430      
431     /**
432      * Gets all the uniqueIds that fall between the two objects for a dimension. If the startObj is NULL
433      * it is assumed that the lower range starts from the first value in the dimension. Similarly, if the endObj is NULL
434      * it is assumed the upper bound is the maximum value in the dimension. <p>
435      
436      * @param tree - the Tree to search
437      * @param startObj - the starting value for the range search
438      * @param endObj - the end value for the range search
439      * @param dimension - the dimension where the key is by type.
440      * @param inclusive - sets whether the range search should be inclusive of the start and end objects.
441      * @param alias - passed back in the result map as the value to indicate what fields the key should filter on.
442      * @return - a Map of the results.
443      * @throws JoftiException
444      */

445      public static Map JavaDoc range(BTree tree, Comparable JavaDoc startObj, Comparable JavaDoc endObj,
446             int dimension, boolean inclusive, Object JavaDoc alias) throws JoftiException {
447
448      return rangeArray(tree, startObj,endObj,dimension,dimension, inclusive, alias);
449  }
450      
451    
452    
453     
454     private static Map JavaDoc rangeArray(BTree tree, Comparable JavaDoc startObj,
455             Comparable JavaDoc endObj, int dimension, int endDimension,
456             boolean inclusive, Object JavaDoc valueReturn) throws JoftiException {
457
458         // we use an OpenHashMap here as it has lower memory and better speed
459
// performance for larger numbers of results
460
final OpenHashMap map = new OpenHashMap(avRangeResults * 2, 0.00f, 0.5f);
461
462         if (startObj == null) {
463             startObj = ValueObject.MIN_COMAPARBLE_VALUE;
464         }
465         if (endObj == null) {
466             endObj = ValueObject.MAX_COMAPARBLE_VALUE;
467         }
468
469         ValueObject startRange = new ValueObject(dimension, startObj);
470         ValueObject finishRange = new ValueObject(endDimension, endObj);
471
472         // we do not need a lock on this node as it is a results node wrapper
473
IResultNode startNode = (IResultNode) tree.search(startRange);
474
475         boolean end = false;
476
477         while (!end) {
478             Object JavaDoc[] entries = startNode.getEntries();
479
480             int tempLength = entries.length;
481
482             // see if all are within range - we can short circuit some checks
483
if (entries[tempLength - 1] != BTree.MAX_LEAF_ENTRY
484                     && ((LeafNodeEntry) entries[0]).value.compareTo(startRange) > 0
485                     && ((LeafNodeEntry) entries[tempLength - 1]).value
486                             .compareTo(finishRange) < 0) {
487                 for (int i = 0; i < tempLength; i++) {
488                     LeafNodeEntry entry = (LeafNodeEntry) entries[i];
489
490                     Object JavaDoc[] tempSet = entry.uniqueIdSet.toArray();
491                     final int length = tempSet.length;
492                     map.ensureCapacity(map.size() + length);
493
494                     // has to be iterator
495
for (int j = length - 1; j >= 0; j--) {
496                         map.put(tempSet[j], valueReturn);
497                     }
498                 }
499             } else {
500                 // we need to look at all values
501
// change to int method of access
502
for (int i = 0; i < tempLength; i++) {
503                     LeafNodeEntry entry = (LeafNodeEntry) entries[i];
504                     if (entry != BTree.MAX_LEAF_ENTRY) {
505
506                         if (inclusive && entry.value.compareTo(startRange) >= 0
507                                 && entry.value.compareTo(finishRange) <= 0) {
508
509                             Object JavaDoc[] tempSet = entry.uniqueIdSet.toArray();
510                             final int length = tempSet.length;
511                             map.ensureCapacity(map.size() + length);
512
513                             // has to be iterator
514
for (int j = length - 1; j >= 0; j--) {
515                                 map.put(tempSet[j], valueReturn);
516                             }
517
518                         } else if ((!inclusive)
519                                 && entry.value.compareTo(startRange) > 0
520                                 && entry.value.compareTo(finishRange) < 0) {
521
522                             Object JavaDoc[] tempSet = entry.uniqueIdSet.toArray();
523                             final int length = tempSet.length;
524
525                             map.ensureCapacity(map.size() + length);
526
527                             // has to be iterator
528
for (int j = length - 1; j >= 0; j--) {
529                                 map.put(tempSet[j], valueReturn);
530                             }
531
532                         } else if (entry.value.compareTo(finishRange) > 0) {
533                             // we are at the end
534

535                             end = true;
536                             break;
537
538                         }
539                     } else {
540                         end = true;
541                         break;
542                     }
543
544                 }
545             }
546             if (!end) {
547
548                 INode tempNode = ((ResultNode) startNode).getDelegate();
549
550                 // we temporarily acquire a lock here so we can get the result
551
// node delegate
552
LockManager.acquireLock((Node) tempNode, LockManager.READ_LOCK);
553
554                 // get the result node that is next node
555
try {
556                     startNode = (IResultNode) startNode.getLinkNode().getNode();
557
558                 } finally {
559
560                     // do not lock couple here - and release the lock on the
561
// node
562
LockManager.releaseLock((Node) tempNode,
563                             LockManager.READ_LOCK);
564                 }
565
566             }
567         }
568
569         // update the current average result size
570
avRangeResults = (avRangeResults + map.size()) / 2;
571         return map;
572
573     }
574     
575     
576     
577     /**
578      * Gets all the uniqueIds that are contained in the tree between two values irrespective of the dimension. If the startObj is NULL
579      * it is assumed that the lower range starts from the first value in the dimension. Similarly, if the endObj is NULL
580      * it is assumed the upper bound is the maximum value in the dimension. <p>
581      
582      * @param tree - the Tree to search
583      * @param startObj - the starting value for the range search
584      * @param endObj - the end value for the range search
585      * @param startdimension - the dimension of the startObj.
586      * @param enddimension - the dimension of the end Obj.
587      * @param inclusive - sets whether the range search should be inclusive of the start and end objects.
588      * @return - A Map of the results.
589      * @throws JoftiException
590      */

591     public static Map JavaDoc getSubTreeKeyValues(BTree tree, Comparable JavaDoc startObj, Comparable JavaDoc endObj,
592             int dimension, int endDimension, boolean inclusive) throws JoftiException {
593         Map JavaDoc map = new LinkedHashMap JavaDoc();
594
595         if (startObj == null) {
596             startObj = ValueObject.MIN_COMAPARBLE_VALUE;
597         }
598         if (endObj == null) {
599             endObj = ValueObject.MAX_COMAPARBLE_VALUE;
600         }
601
602         ValueObject startRange = new ValueObject(dimension, startObj);
603         ValueObject finishRange = new ValueObject(endDimension, endObj);
604
605         IResultNode startNode = (IResultNode) tree.search(startRange);
606  
607     
608             boolean end = false;
609
610             while (!end) {
611                 Object JavaDoc[] entries = startNode.getEntries();
612                 // change to int method of access
613
for (int i = 0; i < entries.length; i++) {
614                     LeafNodeEntry entry = (LeafNodeEntry) entries[i];
615                     if (entry != BTree.MAX_LEAF_ENTRY) {
616
617                         if (inclusive && entry.value.compareTo(startRange) >= 0
618                                 && entry.value.compareTo(finishRange) <= 0) {
619
620                             Object JavaDoc[] tempSet = entry.getUniqueIdSet().toArray();
621                             // has to be iterator
622
for (int j=0;j<tempSet.length;j++) {
623                                 if (entry.getValue() instanceof ValueObject){
624                                     Map JavaDoc tmpMap = getMapForDimension(map, new Integer JavaDoc(((ValueObject)entry.getValue()).dimension));
625                                     tmpMap.put(tempSet[j], entry.value);
626                                 }
627                             }
628
629                         } else if ((!inclusive)
630                                 && entry.value.compareTo(startRange) > 0
631                                 && entry.value.compareTo(finishRange) < 0) {
632
633                             Object JavaDoc[] tempSet = entry.getUniqueIdSet().toArray();
634                             // has to be iterator
635
for (int j=0;j<tempSet.length;j++) {
636                                 if (entry.getValue() instanceof ValueObject){
637                                     Map JavaDoc tmpMap = getMapForDimension(map, new Integer JavaDoc(((ValueObject)entry.getValue()).dimension));
638                                     
639                                     tmpMap.put(tempSet[j], entry.value);
640                                 }
641                             }
642
643                         } else if (entry.value.compareTo(finishRange) > 0) {
644                             //we are at the end
645

646                             end = true;
647                             break;
648
649                         }
650                     } else {
651                         end = true;
652                         break;
653                     }
654
655                 }
656                 if (!end) {
657
658                     INode tempNode = ((ResultNode)startNode).getDelegate();
659                     LockManager.acquireLock((Node) tempNode, LockManager.READ_LOCK);
660                     
661                     try{
662                     startNode = (IResultNode)startNode.getLinkNode().getNode();
663                     
664                     }finally{
665
666                     //do not lock couple here
667
LockManager.releaseLock((Node) tempNode,
668                             LockManager.READ_LOCK);
669                     }
670
671                 }
672             }
673        
674         return map;
675
676     }
677     
678     private static Map JavaDoc getMapForDimension(Map JavaDoc resultMap, Integer JavaDoc dimension){
679         
680         Map JavaDoc tempMap = (Map JavaDoc)resultMap.get(dimension);
681         if (tempMap == null){
682             tempMap = new LinkedHashMap JavaDoc();
683             resultMap.put(dimension, tempMap);
684         }
685         return tempMap;
686         
687     }
688     
689     
690    
691     /**
692      * Gets all the uniqueIds that do not equal the object for a dimension. <p>
693      
694      * @param tree - the Tree to search
695      * @param obj - the value we want to exclude
696      * @param dimension - the dimension of the object.
697      * @return - the starting node
698      * @throws JoftiException
699      */

700  public static Map JavaDoc notEqual(BTree tree, Comparable JavaDoc obj, int dimension, Object JavaDoc valueReturn)
701             throws JoftiException {
702         OpenHashMap map = new OpenHashMap(avRangeResults*2,0.00f,0.5f);
703
704         Comparable JavaDoc start = ValueObject.MIN_COMAPARBLE_VALUE;
705
706         Comparable JavaDoc endObj = ValueObject.MAX_COMAPARBLE_VALUE;
707
708         ValueObject startRange = new ValueObject(dimension, start);
709         ValueObject finishRange = new ValueObject(dimension, endObj);
710
711         ValueObject actualValue = new ValueObject(dimension, obj);
712
713         IResultNode startNode = (IResultNode) tree.search(startRange);
714         INode realNode = ((ResultNode) startNode).getDelegate();
715
716         try {
717             LockManager.acquireLock((Node) realNode, LockManager.READ_LOCK);
718
719             boolean end = false;
720
721             while (!end) {
722                 Object JavaDoc[] entries = realNode.getEntries();
723
724                 for (int i = 0; i < entries.length; i++) {
725                     LeafNodeEntry entry = (LeafNodeEntry) entries[i];
726                     if (entry != BTree.MAX_LEAF_ENTRY) {
727                         Comparable JavaDoc tempObj = entry.value;
728                         if (tempObj.compareTo(startRange) >= 0
729                                 && tempObj.compareTo(finishRange) <= 0) {
730
731                             if (tempObj.compareTo(actualValue) != 0) {
732                                 
733
734                                 Object JavaDoc[] tempEntrySet = entry.getUniqueIdSet().toArray();
735                                 
736                                 map.ensureCapacity(map.size() + tempEntrySet.length);
737                                 Object JavaDoc retVal = valueReturn != null ?valueReturn : null ;
738                                 
739                                 
740                                 for (int j=0;j<tempEntrySet.length;j++) {
741                                     map.put(tempEntrySet[j], retVal);
742                                 }
743                             }
744
745                         } else if (tempObj.compareTo(finishRange) > 0) {
746                             //we are at the end
747

748                             end = true;
749                             break;
750
751                         }
752
753                     } else {
754                         end = true;
755                         break;
756                     }
757
758                 }
759                 if (!end) {
760
761                     INode nextNode = realNode.getLinkNode().getNode();
762
763                     //do not lock couple here
764
LockManager.releaseLock((Node) realNode,
765                             LockManager.READ_LOCK);
766                     LockManager.acquireLock((Node) nextNode,
767                             LockManager.READ_LOCK);
768
769                     realNode = nextNode;
770                 }
771             }
772         } finally {
773             LockManager.releaseLock((Node) realNode, LockManager.READ_LOCK);
774         }
775         return map;
776
777     }
778
779 }
Popular Tags