IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 337


Ignore:
Timestamp:
Mar 31, 2004, 4:34:37 PM (22 years ago)
Author:
eugene
Message:

substantial additions to the text of psDlist and psHash.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/doc/pslib/psLibSDRS.tex

    r320 r337  
    1 %%% $Id: psLibSDRS.tex,v 1.15 2004-03-31 21:27:48 eugene Exp $
     1%%% $Id: psLibSDRS.tex,v 1.16 2004-04-01 02:34:37 eugene Exp $
    22\documentclass[panstarrs]{panstarrs}
    33%\documentclass[panstarrs]{panstarrs}
     
    788788\end{itemize}
    789789
     790\subsection{Data Structure Type Information}
     791
     792Throughout PSLib, we require a variety of structures which correspond
     793to different mathematical data concepts.  For example, we have several
     794data structures which correspond to one-dimensional arrays (vectors)
     795of different data types (\code{int}, \code{float}, etc).  We also have
     796different data structures which correspond to two-dimensional arrays
     797(images or matrices), again with different data types for the
     798individual elements. 
     799
     800A variety of functions perform operations which are equivalent for
     801different data types of the same dimension, or may even be defined for
     802different data types of different dimensions.  For example, if we
     803write the operation $x + y$, the operation is clearly defined
     804regardless of whether the operands $x$ and $y$ are both zero
     805dimensional (single numbers), one dimensional (vectors), two
     806dimensional (images), etc. It is even reasonable to define the meaning
     807of such an operation if the data dimensions do not match: if $x$ is a
     808scalar and $y$ is an image, the natural operation is to add the value
     809of $x$ to every element of $y$; we can also define the meaning of the
     810operation if $x$ is a vector and $y$ is a matrix.  Nor does it matter
     811mathematically that the element data types match; the sum of a float
     812and an integer is a well-defined quantity!  One constraint should be
     813noted: the size of the elements in each dimension must match.  For
     814example, if $x$ were a vector of 100 elements, but $y$ were a vector
     815of 1000 elements, the meaning of the operation $x + y$ is unclear.
     816This type of operation should probably be invalid.
     817
     818Given that some functions should be able to operate equivalently (or
     819identically) on a wide range of data types, it seems cumbersome to be
     820forced into defining a large number of C functions to handle the
     821different data types, just because we have different structures.
     822Admittedly, some details of the function would have to vary for
     823different data types, but since the basic function is the same, it
     824would help both the user and programmer if the same function could be
     825used for different data types.  We therefore define a mechanism which
     826allows the C functions to accept a generic data type, and determine
     827the type of the data on the basis of the data.  The mechanism uses the
     828structure \code{psType}.
     829
     830Each of these equivalent data type is defined by a structure in which
     831the first element is always of type \code{psType}.  This element
     832defines both the dimensions of the array and the data type of each
     833element.  The structure is as follows:
     834\begin{verbatim}
     835typedef struct {
     836    psDimen dimen;                      ///< The dimensionality
     837    psElemType type;                    ///< The type
     838} psType;
     839\begin{end}
     840where \code{psDimen dimen} defines the dimensionality of the data and
     841\code{psElemType type} defines the data type of each element.  These
     842two variable types are defined as structures:
     843\begin{verbatim}
     844typedef enum {
     845    PS_DIMEN_SCALAR,                    ///< Scalar
     846    PS_DIMEN_VECTOR,                    ///< A vector
     847    PS_DIMEN_TRANSV,                    ///< A transposed vector
     848    PS_DIMEN_MATRIX,                    ///< A matrix
     849    PS_DIMEN_OTHER                      ///< Something else that's not supported for arithmetic
     850} psDimen;
     851\end{verbatim}
     852and
     853\begin{verbatim}
     854typedef enum {
     855    PS_TYPE_CHAR,                       ///< Character
     856    PS_TYPE_SHORT,                      ///< Short integer
     857    PS_TYPE_INT,                        ///< Integer
     858    PS_TYPE_LONG,                       ///< Long integer
     859    PS_TYPE_UCHAR,                      ///< Unsigned character
     860    PS_TYPE_USHORT,                     ///< Unsigned short integer
     861    PS_TYPE_UINT,                       ///< Unsigned integer
     862    PS_TYPE_ULONG,                      ///< Unsigned long integer
     863    PS_TYPE_FLOAT,                      ///< Floating point
     864    PS_TYPE_DOUBLE,                     ///< Double-precision floating point
     865    PS_TYPE_COMPLEX,                    ///< Complex numbers consisting of floating point
     866    PS_TYPE_OTHER,                      ///< Something else that's not supported for arithmetic
     867} psElemType;
     868\end{verbatim}
     869We discuss the application of \code{psType} in more detail in
     870section~\ref{math}. 
     871
    790872\subsection{Simple Array types}
    791873
     874\begin{verbatim}
     875psIntArray
     876psFloatArray
     877psDoubleArray
     878psComplexArray
     879psVoidPtrArray
     880\end{verbatim}
     881
    792882\subsubsection{Arrays of Simple Types}
    793883
    794 Any \PS{} datatype \code{psType} may be associated with an array type
    795 \code{psTypeArray}:
     884We require several types of basic one-dimensional arrays: arrays of
     885values of type \code{int}, \code{float}, \code{double},
     886\code{complex}, and \code{void *}.  We have defined structures for
     887these types which are all equivalent.  We illustrate them with the
     888example of \code{psFloatArray}:
     889%
    796890\begin{verbatim}
    797891typedef struct {
    798   int size;
    799   int n;
    800   psType *arr;
    801 } psTypeArray;
    802 \end{verbatim}
    803 with associated constructors and a destructor:
    804 \begin{verbatim}
    805 psTypeArray *psTypeAlloc(int n, int size);
    806 psTypeArray *psTypeRealloc(psTypeArray *arr, int n);
    807 void psTypeFree(psTypeArray *arr); 
    808 \end{verbatim}
    809 
    810 The argument \code{n} is the dimension of the array; \code{size}
    811 is the number of elements allocated ($s \ge n$).
    812 
    813 This type and functions may be declared and defined using two macros,
    814 \code{PS_DECLARE_ARRAY_TYPE(psType)} and
    815 \code{PS_CREATE_ARRAY_TYPE(psType)}.  The former defines the
    816 \code{typedef} and declares the prototypes (and is thus suitable for
    817 use in a header file); the latter generates the code for the three
    818 functions \code{psType(Alloc|Realloc|Free)} (and should thus appear in
    819 exactly one source file for a given type).
    820 
    821 The \code{psType} should be a single word (e.g. \code{psXY}); in particular,
    822 there is no requirement to support a pointer type (\eg{} \code{psXY *});
    823 see next section.
     892    psType type;                        ///< Type of data.  Must be first element
     893    int nalloc;                         ///< Total number of elements available
     894    int n;                              ///< Number of elements in use
     895    float *arr;                         ///< The array data
     896} psFloatArray;
     897\end{verbatim}
     898%
     899In this structure, the argument \code{n} is the length of the array
     900(the number of elements); \code{size} is the number of elements
     901allocated ($s \ge n$).  The allocated memory is available at
     902\code{arr}.  The data type is defined by the first element,
     903\code{psType}.  The structure is associated with a constructor and a destructor:
     904%
     905\begin{verbatim}
     906psFloatArray *psFloatArrayAlloc(int nalloc);
     907psFloatArray *psFloatArrayRealloc(psFloatArray *myArray, int nalloc);
     908void psFloatArrayFree(psFloatArray *restrict myArray);
     909\end{verbatim}
     910%
     911In these functions, \code{nalloc} is the number of elements to
     912allocate.  For \code{psFloatArrayAlloc}, the value of
     913\code{psFloatArray.n} is set to 0 and the allocated arrays are
     914initialized to 0.0.  For \code{psFloatArrayRealloc}, if the value of
     915\code{nalloc} is smaller than the current value of
     916\code{psFloatArray.n}, then \code{psFloatArray.n} is set to
     917\code{nalloc}, the array is adjusted down to match \code{nalloc}, and
     918the extra elements are lost.  If \code{nalloc} is larger than the
     919current value of \code{psFloatArray.n}, \code{psFloatArray.n} is left
     920intact.  If the value of \code{myArray} is \code{NULL}, then
     921\code{psFloatArrayRealloc} behaves like \code{psFloatArrayAlloc}.
     922
     923Basic one-dimensional arrays of all of the types listed above have
     924equivalent structures, constructors, and destructors to those for
     925\code{psFloatArray}, with the words \code{float} converted to the
     926appropriate type.  Thus we have:
     927\begin{verbatim}
     928psIntArray *psIntArrayAlloc(int nalloc);
     929psFloatArray *psFloatArrayAlloc(int nalloc);
     930psDoubleArray *psDoubleArrayAlloc(int nalloc);
     931psComplexArray *psComplexArrayAlloc(int nalloc);
     932\end{verbatim}
     933and so on for the other functions.  The collection of structures and
     934functions may be easily generated with C pre-processor macros.
    824935
    825936\subsubsection{Arrays of Pointer Types}
    826937
    827 The data type created with \code{PS_CREATE_ARRAY_TYPE} (\code{psType})
    828 contains an array of \code{psType}s not
    829 pointers to \code{psType}s; this means that the individual elements are
    830 not allocated using \code{psTypeAlloc}, are not correctly initialized,
    831 and shouldn't be individually deleted with \code{psTypeFree};
    832 
    833 If you wish to use arrays of pointers, use the macros
    834 \code{PS_DECLARE_ARRAY_PTR_TYPE(psType)} and
    835 \code{PS_CREATE_ARRAY_PTR_TYPE(psType)}. These
    836 create types \code{typedef psType *psTypePtr} and \code{psTypePtrArray}:
     938Arrays of pointer types need some additional specification.  We
     939require an array of pointers of type \code{void}, with which we can
     940carry around a collection of data of an arbitrary type which is more
     941complicated than the simple numeric types above.  The structure is a follows:
     942%
    837943\begin{verbatim}
    838944typedef struct {
    839   int size;
    840   int n;
    841   psTypePtr *arr;
    842 } psTypePtrArray;
    843 \end{verbatim}
    844 with associated constructors and a destructor:
    845 \begin{verbatim}
    846 psTypePtrArray *psTypePtrAlloc(int n, int size);
    847 psTypePtrArray *psTypePtrRealloc(psTypePtrArray *arr, int n);
    848 void psTypePtrArrayFree(psTypePtrArray *arr); 
    849 \end{verbatim}
    850 
    851 These constructors create arrays of \code{psType *} and call
    852 \code{psTypeAlloc} and \code{psTypeFree} to allocate and free the
    853 elements. As for the simple arrays, The former defines the typedef and
    854 declares the prototypes (and is thus suitable for use in a header
    855 file) and the latter generates the code for the three functions
    856 \code{psType(Alloc|Realloc|Free)} (and should thus appear in exactly one
    857 source file for a given type).
    858 
    859 The objects pointed to by these types have had their \code{refCounter}s
    860 incremented (see \ref{secMemRefcounter}); to remove an element from the array you
    861 need to say something like:
    862 \begin{verbatim}
    863   psTypePtrArray *pt = psTypePtrArrayAlloc(10, 10);
    864   psType *xy = psMemDecrRefCounter(pt->arr[0]);
    865   pt->arr[0] = NULL;
    866 \end{verbatim}
    867 
    868 \subsubsection{Arrays of \texttt{void *}}
    869 \hlabel{secArrayVoidPtr}
    870 
    871 Arrays of \code{void *} are different, as they need an explicitly-specified
    872 destructor.
    873 
    874 We require a type \code{psVoidPtrArray} that behaves in all respects
    875 as if it had been created with:
    876 \begin{verbatim}
    877 typedef void *psVoidPtr;
    878 PS_DECLARE_ARRAY_TYPE(psVoidPtr);
    879 PS_CREATE_ARRAY_TYPE(psVoidPtr);
    880 \end{verbatim}
    881 except that its destructor is specified as:
    882 \begin{verbatim}
    883 void psVoidPtrArrayFree(psVoidPtrArray *arr,      // array to destroy
    884                        void (*elemFree)(void *)); // destructor for array data
    885 \end{verbatim}
    886 
    887 The routine \code{psVoidPtrArrayFree} assumes that all pointers
    888 had their reference counters incremented
    889 when they were inserted onto the array.\footnote{%
    890   \eg{} \code{va->arr[i] = psMemIncrRefCounter(ptr);}}
    891 
     945    psType type;                        ///< Type of data.  Must be first element
     946    int nalloc;                         ///< Total number of elements available
     947    int n;                              ///< Number of elements in use
     948    void **arr;                         ///< The array data
     949} psVoidPtrArray;
     950\end{verbatim}
     951%
     952There is also an equivalent set of constructors and destructor:
     953%
     954\begin{verbatim}
     955psVoidPtrArray *psVoidPtrArrayAlloc(int nalloc);
     956psVoidPtrArray *psVoidPtrArrayRealloc(psVoidPtrArray *myArray, int nalloc);
     957void psVoidPtrArrayFree(psVoidPtrArray *restrict myArray, void (*elemFree)(void *));
     958\end{verbatim}
     959%
     960The only difference with the numeric array types is the addition of a
     961destructor function which is passed to \code{psVoidPrtArrayFree}.
     962This function, which may be \code{NULL}, is called for each existing
     963element of the array before the array itself is freed.  If the
     964function is \code{NULL}, the elements are are not freed.
     965
     966The routine \code{psVoidPtrArrayFree} assumes that all pointers had
     967their reference counters incremented when they were inserted onto the
     968array.\footnote{\eg{} \code{va->arr[i] = psMemIncrRefCounter(ptr);}}
    892969If \code{psVoidPtrArrayFree}'s argument \code{elemFree} is NULL, the
    893970list should be deleted, but not the elements on it (although their
    894971\code{refcounter}'s should be decremented).
    895972
    896 \subsubsection{Examples of Array Types}
    897 
    898 The following is a complete C program that illustrates the use of
    899 \code{array}s.
    900 \begin{verbatim}
    901 #include "psLib.h"
    902 
    903 typedef struct {
    904     int x, y;
    905 } psXY;
    906 
    907 psXY *psXYAlloc(void)
    908 {
    909     return psAlloc(sizeof(psXY));
    910 }
    911 
    912 void psXYFree(psXY *xy)
    913 {
    914     psFree(xy);
    915 }
    916 
    917 PS_DECLARE_ARRAY_TYPE(psXY);
    918 PS_CREATE_ARRAY_TYPE(psXY);
    919 
    920 PS_DECLARE_ARRAY_PTR_TYPE(psXY);
    921 PS_CREATE_ARRAY_PTR_TYPE(psXY);
    922 
    923 int main(void)
    924 {
    925     psXYArray *t = psXYArrayAlloc(10, 15);
    926     psXYPtrArray *pt = psXYPtrArrayAlloc(10, 10);
    927 
    928     for (int i = 0; i < t->n; i++) {
    929         t->arr[i].x = i;
    930         pt->arr[i]->y = 10*i;
    931     }
    932 
    933     t = psXYArrayRealloc(t, 5);
    934     t = psXYArrayRealloc(t, 8);
    935 
    936     for (int i = 0; i < t->n; i++) {
    937         printf("%d %d  ", t->arr[i].x, pt->arr[i]->y);
    938     }
    939     printf("\n");
    940    
    941     psXYArrayFree(t);
    942 
    943     psXY *xy = psMemDecrRefCounter(pt->arr[0]);
    944     pt->arr[0] = NULL;
    945     psXYFree(xy);   
    946    
    947     psXYPtrArrayFree(pt);
    948 
    949     psMemCheckLeaks(0, NULL, stderr);
    950 
    951     return 0;
    952 }
    953 \end{verbatim}
    954 
    955973\subsection{Doubly-linked lists}
    956974\hlabel{psDlist}
    957975
    958 \PS{} supports doubly linked lists through a type \code{psDlist}.  The
    959 type consists of the following definitions:
    960 
    961 \begin{verbatim}
    962 /** Doubly-linked list element */
    963 typedef struct psDlistElem {
    964    struct psDlistElem *prev;            ///< previous link in list
    965    struct psDlistElem *next;            ///< next link in list
    966    void *data;                          ///< real data item
    967 } psDlistElem;
    968 
    969 /** Doubly-linked list */
     976\PS{} supports doubly linked lists through a type \code{psDlist}:
     977%
     978\begin{verbatim}
    970979typedef struct {
    971980   int n;                               ///< number of elements on list
     
    974983   psDlistElem *iter;                   ///< iteration cursor
    975984} psDlist;
    976 
    977 /** Special values of index into list */
    978 enum {
    979    PS_DLIST_HEAD = 0,                   ///< at head
    980    PS_DLIST_TAIL = -1,                  ///< at tail
    981    PS_DLIST_UNKNOWN = -2,               ///< unknown position
    982    PS_DLIST_PREV = -3,                  ///< previous element
    983    PS_DLIST_NEXT = -4                   ///< next element
    984 };
    985 \end{verbatim}
    986 
    987 The API is:
    988 
    989 \begin{verbatim}
    990 /** Constructor */
    991 psDlist *psDlistAlloc(void *data        ///< initial data item; may be NULL
    992                       );
    993 
    994 /** Destructor */
    995 void psDlistFree(psDlist *list,         ///< list to destroy
    996                 void (*elemFree)(void *) ///< destructor for data on list
    997                  );
    998 
    999 /**** List maintainence functions ****/
    1000 
    1001 /** Add to list */
    1002 psDlist *psDlistAdd(psDlist *list,      ///< list to add to (may be NULL)
    1003                     void *data,         ///< data item to add
    1004                     int where           ///< index, PS_DLIST_HEAD, or PS_DLIST_TAIL
    1005                     );
    1006 
    1007 /** Append to a list */
    1008 psDlist *psDlistAppend(psDlist *list,   ///< list to append to (may be NULL)
    1009                        void *data       ///< data item to add
    1010                        );
    1011 
    1012 /** Remove from a list */
    1013 void *psDlistRemove(psDlist *list,      ///< list to remove element from
    1014                     void *data,         ///< data item to remove
    1015                     int which           ///< index of item, or PS_DLIST_UNKNOWN, or PS_DLIST_NEXT, or
    1016                                         ///< PS_DLIST_PREV
    1017                     );
    1018 /** Retrieve from a list */
    1019 void *psDlistGet(const psDlist *list,   ///< list to retrieve element from
    1020                  int which              ///< index of item, or PS_DLIST_NEXT, or PS_DLIST_PREV
    1021                  );
    1022 
    1023 /** Convert doubly-linked list to an array */
    1024 psVoidPtrArray *psDlistToArray(psDlist *dlist ///< List to convert
    1025                                );
    1026 
    1027 /** Convert array to a doubly-linked list */
    1028 psDlist *psArrayToDlist(psVoidPtrArray *arr ///< Array to convert
    1029                         );
    1030 \end{verbatim}
    1031 
    1032 All data items placed onto lists (e.g. with \code{psDlistAdd}) shall
    1033 have their reference counters (section \ref{secMemRefcounter})
    1034 incremented.  When elements are removed from a list with
    1035 \code{psDlistRemove}, they shall have their reference counters
    1036 decremented. The action of retrieving data from a list (with
    1037 \code{psDlistGet}) shall not affect their reference counter.
    1038 
    1039 If \code{psDlistFree}'s argument \code{elemFree} is NULL, the
    1040 list should be deleted, but not the elements on it (although their
    1041 \code{refcounter}s should be decremented).
    1042 
    1043 Iteration over all elements of the list is provided by the functions:
    1044 \begin{verbatim}
    1045 /** Set the iterator */
    1046 void psDlistSetIterator(psDlist *list,  ///< list to retrieve element from
    1047                         int where,      ///< index, PS_DLIST_HEAD, or PS_DLIST_TAIL
    1048                         int which       ///< index of item, or PS_DLIST_UNKNOWN, or PS_DLIST_NEXT, or
    1049                                         ///< PS_DLIST_PREV
    1050                         );
    1051 
    1052 /** Get next element */
    1053 void *psDlistGetNext(psDlist *list,     ///< list to retrieve element from
    1054                      int which          ///< index of item, or PS_DLIST_UNKNOWN, or PS_DLIST_NEXT, or
    1055                                         ///< PS_DLIST_PREV
    1056                      );
    1057 
    1058 /** Get previous element */
    1059 void *psDlistGetPrev(psDlist *list,     ///< list to retrieve element from
    1060                      int which          ///< index of item, or PS_DLIST_UNKNOWN, or PS_DLIST_NEXT, or
    1061                                         ///< PS_DLIST_PREV
    1062                      );
    1063 \end{verbatim}
    1064 in which the \code{where} argument must be \code{PS_DLIST_HEAD} or \code{PS_DLIST_TAIL},
    1065 to start at the head or tail of the list, and \code{psDlistGetNext} and \code{psDlistGetPrev}
    1066 return the next/previous element. The argument \code{which} identifies which of potentially
    1067 many iteration cursors should be used; it must currently always be \code{0}.
    1068 
    1069 Explicit traversal of the list using the \code{psDlistElem}s
    1070 \code{prev} and \code{next} pointers is also supported.
    1071 
    1072 The routines to convert to and from \code{psVoidPtrArray}s,
    1073 \code{psDlistToArray} and \code{psArrayToDlist} shall ensure that the
    1074 objects on the arrays and lists have had their reference pointers
    1075 correctly incremented (see section \ref{secArrayVoidPtr}) (\eg{} that
    1076 \code{psArrayToDlist(psDlistToArray(list))} returns a properly-formed
    1077 \code{psDlist}).
    1078 
    1079 \subsubsubsection{Rationale}
    1080 
    1081 \tbd{defer this example to the psDlist section?}
    1082 
    1083 The \code{psMemBlock.refcounter} is clearly useful for detecting
    1084 attempts to free memory that is already free.  A more complex
    1085 application is for allowing pointers to complex data-objects (e.g.\
    1086 images) to appear in more than one data structure simultaneously:
    1087 
    1088 \begin{verbatim}
    1089 typedef struct {
    1090     char *name;
    1091     int value;
    1092 } psSimple;
    1093 
    1094 psSimple *psSimpleAlloc(const char *name, int val)
    1095 {
    1096     psSimple *simp = psAlloc(sizeof(psSimple));
    1097     simp->name = strcpy(psAlloc(strlen(name) + 1), name);
    1098     simp->value = val;
    1099 
    1100     return simp;
    1101 }
    1102 
    1103 void psSimpleFree(psSimple *simp)
    1104 {
    1105     if (simp == NULL) { return; }
    1106 
    1107     if (psMemGetRefCounter(simp) > 1) {
    1108         (void)psMemDecrRefCounter(simp);
    1109         return;
    1110     }
    1111 }
    1112 \end{verbatim}
    1113 
    1114 Because of the use of the \code{refcounter} field, we can safely put items of
    1115 this type onto many lists:
    1116 \goodbreak
    1117 \begin{verbatim}
    1118 simp = psSimpleAlloc("RHL", 0);
    1119 psDlistAppend(list1, psMemIncrRefCounter(simp));
    1120 psDlistAppend(list2, psMemIncrRefCounter(simp));
    1121 psSimpleFree(simp);
    1122 \end{verbatim}
    1123 
    1124 (Note: in fact there is no need to explicitly increment the counter
    1125 in this case, as the \code{psDlistAppend} (section \ref{psDlist})
    1126 API specifies that it
    1127 does it for you.)
     985\end{verbatim}
     986%
     987The type \code{psDlist} represents the container of the list.  It has
     988a pointer to the first element in the linked list (\code{head}), a
     989pointer to the last element in the list (\code{tail}), \tbd{an entry
     990for the current cursor location (\code{iter})}, and an entry to define
     991the number of elements in the list (\code{n}).
     992
     993The elements of the list are defined by the type \code{psDlistElem}:
     994%
     995\begin{verbatim}
     996typedef struct psDlistElem {
     997   struct psDlistElem *prev;            ///< previous link in list
     998   struct psDlistElem *next;            ///< next link in list
     999   void *data;                          ///< real data item
     1000} psDlistElem;
     1001\end{verbatim}
     1002%
     1003which includes a pointer to the next element in the list
     1004(\code{next}), the previous element in the list (\code{prev}), and a
     1005\code{void} pointer to whatever data is represented by this list
     1006element. 
     1007
     1008A list may be created with the function
     1009\begin{verbatim}
     1010psDlist *psDlistAlloc(void *data);
     1011\end{verbatim}
     1012which may take a pointer to a data item, or it may take \code{NULL}.
     1013The allocator creates both the \code{psDlist} and the first element in
     1014the list, pointed to by both \code{psDlist.head} and
     1015\code{psDlist.tail}.  If the data entry is \code{NULL}, then an empty
     1016list, with both pointers set to \code{NULL} should be created. 
     1017
     1018An entry may be added to the list with the function:
     1019\begin{verbatim}
     1020psDlist *psDlistAdd(psDlist *list, void *data, int where);
     1021\end{verbatim}
     1022which takes a pointer to the list and also returns a pointer to the
     1023list.  The returned pointer must be used as the value of
     1024\code{psDlist} may have changed.  The value of \code{where} specifies
     1025if the specified data item should be placed on the front of the list
     1026(\code{PS_DLIST_HEAD}), at the end of the list (\code{PS_DLIST_TAIL}),
     1027\tbd{use of other options?}. 
     1028
     1029A data item may be retrieved from the list with the function:
     1030\begin{verbatim}
     1031void *psDlistGet(psDlist *list, int which);
     1032\end{verbatim}
     1033The value of \code{which} may be the numerical index or it may be one
     1034of the special values: \code{PS_DLIST_HEAD}, \code{PS_DLIST_TAIL},
     1035\code{PS_DLIST_PREV}, and \code{PS_DLIST_NEXT}, all of which are
     1036defined as negative integers.
     1037
     1038A data item may be removed from the list with the function:
     1039\begin{verbatim}
     1040void *psDlistRemove(psDlist *list, void *data, int which);
     1041\end{verbatim}
     1042The value of \code{which} may be the numerical index or it may be one
     1043of the special values: \code{PS_DLIST_HEAD}, \code{PS_DLIST_TAIL},
     1044\code{PS_DLIST_PREV}, \code{PS_DLIST_UNKNOWN}, and
     1045\code{PS_DLIST_NEXT}, all of which are defined as negative integers.
     1046If the value of \code{which} is \code{PS_DLIST_UNKNOWN}, then the data
     1047item is identified by matching the pointer value with \code{void
     1048*data}.
     1049
     1050All data items placed onto lists (\code{psDlistAdd}) shall have their
     1051reference counters (section \ref{secMemRefcounter}) incremented.  When
     1052elements are removed from a list with \code{psDlistRemove}, they shall
     1053have their reference counters decremented. The action of retrieving
     1054data from a list (with \code{psDlistGet}) shall not affect their
     1055reference counter.
     1056
     1057A complete list may be freed with the destructor:
     1058\begin{verbatim}
     1059void psDlistFree(psDlist *list, void (*elemFree)(void *));
     1060\end{verbatim}
     1061If the element destructor (\code{elemFree}) is \code{NULL}, the list
     1062should be deleted, but not the elements, although their
     1063\code{refcounter}s should be decremented.
     1064
     1065Two functions are available to convert between the \code{psDlist} and
     1066\code{psVoidPtrArray} containers:
     1067\begin{verbatim}
     1068psVoidPtrArray *psDlistToArray(psDlist *dlist);
     1069psDlist *psArrayToDlist(psVoidPtrArray *arr);
     1070\end{verbatim}
     1071These functions do not free the elements or destroy the input
     1072collection.  Rather, they increment the reference counter for each of
     1073the elements.
     1074
     1075Iteration over all elements of the list using the iteration cursor
     1076\code{iter} is provided by the functions:
     1077\begin{verbatim}
     1078void psDlistSetIterator(psDlist *list, int where);
     1079void *psDlistGetNext(psDlist *list);
     1080void *psDlistGetPrev(psDlist *list);
     1081\end{verbatim}
     1082The first of these functions uses the value of \code{where} to set the
     1083iteration cursor for the given list to the beginning
     1084\code{PS_DLIST_HEAD} or the end \code{PS_DLIST_TAIL}.  The next two
     1085functions move the iteration cursor forward or backwards, returning
     1086the data item from the resulting list entry, or returning \code{NULL}
     1087at the end of the list.  Explicit traversal of the list using the
     1088\code{psDlistElem}s \code{prev} and \code{next} pointers is also
     1089supported.
    11281090
    11291091\subsection{Hash Tables}
    11301092\hlabel{psHash}
    11311093
    1132 The public APIs for the hash table (table \ref{tabPsHash}) are shown below.
    1133 \footnote{
    1134   We choose not to use the posix function \code{hcreate},
    1135   \code{hdestroy}, and \code{hsearch} as they only support
    1136   a single hash table at any one time.}
    1137 
    1138 \begin{verbatim}
    1139 typedef struct HashTable psHash;        ///< Opaque type for a hash table
    1140 
    1141 /// Allocate hash buckets in table.
    1142 psHash *psHashAlloc(int nbucket         ///< initial number of buckets
    1143     );
    1144 
    1145 /// Free hash buckets from table.
    1146 void psHashFree(psHash *table,          ///< hash table to be freed
    1147                 void (*itemFree)(void *item) ///< how to free hashed data; or NULL
    1148     );
    1149 
    1150 /// Insert entry into table.
    1151 void *psHashInsert(psHash *table,       ///< table to insert in
    1152                    const char *key,     ///< key to use
    1153                    void *data,          ///< data to insert
    1154                    void (*itemFree)(void *item) ///< how to free hashed data; or NULL
    1155     );
    1156 
    1157 /// Lookup key in table.
    1158 void *psHashLookup(psHash *table,       ///< table to lookup key in
    1159                    const char *key      ///< key to lookup
    1160     );
    1161 
    1162 /// Remove key from table.
    1163 void *psHashRemove(psHash *table,       ///< table to lookup key in
    1164                    const char *key      ///< key to lookup
    1165     );
    1166 \end{verbatim}
    1167 
    1168 A hash table is an abstract type \code{psHash}.  The argument
    1169 \code{nbucket} to \code{psHashAlloc} is a non-binding suggestion
    1170 from the user for the initial size of the hash table.
    1171 
    1172 If the \code{itemFree} argument to \code{psHashFree} is non-NULL,
    1173 it will be used to delete the data items that have been stored
    1174 in the hash table; if it is NULL this is the responsibility of
    1175 the caller.
    1176 
    1177 The routine \code{psHashInsert} must provide a non-NULL \code{itemFree}
    1178 argument if it wishes to change the value for previously inserted keys;
    1179 if \code{itemFree} is NULL attempting to insert a pre-existing key
    1180 is an error, and the routine will return NULL.  If  \code{psHashInsert}
    1181 succeeds it returns \code{data}.
    1182 
    1183 \code{psHashLookup} returns the \code{data} associated with the
    1184 key, or NULL if the key's invalid.
    1185 
    1186 \code{psHashRemove} removes the entry associated with the
    1187 key from the table, and returns the \code{data}; if the key's invalid it returns NULL.
    1188 
    1189 \code{psHashKeylist} returns the complete list of defined keys
    1190 associated with the psHash table. \tbd{API is not yet specified.}
     1094Hash tables are critical for quick retrieval of text-based data.  The
     1095concept is as follows: Given a large collection of text strings, it is
     1096inefficient to search for a particular entry by performing a basic
     1097string comparison on all entries until a match is found.  Even if a
     1098single list is sorted, we will still spend a substantial amount of
     1099time iterating across the entries in the list.  In a hash table, we
     1100define an operation, the hash function, which uses the bytes of the
     1101string to construct a numerical value, the hash value.  The hash value
     1102is defined to have a limited range of $N$ values.  The hash table
     1103consists of $N$ buckets, each of which contains a list of the strings
     1104whose hash value corresponds to the bucket number.  Searching for a
     1105specific string involves calculating the hash value for the string,
     1106going to the appropriate bucket, and searching through the
     1107corresponding list until the string is matched. 
     1108
     1109For PSLib, we define a hash table and hash buckets as follows:
     1110\footnote{ We choose not to use the posix function \code{hcreate},
     1111\code{hdestroy}, and \code{hsearch} as they only support a single hash
     1112table at any one time.}
     1113%
     1114\begin{verbatim}
     1115typedef struct {
     1116    int nbucket;                        // number of buckets
     1117    psHashBucket **buckets;             // the buckets themselves
     1118} psHash;
     1119\end{verbatim}
     1120%
     1121where \code{nbucket} is the number of buckets defined for the hash
     1122functions, and \code{buckets} are the individual buckets, each of
     1123which is defined by:
     1124%
     1125\begin{verbatim}
     1126typedef struct psHashBucket {
     1127    char *key;                          // key for this item of data
     1128    void *data;                         // the data itself
     1129    struct psHashBucket *next;          // list of other possible keys
     1130} psHashBucket;
     1131\end{verbatim}
     1132where each bucket contains the value of the \code{key}, a pointer to
     1133the \code{data}, and a pointer to the \code{next} list entry in the
     1134bucket.
     1135
     1136A hash table is created with the following function:
     1137\begin{verbatim}
     1138psHash *psHashAlloc(int nbucket);
     1139\end{verbatim}
     1140which allocates the space for the hash table and initializes all of
     1141the buckets.  \tbd{why specify nbucket? isn't it set by the hash
     1142function?}. 
     1143
     1144A data item may be added to the hash table with the function:
     1145\begin{verbatim}
     1146void *psHashInsert(psHash *table, char *key, void *data, void (*itemFree)(void *item));
     1147\end{verbatim}
     1148In this function, the value of the string \code{key} is used to
     1149construct the hash value, find the appropriate bucket set, and add the
     1150new element \code{data} to the list.  The element destructor,
     1151\code{itemFree}, is provided to destroy an existing element with the
     1152same value of \code{key}.  The routine \code{psHashInsert} must
     1153provide a non-NULL \code{itemFree} argument if it wishes to change the
     1154value for previously inserted keys; if \code{itemFree} is NULL
     1155attempting to insert a pre-existing key is an error, and the routine
     1156will return NULL.  If \code{psHashInsert} succeeds it returns
     1157\code{data}.
     1158
     1159The data associated with a given key may be found with the function:
     1160\begin{verbatim}
     1161void *psHashLookup(psHash *table, char *key);
     1162\end{verbatim}
     1163which returns the data value pointed to by the element associated with
     1164\code{key}, or the value \code{NULL} if no match is found.  Similarly,
     1165a specific key may be removed (deleted) with the function:
     1166\begin{verbatim}
     1167void *psHashRemove(psHash *table, char *key);
     1168\end{verbatim}
     1169\tbd{what is return value?}
     1170
     1171A complete hash table may be freed by calling:
     1172\begin{verbatim}
     1173void psHashFree(psHash *table, void (*itemFree)(void *item));
     1174\end{verbatim}
     1175where the function \code{itemFree} is provided to delete the
     1176individual elements in the table.  If it is NULL this is the
     1177responsibility of the caller.
     1178
     1179The function
     1180\begin{verbatim}
     1181psDlist *psHashKeylist(psHast *table);
     1182\end{verbatim}
     1183returns the complete list of defined keys associated with the psHash
     1184table as a linked list.
    11911185
    11921186\section{Data manipulation}
Note: See TracChangeset for help on using the changeset viewer.