📄 hamsterdb.c
字号:
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 + -