= QueryResultsCache
:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR  CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

This service (API and implementation) provides a mechanism by which idempotent query results can be cached for the duration of an _org.apache.isis.applib.services.iactn.Interaction_ .

Caching such values is useful to improve the response time (for the end user) of code that loops "naively" through a set of items, performing an expensive operation each time. If the data is such that the same expensive operation is made many times, then the query cache is a perfect fit.

For example, code that makes a repository call many times within a loop can be performance tuned using this service. The benefit is that the algorithm of the business logic can remain easy to understand.

== API

[source,java]
.QueryResultsCache.java
----
class QueryResultsCache {
  T execute(Callable<T> callable, Class<?> callingClass, String methodName, Object... keys)     // <.>
  R execute(MethodReferences.Call0<? extends R> action, Class<?> callingClass, String methodName)
  R execute(MethodReferences.Call1<? extends R, A0> action, Class<?> callingClass, String methodName, A0 arg0)
  R execute(MethodReferences.Call2<? extends R, A0, A1> action, Class<?> callingClass, String methodName, A0 arg0, A1 arg1)
  R execute(MethodReferences.Call3<? extends R, A0, A1, A2> action, Class<?> callingClass, String methodName, A0 arg0, A1 arg1, A2 arg2)
  R execute(MethodReferences.Call4<? extends R, A0, A1, A2, A3> action, Class<?> callingClass, String methodName, A0 arg0, A1 arg1, A2 arg2, A3 arg3)
  R execute(MethodReferences.Call5<? extends R, A0, A1, A2, A3, A4> action, Class<?> callingClass, String methodName, A0 arg0, A1 arg1, A2 arg2, A3 arg3, A4 arg4)
  void onTransactionEnded()     // <.>
  void destroy()
}
----

<.> xref:#execute_Callable_Class_String_Object[execute(Callable, Class, String, Object)]
+
--
Executes the callable if not already cached for the supplied calling class, method and keys.
--
<.> xref:#onTransactionEnded_[onTransactionEnded()]
+
--
Not API: for framework to call at end of transaction, to clear out the cache.
--

== Members

[#execute_Callable_Class_String_Object]
=== execute(Callable, Class, String, Object)

Executes the callable if not already cached for the supplied calling class, method and keys.

[#onTransactionEnded_]
=== onTransactionEnded()

Not API: for framework to call at end of transaction, to clear out the cache.

(This service really ought to be considered a transaction-scoped service; since that isn't yet supported by the framework, we have to manually reset).

include::hooks/QueryResultsCache_010-implementation.adoc[]

include::hooks/QueryResultsCache_020-examples-and-usage.adoc[]
