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

📄 hamsterdb.c

📁 About: hamsterdb is a database engine written in ANSI C. It supports a B+Tree index structure, uses
💻 C
📖 第 1 页 / 共 4 页
字号:
    ham_status_t st;    ham_u32_t intflags=0;    ham_offset_t blobid=0;    ham_backend_t *be;    if (!db || !key)        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 ((st=ham_txn_begin(&txn, db)))        return (st);    /*     * get rid of the index entry, then free the blob     */    st=be->_fun_erase(be, key, &blobid, &intflags, flags);    if (st==HAM_SUCCESS) {        if (!((intflags&KEY_BLOB_SIZE_TINY) ||              (intflags&KEY_BLOB_SIZE_SMALL) ||              (intflags&KEY_BLOB_SIZE_EMPTY)))            st=blob_free(db, blobid, 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_dump(ham_db_t *db, void *reserved, ham_dump_cb_t cb){#ifdef HAM_ENABLE_INTERNAL    ham_txn_t txn;    ham_status_t st;    ham_backend_t *be;    if (!db || !cb)        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);    /*     * call the backend function     */    st=be->_fun_enumerate(be, my_dump_cb, cb);    if (st) {        (void)ham_txn_abort(&txn);        return (st);    }    return (ham_txn_commit(&txn, 0));#else /* !HAM_ENABLE_INTERNAL */    return (HAM_NOT_IMPLEMENTED);#endif}ham_status_tham_check_integrity(ham_db_t *db, void *reserved){#ifdef HAM_ENABLE_INTERNAL    ham_txn_t txn;    ham_status_t st;    ham_backend_t *be;    if (!db)        return (HAM_INV_PARAMETER);    if (db_get_env(db))        __prepare_db(db);    db_set_error(db, 0);    /*     * check the cache integrity     */    st=cache_check_integrity(db_get_cache(db));    if (st)        return (st);    be=db_get_backend(db);    if (!be)        return (db_set_error(db, HAM_INV_INDEX));    if ((st=ham_txn_begin(&txn, db)))        return (st);    /*     * call the backend function     */    st=be->_fun_check_integrity(be);    if (st) {        (void)ham_txn_abort(&txn);        return (st);    }    return (ham_txn_commit(&txn, 0));#else /* !HAM_ENABLE_INTERNAL */    return (HAM_NOT_IMPLEMENTED);#endif}ham_status_tham_flush(ham_db_t *db, ham_u32_t flags){    ham_status_t st;    (void)flags;    if (!db)        return (HAM_INV_PARAMETER);    if (db_get_env(db))        __prepare_db(db);    db_set_error(db, 0);    /*     * never flush an in-memory-database     */    if (db_get_rt_flags(db)&HAM_IN_MEMORY_DB)        return (0);    /*     * update the header page, if necessary     */    if (db_is_dirty(db)) {        st=page_flush(db_get_header_page(db));        if (st)            return (db_set_error(db, st));    }    st=db_flush_all(db, DB_FLUSH_NODELETE);    if (st)        return (db_set_error(db, st));    st=db_get_device(db)->flush(db_get_device(db));    if (st)        return (db_set_error(db, st));    return (HAM_SUCCESS);}ham_status_tham_close(ham_db_t *db){    ham_status_t st=0;    ham_backend_t *be;    ham_bool_t noenv=HAM_FALSE;    ham_db_t *newowner=0;    if (!db)        return (HAM_INV_PARAMETER);    db_set_error(db, 0);    /*     * if we're in an environment: all pages, which have this page     * as an owner, must transfer their ownership to the     * next page!     */    if (db_get_env(db)) {        ham_db_t *head=env_get_list(db_get_env(db));        while (head) {            if (head!=db) {                newowner=head;                break;            }            head=db_get_next(head);        }    }    if (newowner) {        ham_page_t *head=cache_get_totallist(db_get_cache(db));         while (head) {            if (page_get_owner(head)==db)                page_set_owner(head, newowner);            head=page_get_next(head, PAGE_LIST_CACHED);        }    }    /*     * if this database has no environment, or if it's the last     * database in the environment: delete all environment-members     */    if (db_get_env(db)==0 ||         env_get_list(db_get_env(db))==0 ||        db_get_next(env_get_list(db_get_env(db)))==0)        noenv=HAM_TRUE;    be=db_get_backend(db);    /*     * in-memory-database: free all allocated blobs     */    if (be && db_get_rt_flags(db)&HAM_IN_MEMORY_DB) {        ham_txn_t txn;        free_cb_context_t context;        context.db=db;        if (!ham_txn_begin(&txn, db)) {            (void)be->_fun_enumerate(be, my_free_cb, &context);            (void)ham_txn_commit(&txn, 0);        }    }    /*     * free cached memory     */    if (db_get_record_allocdata(db)) {        ham_mem_free(db, db_get_record_allocdata(db));        db_set_record_allocdata(db, 0);        db_set_record_allocsize(db, 0);    }    if (db_get_key_allocdata(db)) {        ham_mem_free(db, db_get_key_allocdata(db));        db_set_key_allocdata(db, 0);        db_set_key_allocsize(db, 0);    }    /*     * flush the freelist     */    if (noenv) {        st=freel_shutdown(db);        if (st) {            ham_log(("freel_shutdown() failed with status %d (%s)",                    st, ham_strerror(st)));            return (st);        }    }    /*     * flush all pages     */    if (noenv) {        st=db_flush_all(db, 0);        if (st) {            ham_log(("db_flush_all() failed with status %d (%s)",                    st, ham_strerror(st)));            return (st);        }    }    /*     * free the cache for extended keys     */    if (noenv && db_get_extkey_cache(db)) {        extkey_cache_destroy(db_get_extkey_cache(db));        if (db_get_env(db))            env_set_extkey_cache(db_get_env(db), 0);        else            db_set_extkey_cache(db, 0);    }    /* close the backend */    if (be) {        st=be->_fun_close(db_get_backend(db));        if (st) {            ham_log(("backend close() failed with status %d (%s)",                    st, ham_strerror(st)));            return (st);        }        ham_mem_free(db, be);        db_set_backend(db, 0);    }    /*     * if we're not in read-only mode, and not an in-memory-database,     * and the dirty-flag is true: flush the page-header to disk     */	if (db_get_header_page(db) && noenv &&        !(db_get_rt_flags(db)&HAM_IN_MEMORY_DB) &&        db_get_device(db) && db_get_device(db)->is_open(db_get_device(db)) &&        (!(db_get_rt_flags(db)&HAM_READ_ONLY))) {        /* flush the database header, if it's dirty */		if (db_is_dirty(db)) {			st=page_flush(db_get_header_page(db));            if (st) {                ham_log(("page_flush() failed with status %d (%s)",                        st, ham_strerror(st)));                return (db_set_error(db, st));            }        }    }    /*     * environment: move the ownership to another database.     * it's possible that there's no other page, then set the      * ownerwhip to 0     */    if (db_get_env(db) && db_get_header_page(db)) {        page_set_owner(db_get_header_page(db), newowner);    }    /*     * otherwise (if there's no environment), free the page     */    else if (!db_get_env(db) && db_get_header_page(db)) {        if (page_get_pers(db_get_header_page(db)))            (void)page_free(db_get_header_page(db));        (void)page_delete(db_get_header_page(db));        db_set_header_page(db, db_get_header_page(db));    }    /*      * get rid of the cache      */    if (noenv && db_get_cache(db)) {        cache_delete(db, db_get_cache(db));        if (db_get_env(db))            env_set_cache(db_get_env(db), 0);        else            db_set_cache(db, 0);    }    /*      * close the device, but not if we're in an environment     */    if (!db_get_env(db) && db_get_device(db)) {        if (db_get_device(db)->is_open(db_get_device(db))) {            (void)db_get_device(db)->flush(db_get_device(db));            (void)db_get_device(db)->close(db_get_device(db));        }        (void)db_get_device(db)->destroy(db_get_device(db));        db_set_device(db, 0);    }    /*      * close the allocator, but not if we're in an environment     */    if (!db_get_env(db) && db_get_allocator(db)) {        db_get_allocator(db)->close(db_get_allocator(db));        db_set_allocator(db, 0);    }    /*     * remove this database from the environment     */    if (db_get_env(db)) {        ham_db_t *prev=0, *head=env_get_list(db_get_env(db));        while (head) {            if (head==db) {                if (!prev)                    env_set_list(db_get_env(db), db_get_next(db));                else                    db_set_next(prev, db_get_next(db));                break;            }            prev=head;            head=db_get_next(head);        }        db_set_env(db, 0);    }    return (0);}ham_status_tham_cursor_create(ham_db_t *db, void *reserved, ham_u32_t flags,        ham_cursor_t **cursor){    if (!db || !cursor)        return (HAM_INV_PARAMETER);    if (db_get_env(db))        __prepare_db(db);    db_set_error(db, 0);    return (bt_cursor_create(db, 0, flags, (ham_bt_cursor_t **)cursor));}ham_status_tham_cursor_clone(ham_cursor_t *src, ham_cursor_t **dest){    if (!src || !dest)        return (HAM_INV_PARAMETER);    if (db_get_env(cursor_get_db(src)))        __prepare_db(cursor_get_db(src));    db_set_error(cursor_get_db(src), 0);    return (bt_cursor_clone((ham_bt_cursor_t *)src, (ham_bt_cursor_t **)dest));}ham_status_tham_cursor_replace(ham_cursor_t *cursor, ham_record_t *record,            ham_u32_t flags){    if (!cursor || !record)        return (HAM_INV_PARAMETER);    if (db_get_rt_flags(cursor_get_db(cursor))&HAM_READ_ONLY)        return (db_set_error(cursor_get_db(cursor), HAM_DB_READ_ONLY));    if (db_get_env(cursor_get_db(cursor)))        __prepare_db(cursor_get_db(cursor));    db_set_error(cursor_get_db(cursor), 0);    return (bt_cursor_replace((ham_bt_cursor_t *)cursor, record, flags));}ham_status_tham_cursor_move(ham_cursor_t *cursor, ham_key_t *key,            ham_record_t *record, ham_u32_t flags){    if (!cursor)        return (HAM_INV_PARAMETER);    if (db_get_env(cursor_get_db(cursor)))        __prepare_db(cursor_get_db(cursor));    db_set_error(cursor_get_db(cursor), 0);    return (bt_cursor_move((ham_bt_cursor_t *)cursor, key, record, flags));}ham_status_tham_cursor_find(ham_cursor_t *cursor, ham_key_t *key, ham_u32_t flags){    if (!cursor || !key)        return (HAM_INV_PARAMETER);    if (db_get_env(cursor_get_db(cursor)))        __prepare_db(cursor_get_db(cursor));    db_set_error(cursor_get_db(cursor), 0);    return (bt_cursor_find((ham_bt_cursor_t *)cursor, key, flags));}ham_status_tham_cursor_insert(ham_cursor_t *cursor, ham_key_t *key,            ham_record_t *record, ham_u32_t flags){    ham_db_t *db;    if (!cursor || !key || !record)        return (HAM_INV_PARAMETER);    db=cursor_get_db(cursor);    if (db_get_env(db))        __prepare_db(db);    db_set_error(db, 0);    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));    return (bt_cursor_insert((ham_bt_cursor_t *)cursor, key, record, flags));}ham_status_tham_cursor_erase(ham_cursor_t *cursor, ham_u32_t flags){    ham_status_t st;    ham_offset_t rid;    ham_u32_t intflags;    ham_txn_t txn;    ham_db_t *db;    if (!cursor)        return (HAM_INV_PARAMETER);    if (db_get_env(cursor_get_db(cursor)))        __prepare_db(cursor_get_db(cursor));    db=cursor_get_db(cursor);    db_set_error(db, 0);    if (db_get_rt_flags(db)&HAM_READ_ONLY)        return (db_set_error(db, HAM_DB_READ_ONLY));    if ((st=ham_txn_begin(&txn, db)))        return (st);    st=bt_cursor_erase((ham_bt_cursor_t *)cursor, &rid, &intflags, flags);    if (st==HAM_SUCCESS) {        if (!((intflags&KEY_BLOB_SIZE_TINY) ||              (intflags&KEY_BLOB_SIZE_SMALL) ||              (intflags&KEY_BLOB_SIZE_EMPTY)))            st=blob_free(cursor_get_db(cursor), rid, flags);    }    if (st) {        (void)ham_txn_abort(&txn);        return (st);    }    return (ham_txn_commit(&txn, 0));}ham_status_tham_cursor_close(ham_cursor_t *cursor){    if (!cursor)        return (HAM_INV_PARAMETER);    if (db_get_env(cursor_get_db(cursor)))        __prepare_db(cursor_get_db(cursor));    db_set_error(cursor_get_db(cursor), 0);    return (bt_cursor_close((ham_bt_cursor_t *)cursor));}

⌨️ 快捷键说明

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