KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > db4o > P2HashMap


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;
22
23 import java.util.*;
24
25 import com.db4o.foundation.*;
26 import com.db4o.inside.*;
27 import com.db4o.types.*;
28
29 /**
30  * @exclude
31  * @persistent
32  */

33 public class P2HashMap extends P1Collection implements Db4oMap, TransactionListener {
34
35     private static final float FILL = 0.6F;
36
37     private transient int i_changes;
38     private transient boolean i_dontStoreOnDeactivate;
39
40     public P1HashElement[] i_entries;
41     public int i_mask;
42     public int i_maximumSize;
43     public int i_size;
44     
45     public int i_type; // 0 == default hash, 1 == ID hash
46

47
48     transient P1HashElement[] i_table;
49
50     public int i_tableSize;
51
52     P2HashMap() {
53     }
54
55     P2HashMap(int a_size) {
56         a_size = (int) (a_size / FILL);
57         i_tableSize = 1;
58         while (i_tableSize < a_size) {
59             i_tableSize = i_tableSize << 1;
60         }
61         i_mask = i_tableSize - 1;
62         i_maximumSize = (int) (i_tableSize * FILL);
63         i_table = new P1HashElement[i_tableSize];
64     }
65
66     public int activationDepth() {
67         return 2;
68     }
69
70     public int adjustReadDepth(int a_depth) {
71         return 2;
72     }
73     
74     public void checkActive() {
75         super.checkActive();
76         if (i_table == null) {
77             i_table = new P1HashElement[i_tableSize];
78             if (i_entries != null) {
79                 for (int i = 0; i < i_entries.length; i++) {
80                     if(i_entries[i] != null){
81                         i_entries[i].checkActive();
82                         i_table[i_entries[i].i_position] = i_entries[i];
83                     }
84                 }
85             }
86             i_changes = 0;
87             
88             // FIXME: reducing the table in size can be a problem during defragment in
89
// C/S mode on P2HashMaps that were partially stored uncommitted.
90

91 // if ((i_size + 1) * 10 < i_tableSize) {
92
// i_tableSize = i_size + 5;
93
// increaseSize();
94
// modified();
95
// }
96

97         }
98     }
99
100     public void clear() {
101         synchronized (streamLock()) {
102             checkActive();
103             if (i_size != 0) {
104                 for (int i = 0; i < i_table.length; i++) {
105                     deleteAllElements(i_table[i]);
106                     i_table[i] = null;
107                 }
108                 if(i_entries != null){
109                     for (int i = 0; i < i_entries.length; i++) {
110                         i_entries[i] = null;
111                     }
112                 }
113                 i_size = 0;
114                 modified();
115             }
116         }
117     }
118
119     public boolean containsKey(Object JavaDoc key) {
120         return get(key) != null;
121     }
122
123     public boolean containsValue(Object JavaDoc value) {
124         throw new UnsupportedOperationException JavaDoc();
125     }
126
127     public Object JavaDoc createDefault(Transaction a_trans) {
128         checkActive();
129         P2HashMap m4 = new P2HashMap(i_size);
130         m4.i_type = i_type;
131         m4.setTrans(a_trans);
132         P2HashMapIterator i = new P2HashMapIterator(this);
133         while (i.hasNext()) {
134             Object JavaDoc key = i.next();
135             if(key != null){
136                 m4.put4(key, get4(key));
137             }
138         }
139         return m4;
140     }
141
142     private void deleteAllElements(P1HashElement a_entry) {
143         if (a_entry != null) {
144             a_entry.checkActive();
145             deleteAllElements((P1HashElement)a_entry.i_next);
146             a_entry.delete(i_deleteRemoved);
147         }
148     }
149
150     public Set entrySet() {
151         final HashSet out = new HashSet(size());
152         
153         Iterator itor = keySet().iterator();
154         
155         while (itor.hasNext()){
156             final Object JavaDoc key = itor.next();
157             final Object JavaDoc value = get(key);
158             final MapEntry entry = new MapEntry(key);
159             entry.setValue(value);
160             out.add(entry);
161         }
162         
163         return out;
164     }
165     
166     private boolean equals(P1HashElement phe, int hashCode, Object JavaDoc key) {
167         return phe.i_hashCode == hashCode && phe.activatedKey(elementActivationDepth()).equals(key);
168     }
169
170     public Object JavaDoc get(Object JavaDoc key) {
171         synchronized (streamLock()) {
172             checkActive();
173             return get4(key);
174         }
175     }
176
177     Object JavaDoc get4(Object JavaDoc key) {
178         if(key == null){
179             return null;
180         }
181         int hash = hashOf(key);
182         P1HashElement phe = i_table[hash & i_mask];
183         while (phe != null) {
184             phe.checkActive();
185             if (equals(phe, hash, key)) {
186                 return phe.activatedObject(elementActivationDepth());
187             }
188             phe = (P1HashElement)phe.i_next;
189         }
190         return null;
191     }
192     
193     private int hashOf(Object JavaDoc key) {
194         if(i_type == 1) {
195             int id = (int)getIDOf(key);
196             if(id == 0) {
197                 store(key);
198             }
199             id = (int)getIDOf(key);
200             if(id == 0) {
201                 Exceptions4.throwRuntimeException(62);
202             }
203             return id;
204         }
205         return key.hashCode();
206     }
207     
208
209     private void increaseSize() {
210         i_tableSize = i_tableSize << 1;
211         i_maximumSize = (int) (i_tableSize * FILL);
212         i_mask = i_tableSize - 1;
213         P1HashElement[] temp = i_table;
214         i_table = new P1HashElement[i_tableSize];
215         for (int i = 0; i < temp.length; i++) {
216             reposition(temp[i]);
217         }
218     }
219
220     public boolean isEmpty() {
221         return size() == 0;
222     }
223
224     public Set keySet() {
225         return new P2HashMapKeySet(this);
226     }
227
228     void modified() {
229         if (getTrans() != null) {
230             if (i_changes == 0) {
231                 getTrans().addTransactionListener(this);
232             }
233             i_changes++;
234         }
235     }
236
237     public void postRollback() {
238         i_dontStoreOnDeactivate = true;
239         deactivate();
240         i_dontStoreOnDeactivate = false;
241     }
242
243     public void preCommit() {
244         if (i_changes > 0) {
245             Collection4 col = new Collection4();
246             for (int i = 0; i < i_table.length; i++) {
247                 if (i_table[i] != null) {
248                     i_table[i].checkActive();
249                     if (i_table[i].i_position != i) {
250                         i_table[i].i_position = i;
251                         i_table[i].update();
252                     }
253                     col.add(i_table[i]);
254                 }
255             }
256             if (i_entries == null || i_entries.length != col.size()) {
257                 i_entries = new P1HashElement[col.size()];
258             }
259             int i = 0;
260             Iterator4 it = col.iterator();
261             while (it.moveNext()) {
262                 i_entries[i++] = (P1HashElement)it.current();
263             }
264             store(2);
265         }
266         i_changes = 0;
267     }
268
269     public void preDeactivate() {
270         if (!i_dontStoreOnDeactivate) {
271             preCommit();
272         }
273         i_table = null;
274     }
275
276     public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value) {
277         synchronized (streamLock()) {
278             checkActive();
279             return put4(key, value);
280         }
281     }
282
283     private Object JavaDoc put4(Object JavaDoc key, Object JavaDoc value) {
284         int hash = hashOf(key);
285         P1HashElement entry = new P1HashElement(getTrans(), null, key, hash, value);
286         i_size++;
287         if (i_size > i_maximumSize) {
288             increaseSize();
289         }
290         modified();
291         int index = entry.i_hashCode & i_mask;
292         P1HashElement phe = i_table[index];
293         P1HashElement last = null;
294         while (phe != null) {
295             phe.checkActive();
296             if (equals(phe, entry.i_hashCode, key)) {
297                 i_size--;
298                 Object JavaDoc ret = phe.activatedObject(elementActivationDepth());
299                 entry.i_next = phe.i_next;
300                 store(entry);
301                 if (last != null) {
302                     last.i_next = entry;
303                     last.update();
304                 } else {
305                     i_table[index] = entry;
306                 }
307                 phe.delete(i_deleteRemoved);
308                 return ret;
309             }
310             last = phe;
311             phe = (P1HashElement)phe.i_next;
312         }
313         entry.i_next = i_table[index];
314         i_table[index] = entry;
315         store(entry);
316         return null;
317     }
318
319     public void putAll(Map t) {
320         synchronized (streamLock()) {
321             checkActive();
322             Iterator i = t.keySet().iterator();
323             while (i.hasNext()) {
324                 Object JavaDoc key = i.next();
325                 if (key != null) {
326                     put4(key, t.get(key));
327                 }
328             }
329         }
330     }
331
332     public Object JavaDoc remove(Object JavaDoc key) {
333         synchronized (streamLock()) {
334             checkActive();
335             return remove4(key);
336         }
337     }
338
339     Object JavaDoc remove4(Object JavaDoc key) {
340         int hash = hashOf(key);
341         P1HashElement phe = i_table[hash & i_mask];
342         P1HashElement last = null;
343         while (phe != null) {
344             phe.checkActive();
345             if (equals(phe, hash, key)) {
346                 if (last != null) {
347                     last.i_next = phe.i_next;
348                     last.update();
349                 } else {
350                     i_table[hash & i_mask] = (P1HashElement)phe.i_next;
351                 }
352                 modified();
353                 i_size--;
354                 Object JavaDoc obj = phe.activatedObject(elementActivationDepth());
355                 phe.delete(i_deleteRemoved);
356                 return obj;
357             }
358             last = phe;
359             phe = (P1HashElement)phe.i_next;
360         }
361         return null;
362     }
363     
364     public void replicateFrom(Object JavaDoc obj) {
365         checkActive();
366         if(i_entries != null){
367             for (int i = 0; i < i_entries.length; i++) {
368                 if(i_entries[i] != null){
369                     i_entries[i].delete(false);
370                 }
371                 i_entries[i] = null;
372             }
373         }
374         if(i_table != null){
375             for (int i = 0; i < i_table.length; i++) {
376                 i_table[i] = null;
377             }
378         }
379         i_size = 0;
380         
381         P2HashMap m4 = (P2HashMap)obj;
382         m4.checkActive();
383         P2HashMapIterator i = new P2HashMapIterator(m4);
384         while (i.hasNext()) {
385             Object JavaDoc key = i.next();
386             put4(key, m4.get4(key));
387         }
388         
389         modified();
390     }
391
392
393     private void reposition(P1HashElement a_entry) {
394         if (a_entry != null) {
395             reposition((P1HashElement)a_entry.i_next);
396             a_entry.checkActive();
397             Object JavaDoc oldNext = a_entry.i_next;
398             a_entry.i_next = i_table[a_entry.i_hashCode & i_mask];
399             if (a_entry.i_next != oldNext) {
400                 a_entry.update();
401             }
402             i_table[a_entry.i_hashCode & i_mask] = a_entry;
403         }
404     }
405     
406     public int size() {
407         synchronized (streamLock()) {
408             checkActive();
409             return i_size;
410         }
411     }
412
413     public Object JavaDoc storedTo(Transaction a_trans) {
414         if (getTrans() == null) {
415             setTrans(a_trans);
416             modified();
417         } else {
418             if (a_trans != getTrans()) {
419                 return replicate(getTrans(), a_trans);
420                 
421 // Test fix for replication duplication. Not a good idea.
422

423 // Object replicated = asReplicated(getTrans(), a_trans);
424
// if (replicated != null){
425
// return replicated;
426
// }
427
}
428         }
429         return this;
430     }
431
432     public Collection values() {
433         throw new UnsupportedOperationException JavaDoc();
434     }
435
436     private class MapEntry implements Map.Entry {
437         private Object JavaDoc key;
438
439         private Object JavaDoc value;
440
441         public MapEntry(Object JavaDoc key) {
442             this.key = key;
443         }
444
445         public Object JavaDoc getKey() {
446             return key;
447         }
448
449         public Object JavaDoc getValue() {
450             return value;
451         }
452
453         public Object JavaDoc setValue(Object JavaDoc value) {
454             Object JavaDoc result = this.value;
455             this.value = value;
456             return result;
457         }
458
459         public boolean equals(Object JavaDoc obj) {
460             if (!(obj instanceof MapEntry))
461                 return false;
462
463             MapEntry other = (MapEntry) obj;
464
465             return (key.equals(other.key)) && (value.equals(other.value));
466         }
467
468         public int hashCode() {
469             return key.hashCode() ^ value.hashCode();
470         }
471     }
472 }
473
Popular Tags