This is Unofficial EPICS BASE Doxygen Site
gpHash.h File Reference
#include "libComAPI.h"
#include "ellLib.h"
+ Include dependency graph for gpHash.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  GPHENTRY
 

Functions

LIBCOM_API void epicsStdCall gphInitPvt (struct gphPvt **ppvt, int tableSize)
 
LIBCOM_API GPHENTRY *epicsStdCall gphFind (struct gphPvt *pvt, const char *name, void *pvtid)
 
LIBCOM_API GPHENTRY *epicsStdCall gphFindParse (struct gphPvt *pvt, const char *name, size_t len, void *pvtid)
 
LIBCOM_API GPHENTRY *epicsStdCall gphAdd (struct gphPvt *pvt, const char *name, void *pvtid)
 
LIBCOM_API void epicsStdCall gphDelete (struct gphPvt *pvt, const char *name, void *pvtid)
 
LIBCOM_API void epicsStdCall gphFreeMem (struct gphPvt *pvt)
 
LIBCOM_API void epicsStdCall gphDump (struct gphPvt *pvt)
 
LIBCOM_API void epicsStdCall gphDumpFP (FILE *fp, struct gphPvt *pvt)
 

Function Documentation

LIBCOM_API GPHENTRY* epicsStdCall gphAdd ( struct gphPvt pvt,
const char *  name,
void *  pvtid 
)

Definition at line 97 of file gpHashLib.c.

98 {
99  ELLLIST **paplist;
100  ELLLIST *plist;
101  GPHENTRY *pgphNode;
102  int hash;
103 
104  if (pgphPvt == NULL) return NULL;
105  paplist = pgphPvt->paplist;
106  hash = epicsMemHash((char *)&pvtid, sizeof(void *), 0);
107  hash = epicsStrHash(name, hash) & pgphPvt->mask;
108 
109  epicsMutexMustLock(pgphPvt->lock);
110  plist = paplist[hash];
111  if (plist == NULL) {
112  plist = calloc(1, sizeof(ELLLIST));
113  if(!plist){
114  epicsMutexUnlock(pgphPvt->lock);
115  return NULL;
116  }
117  ellInit(plist);
118  paplist[hash] = plist;
119  }
120 
121  pgphNode = (GPHENTRY *) ellFirst(plist);
122  while (pgphNode) {
123  if (pvtid == pgphNode->pvtid &&
124  strcmp(name, pgphNode->name) == 0) {
125  epicsMutexUnlock(pgphPvt->lock);
126  return NULL;
127  }
128  pgphNode = (GPHENTRY *) ellNext((ELLNODE *)pgphNode);
129  }
130 
131  pgphNode = calloc(1, sizeof(GPHENTRY));
132  if(pgphNode) {
133  pgphNode->name = name;
134  pgphNode->pvtid = pvtid;
135  ellAdd(plist, (ELLNODE *)pgphNode);
136  }
137 
138  epicsMutexUnlock(pgphPvt->lock);
139  return (pgphNode);
140 }
unsigned int epicsStrHash(const char *str, unsigned int seed)
Definition: epicsString.c:356
char * name
Definition: flexdef.h:287
#define NULL
Definition: catime.c:38
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
Release the semaphore.
Definition: epicsMutex.cpp:140
void ellAdd(ELLLIST *pList, ELLNODE *pNode)
Adds a node to the end of a list.
Definition: ellLib.c:24
#define ellNext(PNODE)
Find the next node in list.
Definition: ellLib.h:99
List node type.
Definition: ellLib.h:45
unsigned int epicsMemHash(const char *str, size_t length, unsigned int seed)
Definition: epicsString.c:369
#define ellInit(PLIST)
Initialize a list type.
Definition: ellLib.h:76
void * pvtid
Definition: gpHash.h:24
const char * name
Definition: gpHash.h:23
List header type.
Definition: ellLib.h:56
#define epicsMutexMustLock(ID)
Claim a semaphore (see epicsMutexLock()).
Definition: epicsMutex.h:214
#define ellFirst(PLIST)
Find the first node in list.
Definition: ellLib.h:89
LIBCOM_API void epicsStdCall gphDelete ( struct gphPvt pvt,
const char *  name,
void *  pvtid 
)

Definition at line 142 of file gpHashLib.c.

