/* Public domain */ #ifndef _MAILBLOCKD_TABLE_H_ #define _MAILBLOCKD_TABLE_H_ #define TABLE_MAX_FIELDS 8 #define TABLE_NBUCKETS_INIT 64 typedef struct tbl_entry { char *key; u_int count; /* Number of tests */ float scoreAvg; /* Average score */ float scoreTot; /* Total score */ long stamp; /* Timestamp */ SLIST_ENTRY(tbl_entry) bents; } TBL_Entry; typedef struct tbl_bucket { SLIST_HEAD(,tbl_entry) ents; unsigned int nents; } TBL_Bucket; typedef struct tbl { char *path; /* Pathname */ TBL_Bucket *buckets; /* Hash table */ u_int nbuckets; /* Number of buckets */ u_int count; /* Number of entries */ } TBL; __BEGIN_DECLS void TBL_Init(TBL *, const char *, u_int); TBL *TBL_Load(const char *, u_int); int TBL_Save(TBL *, const char *, mode_t); int TBL_SaveFD(TBL *, int); int TBL_Rehash(TBL **, u_int); void TBL_Destroy(TBL *); TBL_Entry *TBL_Insert(TBL *, u_int, const char *); void TBL_DeleteEntry(TBL *, u_int, TBL_Entry *); int TBL_Delete(TBL *, const char *); static __inline__ u_int TBL_Hash(TBL *t, const char *key) { u_int h; u_char *p; for (h = 0, p = (u_char *)key; *p != '\0'; p++) { h = 31 * h + *p; } return (h % t->nbuckets); } /* Look up a named table entry. */ static __inline__ TBL_Entry * TBL_LookupHash(TBL *ta, const char *key, u_int h) { TBL_Entry *ent; SLIST_FOREACH(ent, &ta->buckets[h].ents, bents) { if (strcmp(key, ent->key) == 0) break; } return (ent); } static __inline__ int TBL_Lookup(TBL *ta, const char *key, TBL_Entry **pEnt) { TBL_Entry *tent; if ((tent = TBL_LookupHash(ta, key, TBL_Hash(ta,key))) == NULL) { return (-1); } if (pEnt != NULL) { *pEnt = tent; } return (0); } __END_DECLS #endif /* _MAILBLOCKD_TABLE_H_ */