KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > mdr > persistence > btreeimpl > btreeindex > MultivaluedBtree


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.mdr.persistence.btreeimpl.btreeindex;
20
21 import org.netbeans.mdr.persistence.*;
22 import org.netbeans.mdr.util.MapEntryImpl;
23 import java.lang.ref.WeakReference JavaDoc;
24 import java.util.*;
25 import java.text.*;
26
27 /**
28  * Btree implementation of MultivaluedIndex interface.
29  *
30  * @author Dana Bergen
31  * @version 1.0
32  */

33 public class MultivaluedBtree extends Btree implements MultivaluedIndex {
34
35     // (weak) cache storing BtreeListByKey instances
36
private WeakHashMap listsByKey_cache = new WeakHashMap ();
37
38     public MultivaluedBtree(String JavaDoc name, Storage.EntryType keyType,
39                      Storage.EntryType dataType,
40                  boolean uniqueValues,
41                  BtreePageSource pageSource)
42                  throws StorageException {
43     super(name, keyType, dataType, pageSource);
44     this.uniqueValues = uniqueValues;
45     }
46
47     protected void init() throws StorageException {
48         uniqueKeys = false;
49     super.init();
50     }
51
52     /*
53      * No-argument constructor for reconstructing via read(). Only used with
54      * Btree's whose pageSource is a BtreeMDRSource.
55      */

56     public MultivaluedBtree() {
57     }
58
59     /** Returns a collection view of the values associated in the index with specified key.
60      * Returned collection is read only and may not be modified.
61      * If there are no values associated with the key empty collection is returned.
62      * @return
63      * @param key
64      * @throws StorageException
65      */

66     public Collection getItems(Object JavaDoc key) throws StorageException {
67         WeakReference JavaDoc ref = (WeakReference JavaDoc) listsByKey_cache.get (new BtreeListByKey.Key (key));
68         BtreeListByKey list = null;
69         if (ref != null)
70             list = (BtreeListByKey) ref.get();
71         if (list == null) {
72             list = new BtreeListByKey(this, key);
73             listsByKey_cache.put (list, new WeakReference JavaDoc (list));
74         }
75         return list;
76     }
77     
78    /** Like getItems, but if the values in the index are a key type,
79      * returns the objects associated with the keys.
80      * @return
81      * @param key
82      * @param repos where to look objetcs up
83      * @throws StorageException
84      */

85     public Collection getObjects(Object JavaDoc key, SinglevaluedIndex repos) throws StorageException {
86         WeakReference JavaDoc ref = (WeakReference JavaDoc) listsByKey_cache.get (new BtreeListByKey.Key (key));
87         BtreeListByKey list = null;
88         if (ref != null)
89             list = (BtreeListByKey) ref.get();
90         if (list == null) {
91             list = new BtreeListByKey(this, key);
92             listsByKey_cache.put (list, new WeakReference JavaDoc (list));
93         }
94         return new BtreeListByKeyRepos(list, repos);
95     }
96     
97     /** If true, the collection of values is constrained to hold
98      * no more than one of any value.
99      * @throws StorageException
100      * @return
101      */

102     public boolean isUnique() {
103         return uniqueValues;
104     }
105
106     /** Removes the first occurrence of the specified element in the list
107      * of values associated with the specified key.
108      * @return true if this index changed as a result of this call
109      * @param key
110      * @param value
111      * @throws StorageException
112      */

113     public boolean remove(Object JavaDoc key, Object JavaDoc value) throws StorageException {
114         beginWrite();
115     try {
116         byte[] keyBuffer, dataBuffer;
117         boolean result;
118
119         if ((keyBuffer = keyInfo.toBuffer(key)) == null) {
120         throw new StorageBadRequestException(
121             MessageFormat.format(
122           "Invalid key type for this index: {0} received, {1} expected",
123                 new Object JavaDoc[] {
124                 key.getClass().getName(),
125                 keyInfo.typeName()} ));
126         }
127
128         if ((dataBuffer = dataInfo.toBuffer(value)) == null) {
129         throw new StorageBadRequestException(
130             MessageFormat.format(
131              "Invalid data type for this index: {0} received, {1} expected",
132                 new Object JavaDoc[] {
133                 value.getClass().getName(),
134                 dataInfo.typeName()} ));
135         }
136
137         BtreePage root = pageSource.getPage(rootPageId, this);
138         result = root.remove(keyBuffer, dataBuffer);
139             if (result)
140                 updateKeyModCount (key);
141         pageSource.unpinPage(root);
142         return result;
143     } finally {
144         endWrite();
145     }
146     }
147     
148     public void add(Object JavaDoc key, Object JavaDoc data) throws StorageException {
149         super.add (key, data);
150         updateKeyModCount (key);
151     }
152     
153     public boolean remove(Object JavaDoc key) throws StorageException {
154         boolean result = super.remove (key);
155         if (result)
156             updateKeyModCount (key);
157         return result;
158     }
159     
160     /**
161      * Returns list of {@link BtreeEntryImpl} key-value pairs, where key contains
162      * the queried prefix.
163      */

164     public synchronized Collection queryByKeyPrefix (Object JavaDoc prefix, SinglevaluedIndex primaryIndex) throws StorageException {
165         if (keyType != Storage.EntryType.STRING) {
166             throw new UnsupportedOperationException JavaDoc ("Key type must be EntryType.STRING");
167         }
168         
169         List result = new LinkedList ();
170         byte [] prefixBytes = keyInfo.toBuffer (prefix);
171         SearchResult location = getLocation (prefixBytes);
172         if (location.entryNum == location.page.numEntries())
173             BtreePage.getNext (null, location);
174         
175         while ((location.entryNum < location.page.numEntries()) &&
176             SinglevaluedBtree.isPrefix (prefixBytes, location.page.getKey (location.entryNum))) {
177             byte [] key = location.page.getKey (location.entryNum);
178             Object JavaDoc keyObject = keyInfo.objectFromBuffer (key, primaryIndex);
179             Collection data = getObjects (keyObject, primaryIndex);
180             Object JavaDoc entry = new MapEntryImpl (keyObject, data);
181             result.add (entry);
182             int size = data.size ();
183             location.page.findNth (location, key, size, false);
184         } // while
185
return result;
186     }
187     
188     private static boolean isPrefix (byte [] prefix, byte [] key) {
189         if (prefix.length > key.length)
190             return false;
191         for (int x = 0; x < prefix.length; x++) {
192             if (prefix [x] != key [x])
193                 return false;
194         }
195         return true;
196     }
197     
198     /**
199      * Checks if an instance of BtreeListByKey related to key is in cache, if so, increases
200      * list's modification counter.
201      */

202     protected void updateKeyModCount (Object JavaDoc key) {
203         WeakReference JavaDoc ref = (WeakReference JavaDoc) listsByKey_cache.get (new BtreeListByKey.Key (key));
204         if (ref == null)
205             return;
206         BtreeListByKey list = null;
207         list = (BtreeListByKey) ref.get ();
208         if (list != null)
209             list.increaseModCount ();
210     }
211         
212 }
213
Popular Tags