143 {
144  ELLLIST **paplist;
145  ELLLIST *plist = NULL;
146  GPHENTRY *pgphNode;
147  int hash;
148 
149  if (pgphPvt == NULL) return;
150  paplist = pgphPvt->paplist;
151  hash = epicsMemHash((char *)&pvtid, sizeof(void *), 0);
152  hash = epicsStrHash(name, hash) & pgphPvt->mask;
153 
154  epicsMutexMustLock(pgphPvt->lock);
155  if (paplist[hash] == NULL) {
156  pgphNode = NULL;
157  } else {
158  plist = paplist[hash];
159  pgphNode = (GPHENTRY *) ellFirst(plist);
160  }
161 
162  while(pgphNode) {
163  if (pvtid == pgphNode->pvtid &&
164  strcmp(name, pgphNode->name) == 0) {
165  ellDelete(plist, (ELLNODE*)pgphNode);
166  free((void *)pgphNode);
167  break;
168  }
169  pgphNode = (GPHENTRY *) ellNext((ELLNODE*)pgphNode);
170  }
171 
172  epicsMutexUnlock(pgphPvt->lock);
173  return;
174 }
unsigned int epicsStrHash(const char *str, unsigned int seed)
Definition: epicsString.c:356
char * name
Definition: flexdef.h:287
#define NULL
Definition: catime.c:38
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
Release the semaphore.
Definition: epicsMutex.cpp:140
#define ellNext(PNODE)
Find the next node in list.
Definition: ellLib.h:99
List node type.
Definition: ellLib.h:45
unsigned int epicsMemHash(const char *str, size_t length, unsigned int seed)
Definition: epicsString.c:369
void * pvtid
Definition: gpHash.h:24
const char * name
Definition: gpHash.h:23
List header type.
Definition: ellLib.h:56
#define epicsMutexMustLock(ID)
Claim a semaphore (see epicsMutexLock()).
Definition: epicsMutex.h:214
void ellDelete(ELLLIST *pList, ELLNODE *pNode)
Deletes a node from a list.
Definition: ellLib.c:75
#define ellFirst(PLIST)
Find the first node in list.
Definition: ellLib.h:89
LIBCOM_API void epicsStdCall gphDump ( struct gphPvt pvt)

Definition at line 206 of file gpHashLib.c.

207 {
208  gphDumpFP(stdout, pgphPvt);
209 }
void epicsStdCall gphDumpFP(FILE *fp, gphPvt *pgphPvt)
Definition: gpHashLib.c:211
#define stdout
Definition: epicsStdio.h:30
LIBCOM_API void epicsStdCall gphDumpFP ( FILE *  fp,
struct gphPvt pvt 
)

Definition at line 211 of file gpHashLib.c.

212 {
213  unsigned int empty = 0;
214  ELLLIST **paplist;
215  int h;
216 
217  if (pgphPvt == NULL)
218  return;
219 
220  fprintf(fp, "Hash table has %d buckets", pgphPvt->size);
221 
222  paplist = pgphPvt->paplist;
223  for (h = 0; h < pgphPvt->size; h++) {
224  ELLLIST *plist = paplist[h];
225  GPHENTRY *pgphNode;
226  int i = 0;
227 
228  if (plist == NULL) {
229  empty++;
230  continue;
231  }
232  pgphNode = (GPHENTRY *) ellFirst(plist);
233 
234  fprintf(fp, "\n [%3d] %3d ", h, ellCount(plist));
235  while (pgphNode) {
236  if (!(++i % 3))
237  fprintf(fp, "\n ");
238  fprintf(fp, " %s %p", pgphNode->name, pgphNode->pvtid);
239  pgphNode = (GPHENTRY *) ellNext((ELLNODE*)pgphNode);
240  }
241  }
242  fprintf(fp, "\n%u buckets empty.\n", empty);
243 }
epics::pvData::BitSetPtr empty
Definition: pvAccess.cpp:135
#define ellCount(PLIST)
Report the number of nodes in a list.
Definition: ellLib.h:84
int i
Definition: scan.c:967
#define NULL
Definition: catime.c:38
#define ellNext(PNODE)
Find the next node in list.
Definition: ellLib.h:99
List node type.
Definition: ellLib.h:45
void * pvtid
Definition: gpHash.h:24
const char * name
Definition: gpHash.h:23
List header type.
Definition: ellLib.h:56
#define ellFirst(PLIST)
Find the first node in list.
Definition: ellLib.h:89
LIBCOM_API GPHENTRY* epicsStdCall gphFind ( struct gphPvt pvt,
const char *  name,
void *  pvtid 
)

Definition at line 92 of file gpHashLib.c.

93 {
94  return gphFindParse(pgphPvt, name, strlen(name), pvtid);
95 }
char * name
Definition: flexdef.h:287
GPHENTRY *epicsStdCall gphFindParse(gphPvt *pgphPvt, const char *name, size_t len, void *pvtid)
Definition: gpHashLib.c:61
LIBCOM_API GPHENTRY* epicsStdCall gphFindParse ( struct gphPvt pvt,
const char *  name,
size_t  len,
void *  pvtid 
)

Definition at line 61 of file gpHashLib.c.

