View Javadoc

1   package cz.cuni.amis.utils.concurrency;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   import java.util.concurrent.atomic.AtomicIntegerArray;
6   
7   public class AtomicIntegerList {
8   
9   	private List<AtomicIntegerArray> arrays = new ArrayList<AtomicIntegerArray>();
10  	
11  	private int capacityStep;
12  	
13  	private int size = 0;
14  
15  	public AtomicIntegerList(int initialCapacity, int capacityStep) {
16  		this.capacityStep = capacityStep;
17  		if (initialCapacity > 0) {
18  			getArray(initialCapacity-1);
19  		}
20  	}
21  
22  	private int arrayIndex(int index) {
23  		return index / capacityStep;
24  	}
25  	
26  	private int trueIndex(int index) {
27  		return index - capacityStep * (index / capacityStep);
28  	}
29  	
30  	private AtomicIntegerArray getArray(int index) {
31  		int arrayIndex = arrayIndex(index);
32  		if (size <= index) {
33  			synchronized(arrays) {
34  				if (size <= index) {
35  					size = index + 1;
36  				}
37  			}
38  		}
39  		if (arrayIndex < arrays.size()) return arrays.get(arrayIndex);
40  		synchronized(arrays) {
41  			while (arrays.size() <= arrayIndex) arrays.add(new AtomicIntegerArray(capacityStep));			
42  		}
43  		return arrays.get(arrayIndex);
44  	}
45  	
46  	/**
47  	 * Atomically add the given value to element at index i.
48  	 * 
49  	 * @param i
50  	 * @param delta
51  	 * @return
52  	 */
53  	public int addAndGet(int i, int delta) {
54  		return getArray(i).addAndGet(trueIndex(i), delta);
55  	}
56  
57  	/**
58  	 * Atomically set the value to the given updated value if the current value
59  	 * == the expected value.
60  	 * 
61  	 * @param i
62  	 * @param expect
63  	 * @param update
64  	 * @return
65  	 */
66  	public boolean compareAndSet(int i, int expect, int update) {
67  		return getArray(i).compareAndSet(trueIndex(i), expect, update);
68  	}
69  
70  	/**
71  	 * Atomically decrement by one the element at index i.
72  	 * 
73  	 * @param i
74  	 * @return
75  	 */
76  	public int decrementAndGet(int i) {
77  		return getArray(i).decrementAndGet(trueIndex(i));
78  	}
79  
80  	/**
81  	 * Get the current value at position i.
82  	 * 
83  	 * @param i
84  	 * @return
85  	 */
86  	public int get(int i) {
87  		return getArray(i).get(trueIndex(i));
88  	}
89  
90  	/**
91  	 * Atomically add the given value to element at index i.
92  	 * 
93  	 * @param i
94  	 * @param delta
95  	 * @return
96  	 */
97  	public int getAndAdd(int i, int delta) {
98  		return getArray(i).getAndAdd(trueIndex(i), delta);
99  	}
100 
101 	/**
102 	 * Atomically decrement by one the element at index i.
103 	 * 
104 	 * @param i
105 	 * @return
106 	 */
107 	public int getAndDecrement(int i) {
108 		return getArray(i).getAndDecrement(trueIndex(i));
109 	}
110 
111 	/**
112 	 * Atomically increment by one the element at index i.
113 	 * 
114 	 * @param i
115 	 * @return
116 	 */
117 	public int getAndIncrement(int i) {
118 		return getArray(i).getAndIncrement(trueIndex(i));
119 	}
120 
121 	/**
122 	 * Set the element at position i to the given value and return the old
123 	 * value.
124 	 * 
125 	 * @param i
126 	 * @param newValue
127 	 * @return
128 	 */
129 	public int getAndSet(int i, int newValue) {
130 		return getArray(i).getAndSet(trueIndex(i), newValue);
131 	}
132 
133 	/**
134 	 * Atomically increment by one the element at index i.
135 	 * 
136 	 * @param i
137 	 * @return
138 	 */
139 	public int incrementAndGet(int i) {
140 		return getArray(i).incrementAndGet(trueIndex(i));
141 	}
142 
143 	/**
144 	 * Returns the length of the array (== max-touched-index+1).
145 	 * 
146 	 * @return
147 	 */
148 	public int size() {
149 		return size;
150 	}
151 	
152 	/**
153 	 * Returns current capacity of the array.
154 	 * @return
155 	 */
156 	public int capacity() {
157 		return arrays.size() * capacityStep;
158 	}
159 
160 	/**
161 	 * Set the element at position i to the given value.
162 	 * 
163 	 * @param i
164 	 * @param newValue
165 	 */
166 	public void set(int i, int newValue) {
167 		getArray(i).set(trueIndex(i), newValue);
168 	}
169 
170 	/**
171 	 * Atomically set the value to the given updated value if the current value
172 	 * == the expected value.
173 	 * 
174 	 * @param i
175 	 * @param expect
176 	 * @param update
177 	 * @return
178 	 */
179 	public boolean weakCompareAndSet(int i, int expect, int update) {
180 		return getArray(i).weakCompareAndSet(trueIndex(i), expect, update);
181 	}
182 }