Hi Laurent,

Here's a suggestion on how I would set up the array caching code, mainly with regard to making it easier to make sure we are managing then consistently, but also to allow for more flexible tuning later.

First, make all interactions go through the cache object itself - get, grow, put. This gets rid of a number of static methods with a bunch of similar names and groups the management methods in a class hierarchy.

Second, have each consumer of arrays use its own cache object. Some of them may be the same object reference between different "users", and some of them may be different objects but share their underlying arrays with each other, but a given piece of code could be traced to always get/grow/put its arrays into the same cache object. That way it's easier to see that you aren't mixing/matching clean/dirty arrays.

DirtyFooCache
    foo[] get(size)
    foo[] grow(foo[], newsize)  // or widen?
    void put(foo[])

CleanFooCache
    foo[] get(size)
    foo[] grow(foo[], newsize, <used parts>)
    void put(foo[], <used parts>)

Then code that manages an array named bar would be managed as:
(It may be the same instance as another FooCache
 or it may share its arrays with another FooCache
 but the "barCache" reference is only ever used for the bar array...)
    [Clean|Dirty]FooCache barCache = make/get/share a Cache instance;
    foo[] bar;
    ...
    bar = barCache.get(initSize);
    ...
    bar = barCache.grow/widen(bar, newSize[, usage if clean]);
    ...
    barCache.put(bar[, usage if clean]);
    bar = null;

It's easier to verify that bar is being managed consistently if it always goes back to its own bar object. You can then decide if too different uses of foo[] arrays should share the same arrays or not based on profiling. You can also potentially have different growth algorithms for 2 different arrays of the same type, but possibly even sharing the same underlying arrays. Any degree of customization is possible underneath the covers behind a FooCache basic interface.

I'd also either make the growth heuristics an argument to creating/fetching a FooCache instance or make it subject to a helper "CacheSizeManager" or "CacheSizeStrategy" object in such a way that different uses of IntCache might be able to have different growth strategies - and to possibly even manage different sizing strategies on top of the same set of underlying arrays (i.e. one has buckets that grow by <<2 and another by <<1 and for the even buckets, they share arrays, for instance).

The main thing for the near term, is that it would be nice to have each array use its own cache object so that we can easily verify that it is being consistent with its handling of arrays...

                        ...jim

Reply via email to