History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/java2d/StateTrackable.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/java2d/StateTrackable.java+256−0
@@ -0,0 +1,256 @@
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</code>
133+ * reference to null in the usage pattern above effectively invalidates
134+ * all outstanding <code>Tracker</code> 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+}