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

📄 hamsterdb.c

📁 About: hamsterdb is a database engine written in ANSI C. It supports a B+Tree index structure, uses
💻 C
📖 第 1 页 / 共 4 页
字号:
         */        st=device->read(device, 0, hdrbuf, sizeof(hdrbuf));        if (st) {            ham_log(("os_pread of %s failed with status %d (%s)", filename,                    st, ham_strerror(st)));            (void)ham_close(db);            return (db_set_error(db, st));        }        pagesize=ham_db2h32(((db_header_t *)&hdrbuf[12])->_pagesize);        device_set_pagesize(device, pagesize);        /*         * can we use mmap?         */#if HAVE_MMAP        if (!(flags&HAM_DISABLE_MMAP)) {            if (pagesize%os_get_pagesize()==0)                flags|=DB_USE_MMAP;            else                device->set_flags(device, flags|HAM_DISABLE_MMAP);        }        else            device->set_flags(device, flags|HAM_DISABLE_MMAP);        flags&=~HAM_DISABLE_MMAP; /* don't store this flag */#else        device->set_flags(device, flags|HAM_DISABLE_MMAP);#endif        /*          * create the freelist - not needed for in-memory-databases         */        if (!(flags&HAM_IN_MEMORY_DB)) {            st=freel_create(db);            if (st) {                ham_log(("unable to create freelist"));                (void)ham_close(db);                return (st);            }        }    }    db_set_error(db, HAM_SUCCESS);    /*     * read the header page     */    if (!db_get_header_page(db)) {        page=page_new(db);        if (!page) {            (void)ham_close(db);            return (db_get_error(db));        }        st=page_fetch(page, pagesize);        if (st) {            if (page_get_pers(page))                (void)page_free(page);            (void)page_delete(page);            (void)ham_close(db);            return (st);        }        page_set_type(page, PAGE_TYPE_HEADER);        if (db_get_env(db))            env_set_header_page(db_get_env(db), page);        else            db_set_header_page(db, page);    }    /*     * otherwise, if a header page already exists (which means that we're     * in an environment), we transfer the ownership of the header      * page to this database     */    else {        page_set_owner(db_get_header_page(db), db);    }    /*      * check the file magic     */    if (db_get_magic(db, 0)!='H' ||        db_get_magic(db, 1)!='A' ||        db_get_magic(db, 2)!='M' ||        db_get_magic(db, 3)!='\0') {        ham_log(("invalid file type - %s is not a hamster-db", filename));        (void)ham_close(db);        db_set_error(db, HAM_INV_FILE_HEADER);        return (HAM_INV_FILE_HEADER);    }    /*      * check the database version     */    if (db_get_version(db, 0)!=HAM_VERSION_MAJ ||        db_get_version(db, 1)!=HAM_VERSION_MIN) {        ham_log(("invalid file version"));        (void)ham_close(db);        db_set_error(db, HAM_INV_FILE_VERSION);        return (HAM_INV_FILE_VERSION);    }    /*     * search for a database with this name     */    for (i=0; i<db_get_indexdata_size(db); i++) {        ham_u8_t *ptr=db_get_indexdata_at(db, i);        if (dbname==FIRST_DATABASE_NAME ||            dbname==ham_h2db16(*(ham_u16_t *)ptr)) {            db_set_indexdata_offset(db, i);            break;        }    }    if (i==db_get_indexdata_size(db)) {        (void)ham_close(db);        return (db_set_error(db, HAM_DATABASE_NOT_FOUND));    }    /*      * create the backend     */    backend=db_create_backend(db, flags);    if (!backend) {        ham_log(("unable to create backend with flags 0x%x", flags));        (void)ham_close(db);        db_set_error(db, HAM_INV_INDEX);        return (HAM_INV_INDEX);    }    db_set_backend(db, backend);    /*      * initialize the backend      */    st=backend->_fun_open(backend, flags);    if (st) {        ham_log(("backend create() failed with status %d (%s)",                st, ham_strerror(st)));        db_set_error(db, st);        (void)ham_close(db);        return (st);    }    /*      * set the database flags      */    db_set_rt_flags(db, flags|be_get_flags(backend));    ham_assert(!(be_get_flags(backend)&HAM_DISABLE_VAR_KEYLEN),             ("invalid persistent database flags 0x%x", be_get_flags(backend)));    ham_assert(!(be_get_flags(backend)&HAM_CACHE_STRICT),             ("invalid persistent database flags 0x%x", be_get_flags(backend)));    ham_assert(!(be_get_flags(backend)&HAM_DISABLE_MMAP),             ("invalid persistent database flags 0x%x", be_get_flags(backend)));    ham_assert(!(be_get_flags(backend)&HAM_WRITE_THROUGH),             ("invalid persistent database flags 0x%x", be_get_flags(backend)));    ham_assert(!(be_get_flags(backend)&HAM_READ_ONLY),             ("invalid persistent database flags 0x%x", be_get_flags(backend)));    ham_assert(!(be_get_flags(backend)&HAM_DISABLE_FREELIST_FLUSH),             ("invalid persistent database flags 0x%x", be_get_flags(backend)));    ham_assert(!(be_get_flags(backend)&DB_USE_MMAP),             ("invalid persistent database flags 0x%x", be_get_flags(backend)));    /*      * initialize the cache     */    if (!db_get_cache(db)) {        if (cachesize==0)            cachesize=HAM_DEFAULT_CACHESIZE;         cache=cache_new(db, cachesize/db_get_pagesize(db));        if (!cache) {            (void)ham_close(db);            return (db_get_error(db));        }        if (db_get_env(db))            env_set_cache(db_get_env(db), cache);        else            db_set_cache(db, cache);    }    /*      * set the key compare function     */    ham_set_compare_func(db, db_default_compare);    ham_set_prefix_compare_func(db, db_default_prefix_compare);    return (HAM_SUCCESS);}ham_status_tham_create(ham_db_t *db, const char *filename, ham_u32_t flags, ham_u32_t mode){    return (ham_create_ex(db, filename, flags, mode, 0));}ham_status_tham_create_ex(ham_db_t *db, const char *filename,        ham_u32_t flags, ham_u32_t mode, ham_parameter_t *param){    ham_status_t st;    ham_cache_t *cache;    ham_backend_t *backend;    ham_page_t *page;    ham_u32_t pflags;    ham_device_t *device;    ham_size_t pagesize;    ham_u16_t keysize, dbname=0, i;    ham_size_t cachesize;    if (!db)        return (HAM_INV_PARAMETER);    db_set_error(db, 0);    /*     * check (and modify) the parameters     */    st=__check_create_parameters(HAM_FALSE, filename, &flags, param,             &pagesize, &keysize, &cachesize, &dbname);    if (st)        return (db_set_error(db, st));    /*      * if we do not yet have an allocator: create a new one      */    if (!db_get_allocator(db)) {        db_set_allocator(db, ham_default_allocator_new());        if (!db_get_allocator(db))            return (db_set_error(db, HAM_OUT_OF_MEMORY));    }    /*      * initialize the device, if it does not yet exist     */    if (!db_get_device(db)) {        device=ham_device_new(db_get_allocator(db), flags&HAM_IN_MEMORY_DB);        if (!device)            return (db_get_error(db));        if (db_get_env(db))            env_set_device(db_get_env(db), device);        else            db_set_device(db, device);        device->set_flags(device, flags);        device_set_pagesize(device, pagesize);        /*          * create the file          */        st=device->create(device, filename, flags, mode);        if (st) {            (void)ham_close(db);            return (db_set_error(db, st));        }    }    else        device=db_get_device(db);    /*     * set the flags     */    pflags=flags;    pflags&=~HAM_DISABLE_VAR_KEYLEN;    pflags&=~HAM_CACHE_STRICT;    pflags&=~HAM_DISABLE_MMAP;    pflags&=~HAM_WRITE_THROUGH;    pflags&=~HAM_READ_ONLY;    pflags&=~HAM_DISABLE_FREELIST_FLUSH;    pflags&=~DB_USE_MMAP;    db_set_rt_flags(db, flags);    /*      * if there's no header page, allocate one     */    if (!db_get_header_page(db)) {        page=page_new(db);        if (!page) {            ham_log(("unable to allocate the header page"));            (void)ham_close(db);            return (db_get_error(db));        }		st=page_alloc(page, pagesize);        if (st) {            page_delete(page);            (void)ham_close(db);            return (st);        }        memset(page_get_pers(page), 0, pagesize);        page_set_type(page, PAGE_TYPE_HEADER);        if (db_get_env(db))            env_set_header_page(db_get_env(db), page);        else            db_set_header_page(db, page);        page_set_dirty(page, 1);        /* initialize the header */        db_set_magic(db, 'H', 'A', 'M', '\0');        db_set_version(db, HAM_VERSION_MAJ, HAM_VERSION_MIN,                 HAM_VERSION_REV, 0);        db_set_serialno(db, HAM_SERIALNO);        db_set_error(db, HAM_SUCCESS);        db_set_pagesize(db, pagesize);        db_set_indexdata_size(db, DB_MAX_INDICES);        /*          * initialize the freelist structure in the header page;         * the freelist starts _after_ the header-page, therefore          * the start-address of the freelist is the pagesize         */        st=freel_prepare(db, db_get_freelist(db), db_get_pagesize(db),                db_get_usable_pagesize(db)-                (OFFSET_OF(db_header_t, _freelist_start)+1));        if (st) {            ham_log(("unable to setup the freelist"));            (void)ham_close(db);            return (db_set_error(db, st));        }        /*          * create the freelist - not needed for in-memory-databases         */        if (!(flags&HAM_IN_MEMORY_DB)) {            st=freel_create(db);            if (st) {                ham_log(("unable to create freelist"));                (void)ham_close(db);                return (db_set_error(db, st));            }        }    }    /*     * otherwise, if a header page already exists (which means that we're     * in an environment), we transfer the ownership of the header      * page to this database     */    else {        page_set_owner(db_get_header_page(db), db);    }    /*     * check if this database name is unique     */    for (i=0; i<db_get_indexdata_size(db); i++) {        ham_u16_t name=ham_h2db16(*(ham_u16_t *)db_get_indexdata_at(db, i));        if (name==dbname) {            (void)ham_close(db);            return (db_set_error(db, HAM_DATABASE_ALREADY_EXISTS));        }    }    /*     * find a free slot in the indexdata array and store the      * database name     */    for (i=0; i<db_get_indexdata_size(db); i++) {        ham_u8_t *ptr=db_get_indexdata_at(db, i);        ham_u16_t name=ham_h2db16(*(ham_u16_t *)ptr);        if (!name) {            *(ham_u16_t *)ptr=ham_db2h16(dbname);            db_set_indexdata_offset(db, i);            break;        }    }    if (i==db_get_indexdata_size(db)) {        (void)ham_close(db);        return (db_set_error(db, HAM_INTERNAL_ERROR)); /* TODO */    }    /*      * initialize the cache     */    if (!db_get_cache(db)) {        if (cachesize==0)            cachesize=HAM_DEFAULT_CACHESIZE;        cache=cache_new(db, cachesize/db_get_pagesize(db));        if (!cache) {            (void)ham_close(db);            return (db_get_error(db));        }        if (db_get_env(db))            env_set_cache(db_get_env(db), cache);        else            db_set_cache(db, cache);    }    /*      * create the backend     */    backend=db_create_backend(db, flags);    if (!backend) {        ham_log(("unable to create backend with flags 0x%x", flags));        (void)ham_close(db);        return (db_set_error(db, HAM_INV_INDEX));    }    /*      * initialize the backend     */    st=backend->_fun_create(backend, keysize, pflags);    if (st) {        ham_log(("unable to create the backend"));        (void)ham_close(db);        db_set_error(db, st);        return (st);    }    /*      * store the backend in the database     */    db_set_backend(db, backend);    /*     * set the default key compare functions     */    ham_set_compare_func(db, db_default_compare);    ham_set_prefix_compare_func(db, db_default_prefix_compare);    db_set_dirty(db, HAM_TRUE);    return (HAM_SUCCESS);}ham_status_tham_get_error(ham_db_t *db){    if (!db)        return (0);    return (db_get_error(db));}ham_status_tham_set_prefix_compare_func(ham_db_t *db, ham_prefix_compare_func_t foo){    if (!db)        return (HAM_INV_PARAMETER);    db_set_error(db, 0);    db_set_prefix_compare_func(db, foo);    return (HAM_SUCCESS);}ham_status_tham_set_compare_func(ham_db_t *db, ham_compare_func_t foo){    if (!db)        return (HAM_INV_PARAMETER);    db_set_error(db, 0);    db_set_compare_func(db, foo);    return (HAM_SUCCESS);}ham_status_tham_find(ham_db_t *db, void *reserved, ham_key_t *key,        ham_record_t *record, ham_u32_t flags){    ham_txn_t txn;    ham_status_t st;    ham_backend_t *be;    if (!db || !key || !record)        return (HAM_INV_PARAMETER);    if (db_get_env(db))        __prepare_db(db);    db_set_error(db, 0);    be=db_get_backend(db);    if (!be)        return (db_set_error(db, HAM_INV_INDEX));    if ((st=ham_txn_begin(&txn, db)))        return (st);    /*     * first look up the blob id, then fetch the blob     */    st=be->_fun_find(be, key, record, flags);    if (st==HAM_SUCCESS)        st=util_read_record(db, record, flags);    if (st) {        (void)ham_txn_abort(&txn);        return (st);    }    return (ham_txn_commit(&txn, 0));}ham_status_tham_insert(ham_db_t *db, void *reserved, ham_key_t *key,        ham_record_t *record, ham_u32_t flags){    ham_txn_t txn;    ham_status_t st;    ham_backend_t *be;    if (!db || !key || !record)        return (HAM_INV_PARAMETER);    if (db_get_env(db))        __prepare_db(db);    db_set_error(db, 0);    be=db_get_backend(db);    if (!be)        return (db_set_error(db, HAM_INV_INDEX));    if (db_get_rt_flags(db)&HAM_READ_ONLY)        return (db_set_error(db, HAM_DB_READ_ONLY));    if ((db_get_rt_flags(db)&HAM_DISABLE_VAR_KEYLEN) &&        (key->size>db_get_keysize(db)))        return (db_set_error(db, HAM_INV_KEYSIZE));    if ((db_get_keysize(db)<sizeof(ham_offset_t)) &&        (key->size>db_get_keysize(db)))        return (db_set_error(db, HAM_INV_KEYSIZE));    if ((st=ham_txn_begin(&txn, db)))        return (st);    /*     * store the index entry; the backend will store the blob     */    st=be->_fun_insert(be, key, record, flags);    if (st) {#if 0        (void)ham_txn_abort(&txn);#endif        (void)ham_txn_commit(&txn, 0);        return (st);    }    return (ham_txn_commit(&txn, 0));}ham_status_tham_erase(ham_db_t *db, void *reserved, ham_key_t *key, ham_u32_t flags){    ham_txn_t txn;

⌨️ 快捷键说明

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