Fix caching of record arrays and add for scalars

The implementation of caching for ndarrays of structured types
erroneously uses the type_num to distinguish between different
types - unfortunately in the case of structured arrays, the
type_num is always NPY_VOID, so it treats all structured array
types as being the same type.

As a more correct alternative, this commit changes the
implementation to store a mapping between types and typecodes in a
dict, whose keys are a tuple of the PyArray_Descr* for the array,
the layout, and the dimension.

Additionally, this commit adds caching for scalar record types
using similar logic.
Adding myself