⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 puredb_write.c

📁 pft实现源码
💻 C
字号:
/* (C)opyleft 2001-2004 Frank DENIS <j@pureftpd.org> */#include <config.h>#include "puredb_p.h"#include "puredb_write.h"#ifndef HAVE_STRDUPstatic char *strdup(const char *str){    char *newstr;    size_t str_len_1;        if (str == NULL ||        (str_len_1 = strlen(str) + (size_t) 1U) <= (size_t) 0U ||        (newstr = malloc(str_len_1)) == NULL) {        return NULL;    }    memcpy(newstr, str, str_len_1);        return newstr;}#endifstatic puredb_u32_t puredbw_hash(const char * const msg, size_t len){    puredb_u32_t j = (puredb_u32_t) 5381U;    while (len != 0) {        len--;        j += (j << 5);        j ^= ((unsigned char) msg[len]);    }    j &= 0xffffffff;    return j;}int puredbw_open(PureDBW * const dbw,                 const char * const file_index,                 const char * const file_data,                 const char * const file_final){    dbw->file_index = NULL;    dbw->file_data = NULL;    dbw->file_final = NULL;    dbw->fpindex = NULL;    dbw->fpdata = NULL;    {        int z = (sizeof dbw->hash_table0) / (sizeof dbw->hash_table0[0]) - 1;        do {            dbw->hash_table0[z].hash1_list = NULL;            dbw->hash_table0[z].hash1_list_size = (size_t) 0U;            z--;        } while (z >= 0);    }    if ((dbw->file_index = strdup(file_index)) == NULL ||        (dbw->file_data = strdup(file_data)) == NULL ||        (dbw->file_final = strdup(file_final)) == NULL ||        (dbw->fpindex = fopen(file_index, "wb")) == NULL ||        (dbw->fpdata = fopen(file_data, "w+b")) == NULL) {        return -1;    }    dbw->data_offset_counter = (puredb_u32_t) 0U;    dbw->offset_first_data = (puredb_u32_t)        (sizeof PUREDBW_VERSION - (size_t) 1U +         (1U + sizeof dbw->hash_table0 / sizeof dbw->hash_table0[0]) *         sizeof(puredb_u32_t));    if (fwrite(PUREDBW_VERSION, (size_t) 1U,               sizeof PUREDBW_VERSION - (size_t) 1U,               dbw->fpindex) != (sizeof PUREDBW_VERSION - (size_t) 1U)) {        return -1;    }    return 0;}int puredbw_add(PureDBW * const dbw,                const char * const key, const size_t key_len,                const char * const content, const size_t content_len){    const puredb_u32_t hash = puredbw_hash(key, key_len);    const puredb_u32_t hash_hi = hash & 0xff;    Hash0 * const hash0 = &dbw->hash_table0[hash_hi];    Hash1 *hash1;    if (hash0->hash1_list == NULL) {        hash0->hash1_list_size = sizeof(Hash1);        if ((hash0->hash1_list = malloc(hash0->hash1_list_size)) == NULL) {            return -1;        }    } else {        Hash1 *newpnt;        hash0->hash1_list_size += sizeof(Hash1);        if ((newpnt = realloc(hash0->hash1_list,                              hash0->hash1_list_size)) == NULL) {            return -1;        }        hash0->hash1_list = newpnt;    }    dbw->offset_first_data += sizeof(puredb_u32_t) + sizeof(puredb_u32_t);    hash1 = (Hash1 *) ((unsigned char *) hash0->hash1_list +                       hash0->hash1_list_size - sizeof(Hash1));    hash1->hash = hash;    hash1->offset_data = dbw->data_offset_counter;    dbw->data_offset_counter += sizeof(puredb_u32_t) + sizeof(puredb_u32_t) +        + key_len + content_len;    {        const puredb_u32_t key_len_ = htonl((puredb_u32_t) key_len);        if (fwrite(&key_len_, sizeof key_len_, (size_t) 1U, dbw->fpdata) !=            (size_t) 1U) {            return -1;        }    }    if (fwrite(key, (size_t) 1U, key_len, dbw->fpdata) != key_len) {        return -1;    }    {        const puredb_u32_t content_len_ = htonl((puredb_u32_t) content_len);        if (fwrite(&content_len_, sizeof content_len_, (size_t) 1U,                   dbw->fpdata) != (size_t) 1U) {            return -1;        }    }    if (fwrite(content, (size_t) 1U, content_len, dbw->fpdata)        != content_len) {        return -1;    }    return 0;}int puredbw_add_s(PureDBW * const dbw,                  const char * const key, const char * const content){    return puredbw_add(dbw, key, strlen(key), content, strlen(content));}static int hash1_cmp_hook(const void * const a, const void * const b){    register puredb_u32_t ha = ((const Hash1 *) a)->hash;    register puredb_u32_t hb = ((const Hash1 *) b)->hash;    if (ha < hb) {        return -1;    } else if (ha > hb) {        return 1;    }    ha = ((const Hash1 *) a)->offset_data;    hb = ((const Hash1 *) b)->offset_data;    if (ha < hb) {        return -1;    } else if (ha > hb) {        return 1;    }    return 0;}static int writekeys(PureDBW * const dbw){    register int hash_cnt = (int)        (sizeof dbw->hash_table0 / sizeof dbw->hash_table0[0]);    register const Hash0 *hash0 = dbw->hash_table0;    puredb_u32_t offset = (puredb_u32_t)        ((1U + sizeof dbw->hash_table0 / sizeof dbw->hash_table0[0]) *         sizeof(puredb_u32_t) + sizeof PUREDBW_VERSION - (size_t) 1U);    do {        {            const puredb_u32_t offset_ = htonl((puredb_u32_t) offset);                        if (fwrite(&offset_, sizeof offset_, (size_t) 1U, dbw->fpindex) !=                (size_t) 1U) {                return -1;            }        }        if (hash0->hash1_list_size <= 0U) {            offset += sizeof(puredb_u32_t);            dbw->offset_first_data += sizeof(puredb_u32_t);        } else {            offset += ((hash0->hash1_list_size / sizeof(Hash1)) *                       (sizeof(puredb_u32_t) + sizeof(puredb_u32_t)));        }        hash0++;        hash_cnt--;    } while (hash_cnt != 0);    {                                  /* extra hash0, filler */        const puredb_u32_t null_ = (puredb_u32_t) htonl(offset);        if (fwrite(&null_, sizeof null_, (size_t) 1U, dbw->fpindex) !=            (size_t) 1U) {                return -1;        }    }        hash_cnt = (int) (sizeof dbw->hash_table0 / sizeof dbw->hash_table0[0]);    hash0 = dbw->hash_table0;    do {        register Hash1 *hash1 = hash0->hash1_list;        register size_t list_size = hash0->hash1_list_size;        if (hash1 == NULL) {            const puredb_u32_t null_ =                 (puredb_u32_t) htonl((hash0 - dbw->hash_table0) + 1U);                        if (fwrite(&null_, sizeof null_, (size_t) 1U, dbw->fpindex) !=                (size_t) 1U) {                return -1;            }                        goto next;        }        qsort((void *) hash1, hash0->hash1_list_size / sizeof(Hash1),              sizeof(Hash1), hash1_cmp_hook);        do {            {                const puredb_u32_t hash_ = htonl(hash1->hash);                if (fwrite(&hash_, sizeof hash_, (size_t) 1U, dbw->fpindex) !=                    (size_t) 1U) {                    return -1;                }            }            {                const puredb_u32_t offset_data_ = htonl(hash1->offset_data +                                                      dbw->offset_first_data);                                if (fwrite(&offset_data_, sizeof offset_data_,                           (size_t) 1U, dbw->fpindex) != (size_t) 1U) {                    return -1;                }            }            hash1++;            list_size -= sizeof(Hash1);        } while (list_size > (size_t) 0U);        next:        hash0++;        hash_cnt--;    } while (hash_cnt != 0);    return 0;}static int freestructs(PureDBW * const dbw){    register Hash0 *hash0 = dbw->hash_table0;    int hash0_cnt = (int) (sizeof dbw->hash_table0 / sizeof dbw->hash_table0[0]);    do {        free(hash0->hash1_list);        hash0->hash1_list = NULL;        hash0++;        hash0_cnt--;    } while (hash0_cnt > 0);    return 0;}static int mergefiles(PureDBW * const dbw){    size_t readen;    char buf[4096];    rewind(dbw->fpdata);    while ((readen = fread(buf, (size_t) 1U, sizeof buf, dbw->fpdata)) >           (size_t) 0U) {        if (fwrite(buf, (size_t) 1U, readen, dbw->fpindex) != readen) {            return -1;        }    }    if (fclose(dbw->fpdata) != 0) {        return -1;    }    dbw->fpdata = NULL;    fflush(dbw->fpindex);#ifdef HAVE_FILENO    fsync(fileno(dbw->fpindex));#endif    if (fclose(dbw->fpindex) != 0) {        return -1;    }    dbw->fpindex = NULL;    (void) unlink(dbw->file_data);    if (rename(dbw->file_index, dbw->file_final) < 0)    {        (void) unlink(dbw->file_final);                if (rename(dbw->file_index, dbw->file_final) < 0) {                    return -1;        }    }    return 0;}static void freeall(PureDBW * const dbw){    if (dbw->fpindex != NULL) {        fclose(dbw->fpindex);        dbw->fpindex = NULL;    }    if (dbw->fpdata != NULL) {        fclose(dbw->fpdata);        dbw->fpdata = NULL;    }    free(dbw->file_index);    dbw->file_index = NULL;    free(dbw->file_data);    dbw->file_data = NULL;    free(dbw->file_final);    dbw->file_final = NULL;}void puredbw_free(PureDBW * const dbw){    freestructs(dbw);    freeall(dbw);}int puredbw_close(PureDBW * const dbw){    if (writekeys(dbw) != 0) {        return -1;    }    freestructs(dbw);    if (mergefiles(dbw) != 0) {        return -1;    }    freeall(dbw);    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -