view src/clojure/lang/Ref.java @ 10:ef7dbbd6452c

added clojure source goodness
author Robert McIntyre <rlm@mit.edu>
date Sat, 21 Aug 2010 06:25:44 -0400
parents
children
line wrap: on
line source
1 /**
2 * Copyright (c) Rich Hickey. All rights reserved.
3 * The use and distribution terms for this software are covered by the
4 * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
5 * which can be found in the file epl-v10.html at the root of this distribution.
6 * By using this software in any fashion, you are agreeing to be bound by
7 * the terms of this license.
8 * You must not remove this notice, or any other, from this software.
9 **/
11 /* rich Jul 25, 2007 */
13 package clojure.lang;
15 import java.util.concurrent.atomic.AtomicInteger;
16 import java.util.concurrent.atomic.AtomicLong;
17 import java.util.concurrent.locks.ReentrantReadWriteLock;
19 public class Ref extends ARef implements IFn, Comparable<Ref>, IRef{
20 public int compareTo(Ref ref) {
21 if(this.id == ref.id)
22 return 0;
23 else if(this.id < ref.id)
24 return -1;
25 else
26 return 1;
27 }
29 public int getMinHistory(){
30 return minHistory;
31 }
33 public Ref setMinHistory(int minHistory){
34 this.minHistory = minHistory;
35 return this;
36 }
38 public int getMaxHistory(){
39 return maxHistory;
40 }
42 public Ref setMaxHistory(int maxHistory){
43 this.maxHistory = maxHistory;
44 return this;
45 }
47 public static class TVal{
48 Object val;
49 long point;
50 long msecs;
51 TVal prior;
52 TVal next;
54 TVal(Object val, long point, long msecs, TVal prior){
55 this.val = val;
56 this.point = point;
57 this.msecs = msecs;
58 this.prior = prior;
59 this.next = prior.next;
60 this.prior.next = this;
61 this.next.prior = this;
62 }
64 TVal(Object val, long point, long msecs){
65 this.val = val;
66 this.point = point;
67 this.msecs = msecs;
68 this.next = this;
69 this.prior = this;
70 }
72 }
74 TVal tvals;
75 final AtomicInteger faults;
76 final ReentrantReadWriteLock lock;
77 LockingTransaction.Info tinfo;
78 //IFn validator;
79 final long id;
81 volatile int minHistory = 0;
82 volatile int maxHistory = 10;
84 static final AtomicLong ids = new AtomicLong();
86 public Ref(Object initVal) throws Exception{
87 this(initVal, null);
88 }
90 public Ref(Object initVal,IPersistentMap meta) throws Exception{
91 super(meta);
92 this.id = ids.getAndIncrement();
93 this.faults = new AtomicInteger();
94 this.lock = new ReentrantReadWriteLock();
95 tvals = new TVal(initVal, 0, System.currentTimeMillis());
96 }
98 //the latest val
100 // ok out of transaction
101 Object currentVal(){
102 try
103 {
104 lock.readLock().lock();
105 if(tvals != null)
106 return tvals.val;
107 throw new IllegalStateException(this.toString() + " is unbound.");
108 }
109 finally
110 {
111 lock.readLock().unlock();
112 }
113 }
115 //*
117 public Object deref(){
118 LockingTransaction t = LockingTransaction.getRunning();
119 if(t == null)
120 return currentVal();
121 return t.doGet(this);
122 }
124 //void validate(IFn vf, Object val){
125 // try{
126 // if(vf != null && !RT.booleanCast(vf.invoke(val)))
127 // throw new IllegalStateException("Invalid ref state");
128 // }
129 // catch(RuntimeException re)
130 // {
131 // throw re;
132 // }
133 // catch(Exception e)
134 // {
135 // throw new IllegalStateException("Invalid ref state", e);
136 // }
137 //}
138 //
139 //public void setValidator(IFn vf){
140 // try
141 // {
142 // lock.writeLock().lock();
143 // validate(vf,currentVal());
144 // validator = vf;
145 // }
146 // finally
147 // {
148 // lock.writeLock().unlock();
149 // }
150 //}
151 //
152 //public IFn getValidator(){
153 // try
154 // {
155 // lock.readLock().lock();
156 // return validator;
157 // }
158 // finally
159 // {
160 // lock.readLock().unlock();
161 // }
162 //}
164 public Object set(Object val){
165 return LockingTransaction.getEx().doSet(this, val);
166 }
168 public Object commute(IFn fn, ISeq args) throws Exception{
169 return LockingTransaction.getEx().doCommute(this, fn, args);
170 }
172 public Object alter(IFn fn, ISeq args) throws Exception{
173 LockingTransaction t = LockingTransaction.getEx();
174 return t.doSet(this, fn.applyTo(RT.cons(t.doGet(this), args)));
175 }
177 public void touch(){
178 LockingTransaction.getEx().doEnsure(this);
179 }
181 //*/
182 boolean isBound(){
183 try
184 {
185 lock.readLock().lock();
186 return tvals != null;
187 }
188 finally
189 {
190 lock.readLock().unlock();
191 }
192 }
195 public void trimHistory(){
196 try
197 {
198 lock.writeLock().lock();
199 if(tvals != null)
200 {
201 tvals.next = tvals;
202 tvals.prior = tvals;
203 }
204 }
205 finally
206 {
207 lock.writeLock().unlock();
208 }
209 }
211 public int getHistoryCount(){
212 try
213 {
214 lock.writeLock().lock();
215 return histCount();
216 }
217 finally
218 {
219 lock.writeLock().unlock();
220 }
221 }
223 int histCount(){
224 if(tvals == null)
225 return 0;
226 else
227 {
228 int count = 0;
229 for(TVal tv = tvals.next;tv != tvals;tv = tv.next)
230 count++;
231 return count;
232 }
233 }
235 final public IFn fn(){
236 return (IFn) deref();
237 }
239 public Object call() throws Exception{
240 return invoke();
241 }
243 public void run(){
244 try
245 {
246 invoke();
247 }
248 catch(Exception e)
249 {
250 throw new RuntimeException(e);
251 }
252 }
254 public Object invoke() throws Exception{
255 return fn().invoke();
256 }
258 public Object invoke(Object arg1) throws Exception{
259 return fn().invoke(arg1);
260 }
262 public Object invoke(Object arg1, Object arg2) throws Exception{
263 return fn().invoke(arg1, arg2);
264 }
266 public Object invoke(Object arg1, Object arg2, Object arg3) throws Exception{
267 return fn().invoke(arg1, arg2, arg3);
268 }
270 public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4) throws Exception{
271 return fn().invoke(arg1, arg2, arg3, arg4);
272 }
274 public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) throws Exception{
275 return fn().invoke(arg1, arg2, arg3, arg4, arg5);
276 }
278 public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) throws Exception{
279 return fn().invoke(arg1, arg2, arg3, arg4, arg5, arg6);
280 }
282 public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7)
283 throws Exception{
284 return fn().invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
285 }
287 public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
288 Object arg8) throws Exception{
289 return fn().invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
290 }
292 public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
293 Object arg8, Object arg9) throws Exception{
294 return fn().invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
295 }
297 public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
298 Object arg8, Object arg9, Object arg10) throws Exception{
299 return fn().invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
300 }
302 public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
303 Object arg8, Object arg9, Object arg10, Object arg11) throws Exception{
304 return fn().invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11);
305 }
307 public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
308 Object arg8, Object arg9, Object arg10, Object arg11, Object arg12) throws Exception{
309 return fn().invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
310 }
312 public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
313 Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13)
314 throws Exception{
315 return fn().invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13);
316 }
318 public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
319 Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14)
320 throws Exception{
321 return fn().invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14);
322 }
324 public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
325 Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,
326 Object arg15) throws Exception{
327 return fn().invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15);
328 }
330 public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
331 Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,
332 Object arg15, Object arg16) throws Exception{
333 return fn().invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15,
334 arg16);
335 }
337 public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
338 Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,
339 Object arg15, Object arg16, Object arg17) throws Exception{
340 return fn().invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15,
341 arg16, arg17);
342 }
344 public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
345 Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,
346 Object arg15, Object arg16, Object arg17, Object arg18) throws Exception{
347 return fn().invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15,
348 arg16, arg17, arg18);
349 }
351 public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
352 Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,
353 Object arg15, Object arg16, Object arg17, Object arg18, Object arg19) throws Exception{
354 return fn().invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15,
355 arg16, arg17, arg18, arg19);
356 }
358 public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
359 Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,
360 Object arg15, Object arg16, Object arg17, Object arg18, Object arg19, Object arg20)
361 throws Exception{
362 return fn().invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15,
363 arg16, arg17, arg18, arg19, arg20);
364 }
366 public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
367 Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,
368 Object arg15, Object arg16, Object arg17, Object arg18, Object arg19, Object arg20,
369 Object... args)
370 throws Exception{
371 return fn().invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15,
372 arg16, arg17, arg18, arg19, arg20, args);
373 }
375 public Object applyTo(ISeq arglist) throws Exception{
376 return AFn.applyToHelper(this, arglist);
377 }
379 }