1 package cz.cuni.amis.pogamut.multi.utils.timekey;
2
3 import java.lang.ref.WeakReference;
4 import java.util.ArrayList;
5 import java.util.Comparator;
6 import java.util.HashMap;
7 import java.util.List;
8 import java.util.Map;
9
10 import cz.cuni.amis.utils.flag.FlagInteger;
11 import cz.cuni.amis.utils.flag.ImmutableFlag;
12
13
14
15
16
17
18
19
20 public class TimeKey implements Comparable {
21
22 public static class TimeKeyComparator implements Comparator<TimeKey> {
23
24 @Override
25 public int compare(TimeKey o1, TimeKey o2) {
26 if (o1 == null && o2 == null) return 0;
27 if (o1 == null) return -1;
28 if (o2 == null) return 1;
29 if (o1._time < o2._time) return -1;
30 if (o1._time > o2._time) return 1;
31 return 0;
32 }
33
34 };
35
36 private static FlagInteger instances = new FlagInteger(0);
37
38 public static ImmutableFlag<Integer> getInstances() {
39 return instances.getImmutable();
40 }
41
42 @Override
43 protected void finalize() throws Throwable {
44 super.finalize();
45 synchronized(keys) {
46 WeakReference<TimeKey> ref = keys.get(_time);
47 if (ref == null || ref.get() == null || ref.get()._time == _time) {
48 keys.remove(_time);
49 }
50 }
51 instances.decrement(1);
52 }
53
54 private long _time;
55
56 private TimeKey(long time) {
57 instances.increment(1);
58 _time = time;
59 }
60
61
62 protected static Map<Long, WeakReference<TimeKey>> keys = new HashMap<Long, WeakReference<TimeKey>>(1024);
63
64
65
66
67
68
69
70 public static TimeKey get(long time) {
71 WeakReference<TimeKey> ref = keys.get(time);
72 if (ref != null) {
73 TimeKey key = ref.get();
74 if (key != null) return key;
75 }
76 synchronized(keys) {
77 ref = keys.get(time);
78 if (ref == null) {
79 TimeKey key = new TimeKey(time);
80 keys.put(time, new WeakReference<TimeKey>(key));
81 return key;
82 }
83 TimeKey key = ref.get();
84 if (key == null) {
85 key = new TimeKey(time);
86 keys.put(time, new WeakReference<TimeKey>(key));
87 return key;
88 }
89 return key;
90 }
91 }
92
93
94
95
96 public static void clear() {
97 synchronized(keys) {
98 keys.clear();
99 }
100 }
101
102 @Override
103 public boolean equals(Object other) {
104 if (other == this) return true;
105 if (other == null) return false;
106
107 if (other instanceof TimeKey) {
108 return ((TimeKey)other)._time == this._time;
109 }
110 return false;
111 }
112
113 @Override
114 public int hashCode() {
115 return (int)(_time % Integer.MAX_VALUE);
116 }
117
118
119
120
121
122
123 public static boolean exists(long time) {
124 synchronized(keys) {
125 WeakReference<TimeKey> ref = keys.get(time);
126 if (ref == null) return false;
127 if (ref.get() == null) {
128 keys.remove(time);
129 return false;
130 }
131 return true;
132 }
133 }
134
135
136
137
138
139 public long getTime() {
140 return _time;
141 }
142
143 @Override
144 public int compareTo(Object key) {
145 if (this == key) return 0;
146 if (key == null) return 1;
147 if (!(key instanceof TimeKey)) {
148 throw new ClassCastException("TimeKey can only be compared with TimeKey objects");
149 }
150 if ( this._time < ((TimeKey)key)._time ) {
151 return -1;
152 } else {
153 return 1;
154 }
155 }
156
157 @Override
158 public String toString() {
159 return "TimeKey[" + _time + "]";
160 }
161
162 public static List<WeakReference<TimeKey>> getAllKeys() {
163 synchronized(keys) {
164 return new ArrayList<WeakReference<TimeKey>>(keys.values());
165 }
166 }
167 }