B
Ben Pfaff
James Dow Allen said:Much software has the form
High Level -- application-specific code
Mid Level -- application-specific code
Low Level -- FREQUENT FUNCTION, use library
But often one encounters
High Level -- application-specific code
Mid Level -- FREQUENT FUNCTION
Low Level -- application-specific code
A familiar example where this form is encountered and
dealt with is qsort(), with the low-level handled
simply with a function pointer.
When I run into the latter situation in a performance-critical
area, I try to think of ways that I can invert the dependency,
flipping it around so that it becomes the former situation. One
way to do this is to make the application-specific client code do
more work. This does have the cost of making the client write
more code (but not always much more) and making the client more
tightly bound to the implementation,
One example is the hash table library that I use in PSPP,
available here:
http://git.savannah.gnu.org/cgit/pspp.git/tree/src/libpspp/hmap.h
http://git.savannah.gnu.org/cgit/pspp.git/tree/src/libpspp/hmap.c
Most generic hash table library, in my experience, require the
client to provide at least a hashing function and a comparison
function. My library does not use any function pointers.
Instead, the client provides a hash value at the time of
insertion, as an argument call to the insertion function, and the
library saves the hash value as part of the hash table node.
Instead of providing a conventional search function, the library
provides only a macro that iterates through hash table nodes that
have a given hash value, which is a suitable building block from
which the client can build a "search" function.
The resulting library is slightly harder to use in some ways. On
the other hand, I find that callback functions are often quite
awkward to use--for example, they force auxiliary data to be
inconveniently bundled up--so sometimes it is in fact easier to
use. Its operation is also, in my opinion, more transparent.
I've often idly thought about how the same idea could be applied
to sorting or balanced binary search trees, but it seems to be a
little trickier in those cases.