Example #1
0
/**
 * 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;
}
Example #2
0
/**
 * 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;
}
Example #3
0
File: qlog.c Project: Zengwn/qlibc
/**
 * 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;
}