KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > util > concurrent > CopyOnWriteArrayMap


1 /*
2  * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

5 package com.tc.util.concurrent;
6
7 import com.tc.exception.ImplementMe;
8
9 import java.util.Collection JavaDoc;
10 import java.util.Hashtable JavaDoc;
11 import java.util.Map JavaDoc;
12 import java.util.Set JavaDoc;
13
14 /**
15  * This class provides a thread safe map interface (by extending Hashtable) and adds a way to easily and synchronously
16  * iterator over the list of values as an array. This map is very useful when you want a snap shot of the values to
17  * iterator over and dont want to hold up access to the map the whole time while you are iteratoring over the list to
18  * avoid concurrent modification exception.
19  * <p>
20  * For example : <code>
21  * Hashtable t = ....
22  * for(Iterator i = t.values().iterator(); i.hashNext(); ) {
23  * // do something
24  * }
25  * </code>
26  * In the above code, if multiple threads are accessing t, to avoid ConcurrentModificationException, you need to
27  * synchronize the entire for loop.
28  * <p>
29  * Using CopyOnWriteArrayMap and using the special valuesArray() method will give you a snapshot of the values will
30  * avoid synchronizing the map for the entire duration of the for loop.
31  * <p>
32  * This is achieved by maintaining an internal copy of the values in an array and copying that on modification. So an in
33  * any CopyOnWrite class this is only effective on small datasets with lots of reads and few writes.
34  */

35 public class CopyOnWriteArrayMap extends Hashtable JavaDoc {
36
37   private volatile Object JavaDoc _values[] = new Object JavaDoc[0];
38
39   public CopyOnWriteArrayMap() {
40     super();
41   }
42
43   public CopyOnWriteArrayMap(int initialCapacity, float loadFactor) {
44     super(initialCapacity, loadFactor);
45   }
46
47   public CopyOnWriteArrayMap(int initialCapacity) {
48     super(initialCapacity);
49   }
50
51   public CopyOnWriteArrayMap(Map JavaDoc t) {
52     super(t);
53   }
54
55   public synchronized void clear() {
56     super.clear();
57     _values = new Object JavaDoc[0];
58   }
59
60   public Set JavaDoc entrySet() {
61     throw new ImplementMe("This is not implemented yet due to lack to time."
62         + " Support for remove needs to be provided by wrapping super iterators with my own iterators");
63   }
64
65   public Set JavaDoc keySet() {
66     throw new ImplementMe("This is not implemented yet due to lack to time."
67         + " Support for remove needs to be provided by wrapping super iterators with my own iterators");
68   }
69
70   public synchronized Object JavaDoc put(Object JavaDoc key, Object JavaDoc value) {
71     Object JavaDoc old = super.put(key, value);
72     if (old == null) {
73       Object JavaDoc[] old_values = _values;
74       _values = new Object JavaDoc[old_values.length + 1];
75       System.arraycopy(old_values, 0, _values, 0, old_values.length);
76       _values[old_values.length] = value;
77     } else {
78       Object JavaDoc[] old_values = _values;
79       int length = old_values.length;
80       // XXX:: doing an explicit copy so that the previous snapshots are not messed upon.
81
_values = new Object JavaDoc[length];
82       for (int i = 0; i < length; i++) {
83         _values[i] = (old == old_values[i] ? value : old_values[i]);
84       }
85     }
86     return old;
87   }
88
89   public synchronized void putAll(Map JavaDoc t) {
90     // calls into put anyways
91
super.putAll(t);
92   }
93
94   public synchronized Object JavaDoc remove(Object JavaDoc key) {
95     Object JavaDoc old = super.remove(key);
96     if (old != null) {
97       Object JavaDoc[] old_values = _values;
98       int length = old_values.length;
99       _values = new Object JavaDoc[length - 1];
100       int i = 0;
101       for (int j = 0; j < length; j++) {
102         if (old != old_values[j]) {
103           _values[i++] = old_values[j];
104         }
105       }
106     }
107     return old;
108   }
109
110   public Collection JavaDoc values() {
111     throw new ImplementMe("This is not implemented yet due to lack to time."
112         + " Support for remove needs to be provided by wrapping super iterators with my own iterators");
113   }
114   
115   public synchronized Object JavaDoc[] valuesArray() {
116     return _values;
117   }
118 }
119
Popular Tags