Skip to content

Commit 8800801

Browse files
committed
Add Hint to ignore the cache
1 parent a20b8dc commit 8800801

File tree

6 files changed

+149
-108
lines changed

6 files changed

+149
-108
lines changed

scijava-ops-api/src/main/java/org/scijava/ops/api/OpBuilder.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,8 @@ public Type getType() {
353353
Object.class });
354354
}
355355
};
356-
return env.op(opName, specialType, new Nil<?>[0], Nil.of(Object.class));
356+
return env.op(opName, specialType, new Nil<?>[0], Nil.of(Object.class),
357+
OpBuilder.this.hints);
357358
}
358359

359360
/**
@@ -432,7 +433,8 @@ public Type getType() {
432433
.getType() });
433434
}
434435
};
435-
return env.op(opName, specialType, new Nil<?>[0], outType);
436+
return env.op(opName, specialType, new Nil<?>[0], outType,
437+
OpBuilder.this.hints);
436438
}
437439

438440
/**

scijava-ops-api/src/main/java/org/scijava/ops/api/OpEnvironment.java

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
import org.scijava.discovery.Discoverer;
3838
import org.scijava.priority.Prioritized;
39+
import org.scijava.priority.Priority;
3940
import org.scijava.types.Nil;
4041

4142
/**
@@ -137,8 +138,14 @@ static OpEnvironment build() {
137138
* @param outType the return of the Op (note that it may also be an argument)
138139
* @return an instance of an Op aligning with the search parameters
139140
*/
140-
<T> T op(final String opName, final Nil<T> specialType,
141-
final Nil<?>[] inTypes, final Nil<?> outType);
141+
default <T> T op( //
142+
final String opName, //
143+
final Nil<T> specialType, //
144+
final Nil<?>[] inTypes, //
145+
final Nil<?> outType //
146+
) {
147+
return op(opName, specialType, inTypes, outType, getDefaultHints());
148+
}
142149

143150
/**
144151
* Returns an Op fitting the provided arguments.
@@ -167,8 +174,14 @@ <T> T op(final String opName, final Nil<T> specialType,
167174
* @param outType the return of the Op (note that it may also be an argument)
168175
* @return an instance of an Op aligning with the search parameters
169176
*/
170-
InfoTree infoTree(final String opName, final Nil<?> specialType,
171-
final Nil<?>[] inTypes, final Nil<?> outType);
177+
default InfoTree infoTree( //
178+
final String opName, //
179+
final Nil<?> specialType, //
180+
final Nil<?>[] inTypes, //
181+
final Nil<?> outType //
182+
) {
183+
return infoTree(opName, specialType, inTypes, outType, getDefaultHints());
184+
}
172185

173186
/**
174187
* Returns an {@link InfoTree} fitting the provided arguments.
@@ -197,7 +210,12 @@ default <T> T opFromInfoChain(InfoTree tree, Nil<T> specialType) {
197210
* @param specialType the generic {@link Type} of the Op
198211
* @return an instance of an Op aligning with the search parameters
199212
*/
200-
<T> T opFromSignature(final String signature, final Nil<T> specialType);
213+
default <T> T opFromSignature(final String signature,
214+
final Nil<T> specialType)
215+
{
216+
InfoTree info = treeFromID(signature);
217+
return opFromInfoChain(info, specialType);
218+
}
201219

202220
InfoTree treeFromID(final String signature);
203221

