thank you very much for uploading and commenting the sources.
i did not revise the code, yet, but i would like to discuss your statements...
i) exception handling as logic
you told me not to use exception handling as logic because instantiation of exceptions "take[s] a large hit".
well, i guess, for a single execution an if/ else may be faster than throwing/ catching an exception. but please consider how often the exception is actually thrown: only
- if the pool is empty (arraySize == 0) and get() is called or
- the pool is full (arraySize == array.length) and release() is called.
in contrast an if/ else would add an extra operation whenever get() or release() is executed.
that is why i excepted the exception handling logic to be the way to go.
what do you think?
ii) LinkedList vs. array
you proposed to use a LinkedList instead of cloning the array.
i guess instantitation of arrays is more expensive than instantitation of a LinkedList.Entry, so again you may be right in case of a single execution. but please keep in mind that a LinkedList would be resized whenever get() or release() is called. LinkedList.add() creates a new LinkedList.Entry and links it to the first or last element of the list; LinkedList.remove() unlinks a LinkedList.Entry that later will be destroyed by gc.
for an array, resizing occurs only if the pool is full (arraySize == array.length) and another element is released (and should be stored in the array). on get() no resizing (/ instantiation) is necessary.
so i guess than an array should beat a LinkedList -in case of frequent calls?
you said that the pool is always sorted by LRU (last recently used) and you are right, of course.
that means, on timeout not all elements in the pool have to be verified: i may remove the first timedout element and all elements beyond it.
so i suggest the following timeout algorithm: on timeout the current arraySize will be remembered as "timeout index". on next timeout this index will be used to find the first timedout element (at "timedout index"). if the element at timeout index is not timedout, timedout index has to be greater (otherwise less) than timeout index. all elements at and beyond timedout index will later be removed. in this way iteration is reduced to the minimum, unnecessary operations are avoided.
do you confirm?