Class SwitchPointCache.Builder<T>
- Enclosing class:
SwitchPointCache
SwitchPointCache
.
The builder's constructor is passed information about the class, and
about a SwitchPoint
that will be used when the
dependent values need to be invalidated. To accommodate invalidation
schemes with different granularity, the SwitchPoint
used may be
kept in an instance field of the class, or in a static field and
governing all instances of the class, or even somewhere else entirely
and used for widespread or global invalidation.
The builder's withDependent
method is then used to
declare each value that can be computed and cached in an instance of the
class, by giving the name of a static method that computes the
value (given one argument, an instance of the class) and functions to get
and set a MethodHandle
-typed per-instance slot where the
computation result will be cached.
Finally, the builder's build
method returns
a Consumer<T>
that can be saved in a static final field and
invoked in the object's constructor; it will initialize all of the new
instance's fields that were declared in withDependent
calls to
their initial, uncomputed states.
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionbuild()
Return aUnaryOperator<MethodHandle[]>
to be invoked in the constructor of a client object, applied to a newly-allocated array of the right number of slots, which will initialize all of the array's elements with the corresponding fallback method handles and return the initialized array.withCandidates
(Method[] ms) Supply the candidate methods to be available to subsequentwithDependent
calls.withDependent
(String methodName, int index) Declare one dependent item that will be controlled by this builder'sSwitchPoint
.withDescriber
(Function<? super T, String> describer) Supply theLookup
object to be used in resolving dependent methods.withReceiverType
(Class<?> t) Adjust the static receiver type of subsequently declared dependents.withReturnType
(Class<?> t) Adjust the static return type of subsequently declared dependents that return references.withSlots
(Function<T, MethodHandle[]> slotGetter) Supply a function mapping a receiver object instance to the per-instanceMethodHandle
array whose elements will be the slots.withSwitchPoint
(Function<T, SwitchPoint> spGetter) Supply a function mapping a receiver object instance to theSwitchPoint
to be associated with subsequently declared slots.
-
Constructor Details
-
Builder
Create a builder that will be used to declare dependent values controlled by a singleSwitchPoint
and to create an initializer for the per-instance slots that will hold their states.- Parameters:
c
- the class being configured by this Builder
-
-
Method Details
-
withDescriber
- Parameters:
describer
- function, with a signature like that ofObject.toString
, that will produce a useful description of the object if needed in an exception message. The default if this method is not called isObject::toString
; a different describer can be supplied if the output oftoString
isn't well suited for an exception message. If null, any exception will have its bare constant message with nothing added about the specific receiver object.
-
withLookup
Supply theLookup
object to be used in resolving dependent methods.- Parameters:
l
- aLookup
object obtained by the caller and able to introspect in the class
-
withCandidates
Supply the candidate methods to be available to subsequentwithDependent
calls.- Parameters:
ms
- array of methods such as the caller may obtain withgetDeclaredMethods
, avoiding the access complications of having this class do it. The methods will be filtered to only those that are static with a non-void return type and exactly one parameter, assignable from the target class, and uniquely named within that set. Only such methods can be named in laterwithDependent
calls. No reference to the array will be retained.
-
withSwitchPoint
Supply a function mapping a receiver object instance to theSwitchPoint
to be associated with subsequently declared slots.- Parameters:
spGetter
- a function usable to fetch the SwitchPoint that controls this cache. It is passed an instance of T but need not use it (in the case, for example, of a single controlling SwitchPoint held in a static).
-
withSlots
Supply a function mapping a receiver object instance to the per-instanceMethodHandle
array whose elements will be the slots.- Parameters:
slotGetter
- a function usable to fetch the slot array for an instance.
-
withReturnType
Adjust the static return type of subsequently declared dependents that return references.This can be a more compact notation if compute methods or API methods from a superclass or subclass will be reused and the return type needs to be adjusted to match the static type in the API method (possibly erased from a generic type).
- Parameters:
t
- Class to serve as the following dependents' static return type. Pass null to discontinue adjusting return types for following dependents.- Throws:
IllegalArgumentException
- if t represents a primitive type.
-
withReceiverType
Adjust the static receiver type of subsequently declared dependents.This can be a more compact notation if compute methods or API methods from a superclass or subclass will be reused and the receiver type needs to be adjusted to match the static type in the API method (possibly erased from a generic type).
- Parameters:
t
- Class to serve as the following dependents' static receiver type. Pass null to discontinue adjusting receiver types for following dependents.- Throws:
IllegalArgumentException
- if t is neither a widening nor a narrowing of the receiver type specified for this builder.
-
build
Return aUnaryOperator<MethodHandle[]>
to be invoked in the constructor of a client object, applied to a newly-allocated array of the right number of slots, which will initialize all of the array's elements with the corresponding fallback method handles and return the initialized array.The initializer can be used conveniently in a constructor that assigns the array to a final field, or calls a superclass constructor that does so, to arrange that the array's elements are written in advance of Java's freeze of the final array reference field.
-
withDependent
Declare one dependent item that will be controlled by this builder'sSwitchPoint
.An item is declared by naming the static method that can compute its value when needed, and the index into the per-instance
MethodHandle[]
"slots" array that will be used to cache the value. Typically, these will be private, and there will be an API method for retrieving the value, by fetching the method handle from the array index given here, and invoking it.The method handle that will be found in the named slot has a return type matching the compute method named here, and two parameters; it expects the receiver object as the first parameter, and itself as the second. So the typical API method is simply:
MethodHandle h = slots[MY_SLOT]; return (cast)h.invokeExact(this, h);
When there is a cached value and the
SwitchPoint
has not been invalidated, the two arguments are ignored and the cached value is returned.- Parameters:
methodName
- name of the static method that will be used to compute values for this item. It must be found among the methods that were passed to the Builder constructor, only considering those that are static, with a non-void return and one argument of the class type.index
- index into the per-instance slot arrray where the cached state will be maintained.
-