Changeset 337
- Timestamp:
- Mar 31, 2004, 4:34:37 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/doc/pslib/psLibSDRS.tex (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/doc/pslib/psLibSDRS.tex
r320 r337 1 %%% $Id: psLibSDRS.tex,v 1.1 5 2004-03-31 21:27:48eugene Exp $1 %%% $Id: psLibSDRS.tex,v 1.16 2004-04-01 02:34:37 eugene Exp $ 2 2 \documentclass[panstarrs]{panstarrs} 3 3 %\documentclass[panstarrs]{panstarrs} … … 788 788 \end{itemize} 789 789 790 \subsection{Data Structure Type Information} 791 792 Throughout PSLib, we require a variety of structures which correspond 793 to different mathematical data concepts. For example, we have several 794 data structures which correspond to one-dimensional arrays (vectors) 795 of different data types (\code{int}, \code{float}, etc). We also have 796 different data structures which correspond to two-dimensional arrays 797 (images or matrices), again with different data types for the 798 individual elements. 799 800 A variety of functions perform operations which are equivalent for 801 different data types of the same dimension, or may even be defined for 802 different data types of different dimensions. For example, if we 803 write the operation $x + y$, the operation is clearly defined 804 regardless of whether the operands $x$ and $y$ are both zero 805 dimensional (single numbers), one dimensional (vectors), two 806 dimensional (images), etc. It is even reasonable to define the meaning 807 of such an operation if the data dimensions do not match: if $x$ is a 808 scalar and $y$ is an image, the natural operation is to add the value 809 of $x$ to every element of $y$; we can also define the meaning of the 810 operation if $x$ is a vector and $y$ is a matrix. Nor does it matter 811 mathematically that the element data types match; the sum of a float 812 and an integer is a well-defined quantity! One constraint should be 813 noted: the size of the elements in each dimension must match. For 814 example, if $x$ were a vector of 100 elements, but $y$ were a vector 815 of 1000 elements, the meaning of the operation $x + y$ is unclear. 816 This type of operation should probably be invalid. 817 818 Given that some functions should be able to operate equivalently (or 819 identically) on a wide range of data types, it seems cumbersome to be 820 forced into defining a large number of C functions to handle the 821 different data types, just because we have different structures. 822 Admittedly, some details of the function would have to vary for 823 different data types, but since the basic function is the same, it 824 would help both the user and programmer if the same function could be 825 used for different data types. We therefore define a mechanism which 826 allows the C functions to accept a generic data type, and determine 827 the type of the data on the basis of the data. The mechanism uses the 828 structure \code{psType}. 829 830 Each of these equivalent data type is defined by a structure in which 831 the first element is always of type \code{psType}. This element 832 defines both the dimensions of the array and the data type of each 833 element. The structure is as follows: 834 \begin{verbatim} 835 typedef struct { 836 psDimen dimen; ///< The dimensionality 837 psElemType type; ///< The type 838 } psType; 839 \begin{end} 840 where \code{psDimen dimen} defines the dimensionality of the data and 841 \code{psElemType type} defines the data type of each element. These 842 two variable types are defined as structures: 843 \begin{verbatim} 844 typedef 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} 852 and 853 \begin{verbatim} 854 typedef 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} 869 We discuss the application of \code{psType} in more detail in 870 section~\ref{math}. 871 790 872 \subsection{Simple Array types} 791 873 874 \begin{verbatim} 875 psIntArray 876 psFloatArray 877 psDoubleArray 878 psComplexArray 879 psVoidPtrArray 880 \end{verbatim} 881 792 882 \subsubsection{Arrays of Simple Types} 793 883 794 Any \PS{} datatype \code{psType} may be associated with an array type 795 \code{psTypeArray}: 884 We require several types of basic one-dimensional arrays: arrays of 885 values of type \code{int}, \code{float}, \code{double}, 886 \code{complex}, and \code{void *}. We have defined structures for 887 these types which are all equivalent. We illustrate them with the 888 example of \code{psFloatArray}: 889 % 796 890 \begin{verbatim} 797 891 typedef 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 % 899 In this structure, the argument \code{n} is the length of the array 900 (the number of elements); \code{size} is the number of elements 901 allocated ($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} 906 psFloatArray *psFloatArrayAlloc(int nalloc); 907 psFloatArray *psFloatArrayRealloc(psFloatArray *myArray, int nalloc); 908 void psFloatArrayFree(psFloatArray *restrict myArray); 909 \end{verbatim} 910 % 911 In these functions, \code{nalloc} is the number of elements to 912 allocate. For \code{psFloatArrayAlloc}, the value of 913 \code{psFloatArray.n} is set to 0 and the allocated arrays are 914 initialized 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 918 the extra elements are lost. If \code{nalloc} is larger than the 919 current value of \code{psFloatArray.n}, \code{psFloatArray.n} is left 920 intact. If the value of \code{myArray} is \code{NULL}, then 921 \code{psFloatArrayRealloc} behaves like \code{psFloatArrayAlloc}. 922 923 Basic one-dimensional arrays of all of the types listed above have 924 equivalent structures, constructors, and destructors to those for 925 \code{psFloatArray}, with the words \code{float} converted to the 926 appropriate type. Thus we have: 927 \begin{verbatim} 928 psIntArray *psIntArrayAlloc(int nalloc); 929 psFloatArray *psFloatArrayAlloc(int nalloc); 930 psDoubleArray *psDoubleArrayAlloc(int nalloc); 931 psComplexArray *psComplexArrayAlloc(int nalloc); 932 \end{verbatim} 933 and so on for the other functions. The collection of structures and 934 functions may be easily generated with C pre-processor macros. 824 935 825 936 \subsubsection{Arrays of Pointer Types} 826 937 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}: 938 Arrays of pointer types need some additional specification. We 939 require an array of pointers of type \code{void}, with which we can 940 carry around a collection of data of an arbitrary type which is more 941 complicated than the simple numeric types above. The structure is a follows: 942 % 837 943 \begin{verbatim} 838 944 typedef 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 % 952 There is also an equivalent set of constructors and destructor: 953 % 954 \begin{verbatim} 955 psVoidPtrArray *psVoidPtrArrayAlloc(int nalloc); 956 psVoidPtrArray *psVoidPtrArrayRealloc(psVoidPtrArray *myArray, int nalloc); 957 void psVoidPtrArrayFree(psVoidPtrArray *restrict myArray, void (*elemFree)(void *)); 958 \end{verbatim} 959 % 960 The only difference with the numeric array types is the addition of a 961 destructor function which is passed to \code{psVoidPrtArrayFree}. 962 This function, which may be \code{NULL}, is called for each existing 963 element of the array before the array itself is freed. If the 964 function is \code{NULL}, the elements are are not freed. 965 966 The routine \code{psVoidPtrArrayFree} assumes that all pointers had 967 their reference counters incremented when they were inserted onto the 968 array.\footnote{\eg{} \code{va->arr[i] = psMemIncrRefCounter(ptr);}} 892 969 If \code{psVoidPtrArrayFree}'s argument \code{elemFree} is NULL, the 893 970 list should be deleted, but not the elements on it (although their 894 971 \code{refcounter}'s should be decremented). 895 972 896 \subsubsection{Examples of Array Types}897 898 The following is a complete C program that illustrates the use of899 \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 955 973 \subsection{Doubly-linked lists} 956 974 \hlabel{psDlist} 957 975 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} 970 979 typedef struct { 971 980 int n; ///< number of elements on list … … 974 983 psDlistElem *iter; ///< iteration cursor 975 984 } 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 % 987 The type \code{psDlist} represents the container of the list. It has 988 a pointer to the first element in the linked list (\code{head}), a 989 pointer to the last element in the list (\code{tail}), \tbd{an entry 990 for the current cursor location (\code{iter})}, and an entry to define 991 the number of elements in the list (\code{n}). 992 993 The elements of the list are defined by the type \code{psDlistElem}: 994 % 995 \begin{verbatim} 996 typedef 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 % 1003 which 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 1006 element. 1007 1008 A list may be created with the function 1009 \begin{verbatim} 1010 psDlist *psDlistAlloc(void *data); 1011 \end{verbatim} 1012 which may take a pointer to a data item, or it may take \code{NULL}. 1013 The allocator creates both the \code{psDlist} and the first element in 1014 the list, pointed to by both \code{psDlist.head} and 1015 \code{psDlist.tail}. If the data entry is \code{NULL}, then an empty 1016 list, with both pointers set to \code{NULL} should be created. 1017 1018 An entry may be added to the list with the function: 1019 \begin{verbatim} 1020 psDlist *psDlistAdd(psDlist *list, void *data, int where); 1021 \end{verbatim} 1022 which takes a pointer to the list and also returns a pointer to the 1023 list. The returned pointer must be used as the value of 1024 \code{psDlist} may have changed. The value of \code{where} specifies 1025 if 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 1029 A data item may be retrieved from the list with the function: 1030 \begin{verbatim} 1031 void *psDlistGet(psDlist *list, int which); 1032 \end{verbatim} 1033 The value of \code{which} may be the numerical index or it may be one 1034 of 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 1036 defined as negative integers. 1037 1038 A data item may be removed from the list with the function: 1039 \begin{verbatim} 1040 void *psDlistRemove(psDlist *list, void *data, int which); 1041 \end{verbatim} 1042 The value of \code{which} may be the numerical index or it may be one 1043 of 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. 1046 If the value of \code{which} is \code{PS_DLIST_UNKNOWN}, then the data 1047 item is identified by matching the pointer value with \code{void 1048 *data}. 1049 1050 All data items placed onto lists (\code{psDlistAdd}) shall have their 1051 reference counters (section \ref{secMemRefcounter}) incremented. When 1052 elements are removed from a list with \code{psDlistRemove}, they shall 1053 have their reference counters decremented. The action of retrieving 1054 data from a list (with \code{psDlistGet}) shall not affect their 1055 reference counter. 1056 1057 A complete list may be freed with the destructor: 1058 \begin{verbatim} 1059 void psDlistFree(psDlist *list, void (*elemFree)(void *)); 1060 \end{verbatim} 1061 If the element destructor (\code{elemFree}) is \code{NULL}, the list 1062 should be deleted, but not the elements, although their 1063 \code{refcounter}s should be decremented. 1064 1065 Two functions are available to convert between the \code{psDlist} and 1066 \code{psVoidPtrArray} containers: 1067 \begin{verbatim} 1068 psVoidPtrArray *psDlistToArray(psDlist *dlist); 1069 psDlist *psArrayToDlist(psVoidPtrArray *arr); 1070 \end{verbatim} 1071 These functions do not free the elements or destroy the input 1072 collection. Rather, they increment the reference counter for each of 1073 the elements. 1074 1075 Iteration over all elements of the list using the iteration cursor 1076 \code{iter} is provided by the functions: 1077 \begin{verbatim} 1078 void psDlistSetIterator(psDlist *list, int where); 1079 void *psDlistGetNext(psDlist *list); 1080 void *psDlistGetPrev(psDlist *list); 1081 \end{verbatim} 1082 The first of these functions uses the value of \code{where} to set the 1083 iteration cursor for the given list to the beginning 1084 \code{PS_DLIST_HEAD} or the end \code{PS_DLIST_TAIL}. The next two 1085 functions move the iteration cursor forward or backwards, returning 1086 the data item from the resulting list entry, or returning \code{NULL} 1087 at the end of the list. Explicit traversal of the list using the 1088 \code{psDlistElem}s \code{prev} and \code{next} pointers is also 1089 supported. 1128 1090 1129 1091 \subsection{Hash Tables} 1130 1092 \hlabel{psHash} 1131 1093 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.} 1094 Hash tables are critical for quick retrieval of text-based data. The 1095 concept is as follows: Given a large collection of text strings, it is 1096 inefficient to search for a particular entry by performing a basic 1097 string comparison on all entries until a match is found. Even if a 1098 single list is sorted, we will still spend a substantial amount of 1099 time iterating across the entries in the list. In a hash table, we 1100 define an operation, the hash function, which uses the bytes of the 1101 string to construct a numerical value, the hash value. The hash value 1102 is defined to have a limited range of $N$ values. The hash table 1103 consists of $N$ buckets, each of which contains a list of the strings 1104 whose hash value corresponds to the bucket number. Searching for a 1105 specific string involves calculating the hash value for the string, 1106 going to the appropriate bucket, and searching through the 1107 corresponding list until the string is matched. 1108 1109 For 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 1112 table at any one time.} 1113 % 1114 \begin{verbatim} 1115 typedef struct { 1116 int nbucket; // number of buckets 1117 psHashBucket **buckets; // the buckets themselves 1118 } psHash; 1119 \end{verbatim} 1120 % 1121 where \code{nbucket} is the number of buckets defined for the hash 1122 functions, and \code{buckets} are the individual buckets, each of 1123 which is defined by: 1124 % 1125 \begin{verbatim} 1126 typedef 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} 1132 where each bucket contains the value of the \code{key}, a pointer to 1133 the \code{data}, and a pointer to the \code{next} list entry in the 1134 bucket. 1135 1136 A hash table is created with the following function: 1137 \begin{verbatim} 1138 psHash *psHashAlloc(int nbucket); 1139 \end{verbatim} 1140 which allocates the space for the hash table and initializes all of 1141 the buckets. \tbd{why specify nbucket? isn't it set by the hash 1142 function?}. 1143 1144 A data item may be added to the hash table with the function: 1145 \begin{verbatim} 1146 void *psHashInsert(psHash *table, char *key, void *data, void (*itemFree)(void *item)); 1147 \end{verbatim} 1148 In this function, the value of the string \code{key} is used to 1149 construct the hash value, find the appropriate bucket set, and add the 1150 new element \code{data} to the list. The element destructor, 1151 \code{itemFree}, is provided to destroy an existing element with the 1152 same value of \code{key}. The routine \code{psHashInsert} must 1153 provide a non-NULL \code{itemFree} argument if it wishes to change the 1154 value for previously inserted keys; if \code{itemFree} is NULL 1155 attempting to insert a pre-existing key is an error, and the routine 1156 will return NULL. If \code{psHashInsert} succeeds it returns 1157 \code{data}. 1158 1159 The data associated with a given key may be found with the function: 1160 \begin{verbatim} 1161 void *psHashLookup(psHash *table, char *key); 1162 \end{verbatim} 1163 which 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, 1165 a specific key may be removed (deleted) with the function: 1166 \begin{verbatim} 1167 void *psHashRemove(psHash *table, char *key); 1168 \end{verbatim} 1169 \tbd{what is return value?} 1170 1171 A complete hash table may be freed by calling: 1172 \begin{verbatim} 1173 void psHashFree(psHash *table, void (*itemFree)(void *item)); 1174 \end{verbatim} 1175 where the function \code{itemFree} is provided to delete the 1176 individual elements in the table. If it is NULL this is the 1177 responsibility of the caller. 1178 1179 The function 1180 \begin{verbatim} 1181 psDlist *psHashKeylist(psHast *table); 1182 \end{verbatim} 1183 returns the complete list of defined keys associated with the psHash 1184 table as a linked list. 1191 1185 1192 1186 \section{Data manipulation}
Note:
See TracChangeset
for help on using the changeset viewer.
