/** * Initialize hash table. * * @param range initial size of index range. Value of 0 will use default value, DEFAULT_INDEX_RANGE; * @param options combination of initialization options. * * @return a pointer of malloced qhashtbl_t, otherwise returns NULL. * @retval errno will be set in error condition. * - ENOMEM : Memory allocation failure. * * @code * // create a hash-table. * qhashtbl_t *basic_hashtbl = qhashtbl(0, 0); * * // create a large hash-table for millions of keys with thread-safe option. * qhashtbl_t *small_hashtbl = qhashtbl(1000000, QHASHTBL_THREADSAFE); * @endcode * * @note * Setting the right range is a magic. * In practice, pick a value between (total keys / 3) ~ (total keys * 2). * Available options: * - QHASHTBL_THREADSAFE - make it thread-safe. */ qhashtbl_t *qhashtbl(size_t range, int options) { if (range == 0) { range = DEFAULT_INDEX_RANGE; } qhashtbl_t *tbl = (qhashtbl_t *) calloc(1, sizeof(qhashtbl_t)); if (tbl == NULL) goto malloc_failure; // allocate table space tbl->slots = (qhashtbl_obj_t **) calloc(range, sizeof(qhashtbl_obj_t *)); if (tbl->slots == NULL) goto malloc_failure; // handle options. if (options & QHASHTBL_THREADSAFE) { Q_MUTEX_NEW(tbl->qmutex, true); if (tbl->qmutex == NULL) goto malloc_failure; } // assign methods tbl->put = qhashtbl_put; tbl->putstr = qhashtbl_putstr; tbl->putstrf = qhashtbl_putstrf; tbl->putint = qhashtbl_putint; tbl->get = qhashtbl_get; tbl->getstr = qhashtbl_getstr; tbl->getint = qhashtbl_getint; tbl->remove = qhashtbl_remove; tbl->getnext = qhashtbl_getnext; tbl->size = qhashtbl_size; tbl->clear = qhashtbl_clear; tbl->debug = qhashtbl_debug; tbl->lock = qhashtbl_lock; tbl->unlock = qhashtbl_unlock; tbl->free = qhashtbl_free; // set table range. tbl->range = range; return tbl; malloc_failure: errno = ENOMEM; if (tbl) { assert(tbl->qmutex == NULL); qhashtbl_free(tbl); } return NULL; }
/** * Create new qlist_t linked-list container * * @param options combination of initialization options. * * @return a pointer of malloced qlist_t container, otherwise returns NULL. * @retval errno will be set in error condition. * -ENOMEM : Memory allocation failure. * * @code * qlist_t *list = qlist(0); * @endcode * * @note * Available options: * - QLIST_THREADSAFE - make it thread-safe. */ qlist_t *qlist(int options) { qlist_t *list = (qlist_t *) calloc(1, sizeof(qlist_t)); if (list == NULL) { errno = ENOMEM; return NULL; } // handle options. if (options & QLIST_THREADSAFE) { Q_MUTEX_NEW(list->qmutex, true); if (list->qmutex == NULL) { errno = ENOMEM; free(list); return NULL; } } // member methods list->setsize = qlist_setsize; list->addfirst = qlist_addfirst; list->addlast = qlist_addlast; list->addat = qlist_addat; list->getfirst = qlist_getfirst; list->getlast = qlist_getlast; list->getat = qlist_getat; list->getnext = qlist_getnext; list->popfirst = qlist_popfirst; list->poplast = qlist_poplast; list->popat = qlist_popat; list->removefirst = qlist_removefirst; list->removelast = qlist_removelast; list->removeat = qlist_removeat; list->reverse = qlist_reverse; list->clear = qlist_clear; list->size = qlist_size; list->datasize = qlist_datasize; list->toarray = qlist_toarray; list->tostring = qlist_tostring; list->debug = qlist_debug; list->lock = qlist_lock; list->unlock = qlist_unlock; list->free = qlist_free; return list; }
/** * Open ratating-log file * * @param filepathfmt filename format. formatting argument is same as * strftime() * @param mode new file mode. 0 for system default * @param rotateinterval rotating interval seconds, set 0 to disable rotation * @param options combination of options. * * @return a pointer of qlog_t structure * * @note * rotateinterval is not relative time. If you set it to 3600, log file will be * rotated at every hour. And filenameformat is same as strftime(). So If you * want to log with hourly rotating, filenameformat must be defined including * hour format like "/somepath/xxx-%Y%m%d%H.log". You can set it to * "/somepath/xxx-%H.log" for daily overrided log file. * * @note * Available options: * - QLOG_OPT_THREADSAFE - make it thread-safe. * - QLOG_OPT_FLUSH - flush out buffer everytime. * * @code * qlog_t *log = qlog("/tmp/qdecoder-%Y%m%d.err", 0644, 86400, QLOG_OPT_THREADSAFE); * log->free(log); * @endcode */ qlog_t *qlog(const char *filepathfmt, mode_t mode, int rotateinterval, int options) { qlog_t *log; // malloc qlog_t structure log = (qlog_t *) calloc(1, sizeof(qlog_t)); if (log == NULL) { errno = ENOMEM; return NULL; } // set up the structure. qstrcpy(log->filepathfmt, sizeof(log->filepathfmt), filepathfmt); log->mode = mode; if (rotateinterval > 0) log->rotateinterval = rotateinterval; // handle options if (options & QLOG_OPT_THREADSAFE) { Q_MUTEX_NEW(log->qmutex, true); if (log->qmutex == NULL) { errno = ENOMEM; free(log); return NULL; } } if (options & QLOG_OPT_FLUSH) { log->logflush = true; } // try to open the log file. if (_real_open(log) == false) { free(log); Q_MUTEX_DESTROY(log->qmutex); return NULL; } // member methods log->write = write_; log->writef = writef; log->duplicate = duplicate; log->flush = flush_; log->free = free_; return log; }