Is it possible to implement caching of method results based on field input instead of map?

I've seen some implementations of method result caching using AspectJ. For example one of the jcabi-aspects or some old examples ,

The idea is that instead of writing boliver code to cache the result of a method in a field, for example:

public Mesh someComplexGeometry() {
    if (this.geometry == null) {
        this.geometry = computeTheGeometry();
    }
    return this.geometry;
}

      

We comment out the methods, so the AspectJ compiler changes its bytecode so that their result is stored somewhere after the first execution and retrieved on successive launches:

@Cacheable
public Mesh someComplextGeometry() {
  // just compute the mesh, very neat and clear
}

      

I'm worried that all the caching aspects I've seen implementations rely on storing values ​​in Map

. It also involves the rather complicated process of constructing keys for these cards. I am afraid this may affect performance.

I think it would be ideal if there was an aspect that worked this way: for each of the n class methods annotated with @Cacheable

, add a field to that class private Object cache_n

, and then on the first method, the call stores the result in the field, not in Map

. and then continues to return the contents of the field on successive calls to the method.

So, the idea is to introduce custom private fields for each annotated method while weaving instead of using whole fat Map

. But I cannot figure out how to do this, and if it is possible.

The next aspect implements what I want, but only for the case where the class has only one method annotated with @Cached

:

public aspect Cacher {
    private Object cache;

    pointcut cached(): execution(@Cached * * (..));

    Object around(): cached() {
        if (cache == null) {
            cache = proceed();
        }
        return cache;
    }
}

      

Can I do this kind of caching with AspectJ? If I can't, are there any platform restrictions that prohibit such a thing, or is it simply not implemented in the AspectJ language?

+3


source to share


1 answer


You can create such a field-based memoization using percflow

Per Clause. This will instantiate your aspect for each method to gossip.



This should of course only be used if the method has no parameter. when the method uses a parameter, you still need a map to know what result will be returned based on the parameter.

0


source







All Articles