@@ -966,7 +984,9 @@ default OpBuilder.Arity16 arity16(final String opName, final Hints hints) {
966984
* @param names - the name(s) of the Op
967985
* @return an {@link OpInfo} which can make instances of {@code opClass}
968986
*/
969-
OpInfo opify(Class<?> opClass, String... names);
987+
default OpInfo opify(Class<?> opClass, String... names) {
988+
return opify(opClass, Priority.NORMAL, names);
989+
}
970990

971991
/**
972992
* Creates an {@link OpInfo} from an {@link Class} with the given priority.

scijava-ops-api/templates/main/java/org/scijava/ops/api/OpBuilder.vm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ public class OpBuilder {
238238
}
239239
};
240240
return env.op(opName, specialType, new Nil<?>[0], Nil.of(
241-
Object.class));
241+
Object.class), OpBuilder.this.hints);
242242
}
243243

244244
/**
@@ -307,7 +307,7 @@ public class OpBuilder {
307307
.getType() });
308308
}
309309
};
310-
return env.op(opName, specialType, new Nil<?>[0], outType);
310+
return env.op(opName, specialType, new Nil<?>[0], outType, OpBuilder.this.hints);
311311
}
312312

313313
/**

scijava-ops-engine/src/main/java/org/scijava/ops/engine/BaseOpHints.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,15 @@ private History() {
108108

109109
}
110110

111+
public static final class Cache {
112+
113+
private Cache() {
114+
// Prevent instantiation of static utility class
115+
}
116+
117+
public static final String PREFIX = "cache";
118+
public static final String IGNORE = PREFIX + ".IGNORE";
119+
120+
}
121+
111122
}

scijava-ops-engine/src/main/java/org/scijava/ops/engine/impl/DefaultOpEnvironment.java

Lines changed: 47 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -197,26 +197,16 @@ private SortedSet<OpInfo> filterInfos(SortedSet<OpInfo> infos, Hints hints) {
197197
}
198198

199199
@Override
200-
public <T> T op(final String opName, final Nil<T> specialType,
201-
final Nil<?>[] inTypes, final Nil<?> outType)
202-
{
203-
return op(opName, specialType, inTypes, outType, getDefaultHints());
204-
}
205-
206-
@Override
207-
public <T> T op(final String opName, final Nil<T> specialType,
208-
final Nil<?>[] inTypes, final Nil<?> outType, Hints hints)
209-
{
200+
public <T> T op( //
201+
final String opName, //
202+
final Nil<T> specialType, //
203+
final Nil<?>[] inTypes, //
204+
final Nil<?> outType, //
205+
Hints hints //
206+
) {
210207
return findOp(opName, specialType, inTypes, outType, hints).asOpType();
211208
}
212209

213-
@Override
214-
public InfoTree infoTree(String opName, Nil<?> specialType, Nil<?>[] inTypes,
215-
Nil<?> outType)
216-
{
217-
return infoTree(opName, specialType, inTypes, outType, getDefaultHints());
218-
}
219-
220210
@Override
221211
public InfoTree infoTree(String opName, Nil<?> specialType, Nil<?>[] inTypes,
222212
Nil<?> outType, Hints hints)
@@ -229,14 +219,6 @@ public InfoTree treeFromInfo(OpInfo info, Nil<?> specialType, Hints hints) {
229219
return findOp(info, specialType, hints).infoTree();
230220
}
231221

232-
@Override
233-
public <T> T opFromSignature(final String signature,
234-
final Nil<T> specialType)
235-
{
236-
InfoTree info = treeFromID(signature);
237-
return opFromInfoChain(info, specialType);
238-
}
239-
240222
@Override
241223
public <T> T opFromInfoChain(final InfoTree tree, final Nil<T> specialType,
242224
Hints hints)
@@ -271,11 +253,6 @@ public Type genericType(Object obj) {
271253
return typeService.reify(obj);
272254
}
273255

274-
@Override
275-
public OpInfo opify(final Class<?> opClass, String... names) {
276-
return opify(opClass, Priority.NORMAL, names);
277-
}
278-
279256
@Override
280257
public OpInfo opify(final Class<?> opClass, final double priority,
281258
String... names)
@@ -398,17 +375,26 @@ private <T> RichOp<T> findOp(final String opName, final Nil<T> specialType,
398375
{
399376
final OpRequest request = DefaultOpRequest.fromTypes(opName, specialType
400377
.getType(), outType != null ? outType.getType() : null, toTypes(inTypes));
401-
MatchingConditions conditions = generateCacheHit(request, hints);
402-
return (RichOp<T>) wrapViaCache(conditions);
378+
var conditions = MatchingConditions.from(request, hints);
379+
OpInstance<T> instance = (OpInstance<T>) generateCacheHit(conditions);
380+
return wrapOp(instance, conditions);
403381
}
404382

405383
@SuppressWarnings("unchecked")
406384
private <T> OpInstance<T> findOp(final OpInfo info, final Nil<T> specialType,
407385
Hints hints) throws OpMatchingException
408386
{
409387
OpRequest request = new InfoMatchingOpRequest(info, specialType);
410-
MatchingConditions conditions = insertCacheHit(request, hints, info);
411-
return (OpInstance<T>) getInstance(conditions);
388+
389+
// create new OpCandidate from request and info
390+
OpCandidate candidate = new OpCandidate(this, request, info);
391+
392+
MatchingConditions conditions = MatchingConditions.from(request, hints);
393+
var instance = instantiateOp(candidate, conditions.hints());
394+
395+
// cache instance
396+
setInstance(conditions, instance);
397+
return (OpInstance<T>) instance;
412398
}
413399

414400
private Type[] toTypes(Nil<?>... nils) {
@@ -418,33 +404,6 @@ private Type[] toTypes(Nil<?>... nils) {
418404
.toArray(Type[]::new);
419405
}
420406

421-
/**
422-
* Creates an Op instance from an {@link OpInfo} with the provided
423-
* {@link MatchingConditions} as the guidelines for {@link OpInfo} selection.
424-
* This Op instance is put into the {@link #opCache}, and is retrievable via
425-
* {@link DefaultOpEnvironment#wrapViaCache(MatchingConditions)}
426-
*
427-
* @param request the {@link OpRequest} request
428-
* @param hints the {@link Hints} containing matching preferences
429-
* @param info the {@link OpInfo} describing the Op that should match these
430-
* conditions1
431-
* @return the {@link MatchingConditions} that will return the Op described by
432-
* {@code info} from the op cache
433-
*/
434-
private MatchingConditions insertCacheHit(final OpRequest request, //
435-
final Hints hints, //
436-
final OpInfo info //
437-
) {
438-
MatchingConditions conditions = MatchingConditions.from(request, hints);
439-
440-
// create new OpCandidate from request and info
441-
OpCandidate candidate = new OpCandidate(this, request, info);
442-
443-
instantiateAndCache(conditions, candidate);
444-
445-
return conditions;
446-
}
447-
448407
/**
449408
* Finds an Op instance matching the request described by {@link OpRequest}
450409
* {@code request} and stores this Op in {@link #opCache}. NB the return must
@@ -453,40 +412,39 @@ private MatchingConditions insertCacheHit(final OpRequest request, //
453412
* provide that T (since the {@link OpRequest} could require that the Op
454413
* returned is of multiple types).
455414
*
456-
* @param request the {@link OpRequest} request
457-
* @param hints the {@link Hints} containing matching preferences
458-
* @return the {@link MatchingConditions} that will return the Op found from
459-
* the op cache
415+
* @param conditions the {@link MatchingConditions} defining a proper match
416+
* @return the {@link OpInstance} generated to satisfy {@code conditions}
460417
*/
461-
private MatchingConditions generateCacheHit(OpRequest request, Hints hints) {
462-
MatchingConditions conditions = MatchingConditions.from(request, hints);
418+
private OpInstance<?> generateCacheHit(MatchingConditions conditions) {
463419
// see if the request has been matched already
464420
OpInstance<?> cachedOp = getInstance(conditions);
465-
if (cachedOp != null) return conditions;
421+
if (cachedOp != null) return cachedOp;
466422

467423
// obtain suitable OpCandidate
468-
OpCandidate candidate = findOpCandidate(conditions.request(), conditions
469-
.hints());
470-
471-
instantiateAndCache(conditions, candidate);
472-
473-
return conditions;
474-
}
475-
476-
private void instantiateAndCache(MatchingConditions conditions,
477-
OpCandidate candidate)
478-
{
479-
// obtain Op instance (with dependencies)
480-
OpInstance<?> op = instantiateOp(candidate, conditions.hints());
424+
var candidate = findOpCandidate(conditions.request(), conditions.hints());
425+
var instance = instantiateOp(candidate, conditions.hints());
481426

482427
// cache instance
483-
opCache.putIfAbsent(conditions, op);
428+
setInstance(conditions, instance);
429+
return instance;
484430
}
485431

486432
private OpInstance<?> getInstance(MatchingConditions conditions) {
433+
if (conditions.hints().contains(BaseOpHints.Cache.IGNORE)) {
434+
return null;
435+
}
487436
return opCache.get(conditions);
488437
}
489438

439+
private void setInstance(MatchingConditions conditions,
440+
OpInstance<?> instance)
441+
{
442+
if (conditions.hints().contains(BaseOpHints.Cache.IGNORE)) {
443+
return;
444+
}
445+
opCache.put(conditions, instance);
446+
}
447+
490448
private OpCandidate findOpCandidate(OpRequest request, Hints hints) {
491449
return matcher.match(MatchingConditions.from(request, hints), this);
492450
}
@@ -631,18 +589,19 @@ private List<RichOp<?>> resolveOpDependencies(OpInfo info,
631589
// Then, match dependencies
632590
final List<RichOp<?>> dependencyChains = new ArrayList<>();
633591
for (final OpDependencyMember<?> dependency : Infos.dependencies(info)) {
634-
final OpRequest dep = inferOpRequest(dependency,
592+
final OpRequest request = inferOpRequest(dependency,
635593
dependencyTypeVarAssigns);
636594
try {
637-
// Add hints requested by the dependency
638-
Hints depHints = baseDepHints.plus(dependency.hints());
595+
var conditions = MatchingConditions.from(request,
596+
// Add hints requested by the dependency
597+
baseDepHints.plus(dependency.hints()));
639598

640-
MatchingConditions conditions = generateCacheHit(dep, depHints);
641-
dependencyChains.add(wrapViaCache(conditions));
599+
OpInstance<?> instance = generateCacheHit(conditions);
600+
dependencyChains.add(wrapOp(instance, conditions));
642601
}
643602
catch (final OpMatchingException e) {
644603
String message = DependencyMatchingException.message(info
645-
.implementationName(), dependency.getKey(), dep);
604+
.implementationName(), dependency.getKey(), request);
646605
if (e instanceof DependencyMatchingException) {
647606
throw new DependencyMatchingException(message,
648607
(DependencyMatchingException) e);
@@ -662,11 +621,6 @@ private OpRequest inferOpRequest(OpDependencyMember<?> dependency,
662621
return inferOpRequest(mappedDependencyType, dependencyName, typeVarAssigns);
663622
}
664623

665-
private RichOp<?> wrapViaCache(MatchingConditions conditions) {
666-
OpInstance<?> instance = getInstance(conditions);
667-
return wrapOp(instance, conditions);
668-
}
669-
670624
/**
671625
* Tries to infer a {@link OpRequest} from a functional Op type. E.g. the
672626
* type:

0 commit comments

Comments
 (0)