Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/classes/sun/java2d/StateTrackable.java
41152 views
1
/*
2
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.java2d;
27
28
/**
29
* This interface is implemented by classes which contain complex state
30
* so that other objects can track whether or not their state has changed
31
* since earlier interactions with the object.
32
* <p>
33
* The suggested usage pattern for code that manages some trackable data
34
* is as follows:
35
* <pre>
36
* class Trackable implements StateTrackable {
37
* TrackedInfo data;
38
* State curState = STABLE;
39
* StateTracker curTracker = null;
40
* // Hypothetical method to return a static piece of our tracked data.
41
* // Assume that Datum is either a copy of some piece of the tracked
42
* // data or that it is itself immutable.
43
* public Datum getSomeDatum(int key) {
44
* // No need to modify the state for this type of "get" call.
45
* return data.getDatum(key);
46
* }
47
* // Hypothetical method to return a raw reference to our tracked data.
48
* public TrackedInfo getRawHandleToInfo() {
49
* // Since we are returning a raw reference to our tracked
50
* // data and since we can not track what the caller will
51
* // do with that reference, we can no longer track the
52
* // state of this data.
53
* synchronized (this) {
54
* // Note: modifying both curState and curTracker requires
55
* // synchronization against the getStateTracker method.
56
* curState = UNTRACKABLE;
57
* curTracker = null;
58
* }
59
* return data;
60
* }
61
* // Hypothetical method to set a single piece of data to some
62
* // new static value.
63
* public void setSomeDatum(int key, Datum datum) {
64
* data.setDatum(key, datum);
65
* // We do not need to change state for this, we simply
66
* // invalidate the outstanding StateTracker objects.
67
* // Note: setting curTracker to null requires no synchronization.
68
* curTracker = null;
69
* }
70
* // getStateTracker must be synchronized against any code that
71
* // changes the State.
72
* public synchronized StateTracker getStateTracker() {
73
* StateTracker st = curTracker;
74
* if (st == null) {
75
* switch (curState) {
76
* case IMMUTABLE: st = StateTracker.ALWAYS_CURRENT; break;
77
* case STABLE: st = new Tracker(this); break;
78
* case DYNAMIC: st = StateTracker.NEVER_CURRENT; break;
79
* case UNTRACKABLE: st = StateTracker.NEVER_CURRENT; break;
80
* }
81
* curTracker = st;
82
* }
83
* return st;
84
* }
85
*
86
* static class Tracker implements StateTracker {
87
* Trackable theTrackable;
88
* public Tracker(Trackable t) {
89
* theTrackable = t;
90
* }
91
* public boolean isCurrent() {
92
* return (theTrackable.curTracker == this);
93
* }
94
* }
95
* }
96
* </pre>
97
* Note that the mechanism shown above for invalidating outstanding
98
* StateTracker objects is not the most theoretically conservative
99
* way to implement state tracking in a "set" method.
100
* There is a small window of opportunity after the data has changed
101
* before the outstanding StateTracker objects are invalidated and
102
* where they will indicate that the data is still the same as when
103
* they were instantiated.
104
* While this is technically inaccurate, it is acceptable since the more
105
* conservative approaches to state management are much more complex and
106
* cost much more in terms of performance for a very small gain in
107
* correctness.
108
* For example:
109
* <p>
110
* The most conservative approach would be to synchronize all accesses
111
* and all modifications to the data, including its State.
112
* This would require synchronized blocks around some potentially large
113
* bodies of code which would impact the multi-threaded scalability of
114
* the implementation.
115
* Further, if data is to be coordinated or transferred between two
116
* trackable objects then both would need to be synchronized raising
117
* the possibility of deadlock unless some strict rules of priority
118
* for the locking of the objects were established and followed
119
* religiously.
120
* Either or both of these drawbacks makes such an implementation
121
* infeasible.
122
* <p>
123
* A less conservative approach would be to change the state of the
124
* trackable object to DYNAMIC during all modifications of the data
125
* and then to change it back to STABLE after those modifications
126
* are complete.
127
* While this state transition more accurately reflects the temporary
128
* loss of tracking during the modification phase, in reality the
129
* time period of the modifications would be small in most cases
130
* and the 2 changes of state would each require synchronization.
131
* <p>
132
* In comparison the act of setting the {@code curTracker}
133
* reference to null in the usage pattern above effectively invalidates
134
* all outstanding {@code Tracker} objects as soon as possible
135
* after the change to the data and requires very little code and no
136
* synchronization to implement.
137
* <p>
138
* In the end it is up to the implementor of a StateTrackable object
139
* how fine the granularity of State updates should be managed based
140
* on the frequency and atomicity of the modifications and the
141
* consequences of returning an inaccurate State for a particularly
142
* small window of opportunity.
143
* Most implementations are likely to follow the liberal, but efficient
144
* guidelines found in the usage pattern proposed above.
145
*
146
* @since 1.7
147
*/
148
public interface StateTrackable {
149
/**
150
* An enumeration describing the current state of a trackable
151
* object.
152
* These values describe how often the complex data contained
153
* in a trackable object can be changed and whether or not it
154
* makes sense to try to track the data in its current state.
155
* @see StateTrackable#getState
156
* @since 1.7
157
*/
158
public enum State {
159
/**
160
* The complex data will never change again.
161
* Information related to the current contents of the complex
162
* data can be calculated and cached indefinitely with no
163
* further checks to see if the information is stale.
164
*/
165
IMMUTABLE,
166
167
/**
168
* The complex data is currently stable, but could change at
169
* some point in the future.
170
* Information related to the current contents of the complex
171
* data can be calculated and cached, but a StateTracker should
172
* be used to verify the freshness of such precalculated data
173
* before each future use.
174
*/
175
STABLE,
176
177
/**
178
* The complex data is currently in flux and is frequently
179
* changing.
180
* While information related to the current contents of the
181
* complex data could be calculated and cached, there is a
182
* reasonably high probability that the cached information
183
* would be found to be out of date by the next time it is
184
* used.
185
* It may also be the case that the current contents are
186
* temporarily untrackable, but that they may become trackable
187
* again in the future.
188
*/
189
DYNAMIC,
190
191
/**
192
* The complex data can currently be changed by external
193
* references and agents in a way that cannot be tracked.
194
* If any information about the current contents of the complex
195
* data were to be cached, there would be no way to determine
196
* whether or not that cached information was out of date.
197
*/
198
UNTRACKABLE,
199
};
200
201
/**
202
* Returns the general state of the complex data held by this
203
* object.
204
* This return value can be used to determine if it makes
205
* strategic sense to try and cache information about the current
206
* contents of this object.
207
* The StateTracker returned from the getStateTracker() method
208
* will further aid in determining when the data has been
209
* changed so that the caches can be verified upon future uses.
210
* @return the current state of trackability of the complex
211
* data stored in this object.
212
* @see #getStateTracker
213
* @since 1.7
214
*/
215
public State getState();
216
217
/**
218
* Returns an object which can track future changes to the
219
* complex data stored in this object.
220
* If an external agent caches information about the complex
221
* data of this object, it should first get a StateTracker
222
* object from this method so that it can check if such
223
* information is current upon future uses.
224
* Note that a valid StateTracker will always be returned
225
* regardless of the return value of getState(), but in some
226
* cases the StateTracker may be a trivial implementation
227
* which always returns the same value from its
228
* {@link StateTracker#isCurrent isCurrent} method.
229
* <ul>
230
* <li>If the current state is {@link State#IMMUTABLE IMMUTABLE},
231
* this StateTracker and any future StateTracker objects
232
* returned from this method will always indicate that
233
* the state has not changed.</li>
234
* <li>If the current state is {@link State#UNTRACKABLE UNTRACKABLE},
235
* this StateTracker and any future StateTracker objects
236
* returned from this method will always indicate that
237
* the state has changed.</li>
238
* <li>If the current state is {@link State#DYNAMIC DYNAMIC},
239
* this StateTracker may always indicate that the current
240
* state has changed, but another StateTracker returned
241
* from this method in the future when the state has changed
242
* to {@link State#STABLE STABLE} will correctly track changes.</li>
243
* <li>Otherwise the current state is {@link State#STABLE STABLE}
244
* and this StateTracker will indicate whether or not the
245
* data has changed since the time at which it was fetched
246
* from the object.</li>
247
* </ul>
248
* @return an object implementing the StateTracker interface
249
* that tracks whether changes have been made to the complex
250
* contents of this object since it was returned.
251
* @see State
252
* @see #getState
253
* @since 1.7
254
*/
255
public StateTracker getStateTracker();
256
}
257
258