Changeset 179 for trunk/doc/draft/utils.tex
- Timestamp:
- Mar 9, 2004, 3:07:27 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/doc/draft/utils.tex (modified) (23 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/doc/draft/utils.tex
r139 r179 58 58 The \PS{} software system will need a level of memory management 59 59 placed between the operating system (malloc/free) and the high level 60 routines (e.g. \code{psMetaData New}).60 routines (e.g. \code{psMetaDataAlloc}). 61 61 62 62 This layer is in addition to the possibility that specific heavily 63 63 used data types may need their own special-purpose memory managers; 64 64 but as we have specified that all user-level objects be allocated via 65 \code{type New/typeDel} functions, we will easily be able to65 \code{typeAlloc/typeFree} functions, we will easily be able to 66 66 implement such functionality without impacting on the facilities 67 67 described here. … … 69 69 All of the memory management APIs should be provided in a header file 70 70 \file{psMemory.h} which is included by \file{psUtils.h}. 71 72 \textit{Do we want to rename \code{psAlloc} to \code{psNew} and73 \code{psFree} to \code{psDel}? Or is it too late? XXX}74 71 75 72 \subsection{Rationale} … … 92 89 We need to provide a mechanism for tracking and fixing memory 93 90 leaks. While it is possible to do this by linking with external 94 libraries ( XXX reference), it is convenient to do so within the91 libraries (\tbd{reference}), it is convenient to do so within the 95 92 \PS{} framework. 96 93 … … 376 373 } psSimple; 377 374 378 psSimple *psSimple New(const char *name, int val)375 psSimple *psSimpleAlloc(const char *name, int val) 379 376 { 380 377 psSimple *simp = psAlloc(sizeof(psSimple)); … … 385 382 } 386 383 387 void psSimple Del(psSimple *simp)384 void psSimpleFree(psSimple *simp) 388 385 { 389 386 if (simp == NULL) { return; } … … 411 408 \goodbreak 412 409 \begin{verbatim} 413 simp = psSimple New("RHL", 0);410 simp = psSimpleAlloc("RHL", 0); 414 411 psDlistAppend(list1, psMemIncrRefCounter(simp)); 415 412 psDlistAppend(list2, psMemIncrRefCounter(simp)); 416 psSimple Del(simp);413 psSimpleFree(simp); 417 414 \end{verbatim} 418 415 … … 447 444 int level); // desired trace level 448 445 int psGetTraceLevel(const char *name); // facilty of interest 446 447 void psTraceReset(void); // turn off all tracing, and free trace's allocated memory 449 448 450 449 void psPrintTraceLevels(void); // print trace levels … … 513 512 within the functions that implement \file{psTrace.h} 514 513 or \file{psMemory.h} systems. 514 515 \item 516 \code{psTraceReset} shall reset all tracing to the state that it 517 had at program initiation, including freeing any memory that the 518 tracing subsystem may have allocated. 515 519 \end{itemize} 516 520 … … 581 585 582 586 int psSetLogDestination(int dest); 587 void psSetLogFormat(const char *fmt); 588 583 589 int psSetLogLevel(int level); 584 590 \end{verbatim} … … 634 640 write to \code{stderr} and \code{stdout} respectively. 635 641 636 \section{The Pan-STARRS \texttt{psDlist} doubly-linked list type} 642 The fields included in the log message may be controlled using \code{psSetLogFormat} which 643 expects a string consisting of the letters \code{H} (host), \code{L} (level), \code{M} (message), 644 \code{N} (name), and \code{T} (time). The default is \code{HLMNT}. 645 646 \section{The Pan-STARRS \code{psDlist} doubly-linked list type} 637 647 \hlabel{psDlist} 638 648 … … 667 677 668 678 \begin{verbatim} 669 psDlist *psDlist New(void *data); // initial data item; may be NULL670 671 void psDlist Del(psDlist *list, // list to destroy672 void (*elem Del)(void *)); // destructor for list data, or NULL679 psDlist *psDlistAlloc(void *data); // initial data item; may be NULL 680 681 void psDlistFree(psDlist *list, // list to destroy 682 void (*elemFree)(void *)); // destructor for list data, or NULL 673 683 674 684 /* … … 702 712 their reference counter. 703 713 704 If \code{psDlist Del}'s argument \code{elemDel} is NULL, the714 If \code{psDlistFree}'s argument \code{elemFree} is NULL, the 705 715 list should be deleted, but not the elements on it (although their 706 716 \code{refcounter}'s should be decremented). 707 717 708 The \code{psDlistGet} routine may be used to provide an iterator. The 709 call \code{psDlistGet(list, psDlistHead)} returns the data from the 710 head link of the list, but also sets the iteration cursor to the head. 711 A seried of calls to \code{psDlistGet(list, psDlistNext)} return the 712 elements of the list in order (you may also use \code{psDlistTail} and 713 \code{psDlistPrev} to traverse the list backwards). 718 Iteration over all elements of the list is provided by the functions: 719 \begin{verbatim} 720 void psDlistSetIterator(psDlist *list, int where, int which); 721 void *psDlistGetNext(psDlist *list, int which); 722 void *psDlistGetPrev(psDlist *list, int which); 723 \end{verbatim} 724 in which the \code{where} argument must be \code{PS_DLIST_HEAD} or \code{PS_DLIST_TAIL}, 725 to start at the head or tail of the list, and \code{psDlistGetNext} and \code{psDlistGetPrev} 726 return the next/previous element. The argument \code{which} identifies which of potentially 727 many iteration cursors should be used; it must currently always be \code{0}. 714 728 715 729 Explicit traversal of the list using the \code{psDlistElem}'s … … 746 760 with associated constructors and a destructor: 747 761 \begin{verbatim} 748 psTypeArray *psType New(int n, int size);762 psTypeArray *psTypeAlloc(int n, int size); 749 763 psTypeArray *psTypeRealloc(psTypeArray *arr, int n); 750 void psType Del(psTypeArray *arr);764 void psTypeFree(psTypeArray *arr); 751 765 \end{verbatim} 752 766 … … 760 774 and declares the prototypes (and is thus suitable for use in a 761 775 header file); the latter generates the code for the three functions 762 \code{psType( New|Realloc|Del} (and should thus appear in exactly one776 \code{psType(Alloc|Realloc|Free} (and should thus appear in exactly one 763 777 source file for a given type). 764 778 … … 772 786 contains an array of \code{psType}s not 773 787 pointers to \code{psType}s; this means that the individual elements are 774 not allocated using \code{psType New}, are not correctly initialized,775 and shouldn't be individually deleted with \code{psType Del};788 not allocated using \code{psTypeAlloc}, are not correctly initialized, 789 and shouldn't be individually deleted with \code{psTypeFree}; 776 790 777 791 If you wish to use arrays of pointers, use the macros … … 788 802 with associated constructors and a destructor: 789 803 \begin{verbatim} 790 psTypePtrArray *psTypePtr New(int n, int size);804 psTypePtrArray *psTypePtrAlloc(int n, int size); 791 805 psTypePtrArray *psTypePtrRealloc(psTypePtrArray *arr, int n); 792 void psTypePtrArray Del(psTypePtrArray *arr);806 void psTypePtrArrayFree(psTypePtrArray *arr); 793 807 \end{verbatim} 794 808 795 809 These constructors create arrays of \code{psType *} and call 796 \code{psType New} and \code{psTypeDel} to allocate and free the810 \code{psTypeAlloc} and \code{psTypeFree} to allocate and free the 797 811 elements. As for the simple arrays, The former defines the typedef and 798 812 declares the prototypes (and is thus suitable for use in a header 799 813 file) and the latter generates the code for the three functions 800 \code{psType( New|Realloc|Del} (and should thus appear in exactly one814 \code{psType(Alloc|Realloc|Free} (and should thus appear in exactly one 801 815 source file for a given type). 802 816 … … 805 819 need to say something like: 806 820 \begin{verbatim} 807 psTypePtrArray *pt = psTypePtrArray New(10, 10);821 psTypePtrArray *pt = psTypePtrArrayAlloc(10, 10); 808 822 psType *xy = psMemDecrRefCounter(pt->arr[0]); 809 823 pt->arr[0] = NULL; 810 824 \end{verbatim} 811 825 812 \subsubsection{Arrays of \ texttt{void *}}826 \subsubsection{Arrays of \code{void *}} 813 827 \hlabel{secArrayVoidPtr} 814 828 … … 825 839 except that its destructor is specified as: 826 840 \begin{verbatim} 827 void psVoidPtrArray Del(psVoidPtrArray *arr, // array to destroy828 void (*elem Del)(void *)); // destructor for array data829 \end{verbatim} 830 831 The routine \code{psVoidPtrArray Del} assumes that all pointers841 void psVoidPtrArrayFree(psVoidPtrArray *arr, // array to destroy 842 void (*elemFree)(void *)); // destructor for array data 843 \end{verbatim} 844 845 The routine \code{psVoidPtrArrayFree} assumes that all pointers 832 846 had their reference counters incremented 833 847 when they were inserted onto the array.\footnote{% 834 848 \eg{} \code{va->arr[i] = psMemIncrRefCounter(ptr);}} 835 849 836 If \code{psVoidPtrArray Del}'s argument \code{elemDel} is NULL, the850 If \code{psVoidPtrArrayFree}'s argument \code{elemFree} is NULL, the 837 851 list should be deleted, but not the elements on it (although their 838 852 \code{refcounter}'s should be decremented). … … 849 863 } psXY; 850 864 851 psXY *psXY New(void)865 psXY *psXYAlloc(void) 852 866 { 853 867 return psAlloc(sizeof(psXY)); 854 868 } 855 869 856 void psXY Del(psXY *xy)870 void psXYFree(psXY *xy) 857 871 { 858 872 psFree(xy); … … 867 881 int main(void) 868 882 { 869 psXYArray *t = psXYArray New(10, 15);870 psXYPtrArray *pt = psXYPtrArray New(10, 10);883 psXYArray *t = psXYArrayAlloc(10, 15); 884 psXYPtrArray *pt = psXYPtrArrayAlloc(10, 10); 871 885 872 886 for (int i = 0; i < t->n; i++) { … … 883 897 printf("\n"); 884 898 885 psXYArray Del(t);899 psXYArrayFree(t); 886 900 887 901 psXY *xy = psMemDecrRefCounter(pt->arr[0]); 888 902 pt->arr[0] = NULL; 889 psXY Del(xy);903 psXYFree(xy); 890 904 891 psXYPtrArray Del(pt);905 psXYPtrArrayFree(pt); 892 906 893 907 psMemCheckLeaks(0, NULL, stderr); … … 904 918 typedef struct HashTable psHash; 905 919 906 psHash *psHashNew(int nbucket); // initial number of buckets 907 void psHashDel(psHash *table, // hash table to be freed 908 void (*itemDel)(void *item)); // how to free hashed data; 909 // or NULL 910 911 void *psHashInsert(psHash *table, // table to insert in 912 const char *key, // key to use 913 void *data, // data to insert 914 void (*itemDel)(void *item)); // how to free hashed data; 915 // or NULL 916 void *psHashLookup(psHash *table, // table to lookup key in 917 const char *key); // key to lookup 920 psHash *psHashAlloc(int nbucket); // initial number of buckets 921 void psHashFree(psHash *table, // hash table to be freed 922 void (*itemFree)(void *item)); // how to free hashed data; 923 // or NULL 924 925 void *psHashInsert(psHash *table, // table to insert in 926 const char *key, // key to use 927 void *data, // data to insert 928 void (*itemFree)(void *item)); // how to free hashed data; 929 // or NULL 930 void *psHashLookup(psHash *table, // table to lookup key in 931 const char *key); // key to lookup 932 933 void *psHashRemove(psHash *table, // table to lookup key in 934 const char *key); // key to lookup 918 935 \end{verbatim} 919 936 \begin{caption}{The public API for hash tables from \file{psHash.h}} … … 926 943 is included by \file{psUtils.h}. 927 944 \footnote{ 928 We choose not to use the posix function \ texttt{hcreate},929 \ texttt{hdestroy}, and \code{hsearch} as they only support945 We choose not to use the posix function \code{hcreate}, 946 \code{hdestroy}, and \code{hsearch} as they only support 930 947 a single hash table at any one time.} 931 948 932 A hash table is an abstract type \ texttt{psHash}. The argument933 \ texttt{nbucket} to \texttt{psHashNew} is a non-binding suggestion949 A hash table is an abstract type \code{psHash}. The argument 950 \code{nbucket} to \code{psHashAlloc} is a non-binding suggestion 934 951 from the user for the initial size of the hash table. 935 952 936 If the \ texttt{itemDel} argument to \texttt{psHashDel} is non-NULL,953 If the \code{itemFree} argument to \code{psHashFree} is non-NULL, 937 954 it will be used to delete the data items that have been stored 938 955 in the hash table; if it is NULL this is the responsibility of 939 956 the caller. 940 957 941 The routine \ texttt{psHashInsert} must provide a non-NULL \texttt{itemDel}958 The routine \code{psHashInsert} must provide a non-NULL \code{itemFree} 942 959 argument if it wishes to change the value previously inserted keys; 943 if \ texttt{itemDel} is NULL attempting to insert a pre-existing key944 is an error, and the routine will return NULL. If \ texttt{psHashInsert}945 succeeds it returns \ texttt{data}.946 947 \ texttt{psHashLookup} returns the \texttt{data} associated with the960 if \code{itemFree} is NULL attempting to insert a pre-existing key 961 is an error, and the routine will return NULL. If \code{psHashInsert} 962 succeeds it returns \code{data}. 963 964 \code{psHashLookup} returns the \code{data} associated with the 948 965 key, or NULL if the key's invalid. 966 967 \code{psHashRemove} removes the entry associated with the 968 key from the table, and returns the \code{data}; if the key's invalid it returns NULL. 949 969 950 970 \section{Miscellaneous Utilities}
Note:
See TracChangeset
for help on using the changeset viewer.