62 {
63  ELLLIST **paplist;
64  ELLLIST *gphlist;
65  GPHENTRY *pgphNode;
66  int hash;
67 
68  if (pgphPvt == NULL) return NULL;
69  paplist = pgphPvt->paplist;
70  hash = epicsMemHash((char *)&pvtid, sizeof(void *), 0);
71  hash = epicsMemHash(name, len, hash) & pgphPvt->mask;
72 
73  epicsMutexMustLock(pgphPvt->lock);
74  gphlist = paplist[hash];
75  if (gphlist == NULL) {
76  pgphNode = NULL;
77  } else {
78  pgphNode = (GPHENTRY *) ellFirst(gphlist);
79  }
80 
81  while (pgphNode) {
82  if (pvtid == pgphNode->pvtid &&
83  strlen(pgphNode->name) == len &&
84  strncmp(name, pgphNode->name, len) == 0) break;
85  pgphNode = (GPHENTRY *) ellNext((ELLNODE *)pgphNode);
86  }
87 
88  epicsMutexUnlock(pgphPvt->lock);
89  return pgphNode;
90 }
char * name
Definition: flexdef.h:287
#define NULL
Definition: catime.c:38
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
Release the semaphore.
Definition: epicsMutex.cpp:140
#define ellNext(PNODE)
Find the next node in list.
Definition: ellLib.h:99
List node type.
Definition: ellLib.h:45
unsigned int epicsMemHash(const char *str, size_t length, unsigned int seed)
Definition: epicsString.c:369
void * pvtid
Definition: gpHash.h:24
const char * name
Definition: gpHash.h:23
List header type.
Definition: ellLib.h:56
#define epicsMutexMustLock(ID)
Claim a semaphore (see epicsMutexLock()).
Definition: epicsMutex.h:214
#define ellFirst(PLIST)
Find the first node in list.
Definition: ellLib.h:89
LIBCOM_API void epicsStdCall gphFreeMem ( struct gphPvt pvt)

Definition at line 176 of file gpHashLib.c.

177 {
178  ELLLIST **paplist;
179  int h;
180 
181  /* Caller must ensure that no other thread is using *pvt */
182  if (pgphPvt == NULL) return;
183 
184  paplist = pgphPvt->paplist;
185  for (h = 0; h < pgphPvt->size; h++) {
186  ELLLIST *plist = paplist[h];
187  GPHENTRY *pgphNode;
188  GPHENTRY *next;
189 
190  if (plist == NULL) continue;
191  pgphNode = (GPHENTRY *) ellFirst(plist);
192 
193  while (pgphNode) {
194  next = (GPHENTRY *) ellNext((ELLNODE*)pgphNode);
195  ellDelete(plist, (ELLNODE*)pgphNode);
196  free(pgphNode);
197  pgphNode = next;
198  }
199  free(paplist[h]);
200  }
201  epicsMutexDestroy(pgphPvt->lock);
202  free(paplist);
203  free(pgphPvt);
204 }
void epicsStdCall epicsMutexDestroy(epicsMutexId pmutexNode)
Destroy an epicsMutex semaphore.
Definition: epicsMutex.cpp:127
struct hash_entry * next
Definition: flexdef.h:286
#define NULL
Definition: catime.c:38
#define ellNext(PNODE)
Find the next node in list.
Definition: ellLib.h:99
List node type.
Definition: ellLib.h:45
List header type.
Definition: ellLib.h:56
void ellDelete(ELLLIST *pList, ELLNODE *pNode)
Deletes a node from a list.
Definition: ellLib.c:75
#define ellFirst(PLIST)
Find the first node in list.
Definition: ellLib.h:89
LIBCOM_API void epicsStdCall gphInitPvt ( struct gphPvt **  ppvt,
int  tableSize 
)

Definition at line 37 of file gpHashLib.c.

38 {
39  gphPvt *pgphPvt;
40 
41  if (size & (size - 1)) {
42  fprintf(stderr, "gphInitPvt: %d is not a power of 2\n", size);
43  size = DEFAULT_SIZE;
44  }
45 
46  if (size < MIN_SIZE)
47  size = MIN_SIZE;
48 
49  if (size > MAX_SIZE)
50  size = MAX_SIZE;
51 
52  pgphPvt = callocMustSucceed(1, sizeof(gphPvt), "gphInitPvt");
53  pgphPvt->size = size;
54  pgphPvt->mask = size - 1;
55  pgphPvt->paplist = callocMustSucceed(size, sizeof(ELLLIST *), "gphInitPvt");
56  pgphPvt->lock = epicsMutexMustCreate();
57  *ppvt = pgphPvt;
58  return;
59 }
epicsMutexId lock
Definition: gpHashLib.c:29
ELLLIST ** paplist
Definition: gpHashLib.c:28
int size
Definition: gpHashLib.c:26
#define epicsMutexMustCreate()
Create an epicsMutex semaphore for use from C code.
Definition: epicsMutex.h:179
#define MAX_SIZE
Definition: gpHashLib.c:34
#define MIN_SIZE
Definition: gpHashLib.c:32
#define DEFAULT_SIZE
Definition: gpHashLib.c:33
LIBCOM_API void * callocMustSucceed(size_t count, size_t size, const char *msg)
A calloc() that never returns NULL.
Definition: cantProceed.c:22
#define stderr
Definition: epicsStdio.h:32
unsigned int mask
Definition: gpHashLib.c:27
List header type.
Definition: ellLib.h:56