1 // ================================================================ 2 // Reusable singly linked list of string, with tail for append. 3 // 4 // Unlike slls which frees all memory on the destructor, this rslls class is 5 // designed to be reusable: there is a reset method which doesn't free all node 6 // structures. The context is the CSV-reader which extends a singly linked 7 // list for every data line. Now, all CSV lines have nominally the same number 8 // of fields (say N), so using slls, the CSV reader would be allocating and 9 // freeing N nodes on every line. Mingled in with other mallocs and frees, this 10 // results in needless heap fragmentation. Here, by contrast, as a performance 11 // optimization, the CSV reader can keep and reuse the nodes of a list, only 12 // changing the value-pointers on each CSV line. 13 // 14 // This means that while an slls iteration looks like 15 // 16 // for (sllse_t* pe = plist->phead; pe != NULL; pe = pe->pnext) { 17 // ... 18 // } 19 // 20 // an rslls iteration must also check length: 21 // 22 // unsigned long long i = 0; 23 // for (rsllse_t* pe = plist->phead; i < plist->length && pe != NULL; pe = pe->pnext, i++) { 24 // ... 25 // } 26 // 27 // ================================================================ 28 29 #ifndef RSLLS_H 30 #define RSLLS_H 31 32 #include <stdio.h> 33 #include "lib/free_flags.h" 34 35 typedef struct _rsllse_t { 36 char* value; 37 char free_flag; 38 char quote_flag; 39 struct _rsllse_t *pnext; 40 } rsllse_t; 41 42 typedef struct _rslls_t { 43 rsllse_t *phead; 44 rsllse_t *ptail; 45 unsigned long long length; 46 } rslls_t; 47 48 rslls_t* rslls_alloc(); 49 void rslls_reset(rslls_t* plist); 50 void rslls_free(rslls_t* plist); 51 void rslls_append(rslls_t* plist, char* value, char free_flag, char quote_flag); 52 53 void rslls_print(rslls_t* plist); 54 55 #endif // RSLLS_H 56