txn.c
来自「About: hamsterdb is a database engine w」· C语言 代码 · 共 188 行
C
188 行
/** * Copyright (C) 2005-2007 Christoph Rupp (chris@crupp.de). * All rights reserved. See file LICENSE for licence and copyright * information. * */#include <string.h>#include "txn.h"#include "db.h"#include "error.h"#include "freelist.h"#include "mem.h"ham_status_ttxn_add_page(ham_txn_t *txn, ham_page_t *page){#ifdef HAM_DEBUG /* * check if the page is already in the transaction's pagelist - * that would be a bug */ ham_assert(txn_get_page(txn, page_get_self(page))==0, ("page 0x%llx is already in the txn", page_get_self(page)));#endif /* * not found? add the page */ page_add_ref(page); txn_set_pagelist(txn, page_list_insert(txn_get_pagelist(txn), PAGE_LIST_TXN, page)); return (HAM_SUCCESS);}ham_status_ttxn_free_page(ham_txn_t *txn, ham_page_t *page){ ham_assert(!(page_get_npers_flags(page)&PAGE_NPERS_DELETE_PENDING), (0)); page_set_npers_flags(page, page_get_npers_flags(page)|PAGE_NPERS_DELETE_PENDING); return (HAM_SUCCESS);}ham_status_ttxn_remove_page(ham_txn_t *txn, struct ham_page_t *page){ txn_set_pagelist(txn, page_list_remove(txn_get_pagelist(txn), PAGE_LIST_TXN, page)); page_release_ref(page); return (0);}ham_page_t *txn_get_page(ham_txn_t *txn, ham_offset_t address){ ham_page_t *start, *p=txn_get_pagelist(txn); start=p; while (p) { if (page_get_self(p)==address) return (p); p=page_get_next(p, PAGE_LIST_TXN); ham_assert(start!=p, ("circular reference in page-list")); if (start==p) break; } return (0);}ham_status_tham_txn_begin(ham_txn_t *txn, ham_db_t *db){ memset(txn, 0, sizeof(*txn)); txn_set_db(txn, db); db_set_txn(db, txn); db_set_txn_id(db, db_get_txn_id(db)+1); return (0);}ham_status_tham_txn_commit(ham_txn_t *txn, ham_u32_t flags){ ham_status_t st; ham_page_t *head, *next; ham_db_t *db=txn_get_db(txn); db_set_txn(db, 0); /* * flush the pages */ head=txn_get_pagelist(txn); while (head) { next=page_get_next(head, PAGE_LIST_TXN); page_set_next(head, PAGE_LIST_TXN, 0); page_set_previous(head, PAGE_LIST_TXN, 0); /* page is no longer in use */ page_release_ref(head); /* * delete the page? * * in-memory-databases don't use a freelist and therefore * can delete the page without consequences */ if (page_get_npers_flags(head)&PAGE_NPERS_DELETE_PENDING) { /* remove page from cache, add it to garbage list */ page_set_dirty(head, 0); st=db_free_page(head, DB_MOVE_TO_FREELIST); if (st) return (st); goto commit_next; } /* flush the page */ st=db_flush_page(db, head, flags&TXN_FORCE_WRITE ? HAM_WRITE_THROUGH : 0); if (st) { ham_trace(("commit failed with status 0x%x", st)); txn_set_pagelist(txn, head); (void)ham_txn_abort(txn); /* errors here are fatal... */ return (st); }commit_next: head=next; } txn_set_pagelist(txn, 0); return (0);}ham_status_tham_txn_abort(ham_txn_t *txn){ ham_page_t *head, *next; db_set_txn(txn_get_db(txn), 0); /* * delete all modified pages */ head=txn_get_pagelist(txn); while (head) { next=page_get_next(head, PAGE_LIST_TXN); page_set_next(head, PAGE_LIST_TXN, 0); page_set_previous(head, PAGE_LIST_TXN, 0); /* page is no longer in use */ page_release_ref(head);#if 0 page_set_dirty(head, 0); /* delete the page? */ if (page_get_npers_flags(head)&PAGE_NPERS_DELETE_PENDING) { /* remove the flag */ page_set_npers_flags(head, page_get_npers_flags(head)&(~PAGE_NPERS_DELETE_PENDING)); } (void)cache_move_to_garbage(db_get_cache(db), 0, head);#endif head=next; } txn_set_pagelist(txn, 0); return (0);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?