1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 1996,2008 Oracle. All rights reserved. 5 * 6 * $Id: hash_reclaim.c,v 12.11 2008/01/08 20:58:34 bostic Exp $ 7 */ 8 9#include "db_config.h" 10 11#include "db_int.h" 12#include "dbinc/db_page.h" 13#include "dbinc/hash.h" 14 15/* 16 * __ham_reclaim -- 17 * Reclaim the pages from a subdatabase and return them to the 18 * parent free list. For now, we link each freed page on the list 19 * separately. If people really store hash databases in subdatabases 20 * and do a lot of creates and deletes, this is going to be a problem, 21 * because hash needs chunks of contiguous storage. We may eventually 22 * need to go to a model where we maintain the free list with chunks of 23 * contiguous pages as well. 24 * 25 * PUBLIC: int __ham_reclaim __P((DB *, DB_THREAD_INFO *, DB_TXN *txn)); 26 */ 27int 28__ham_reclaim(dbp, ip, txn) 29 DB *dbp; 30 DB_THREAD_INFO *ip; 31 DB_TXN *txn; 32{ 33 DBC *dbc; 34 HASH_CURSOR *hcp; 35 int ret; 36 37 /* Open up a cursor that we'll use for traversing. */ 38 if ((ret = __db_cursor(dbp, ip, txn, &dbc, 0)) != 0) 39 return (ret); 40 hcp = (HASH_CURSOR *)dbc->internal; 41 42 if ((ret = __ham_get_meta(dbc)) != 0) 43 goto err; 44 45 /* Write lock the metapage for deallocations. */ 46 if ((ret = __ham_dirty_meta(dbc, 0)) != 0) 47 goto err; 48 49 /* Avoid locking every page, we have the handle locked exclusive. */ 50 F_SET(dbc, DBC_DONTLOCK); 51 52 if ((ret = __ham_traverse(dbc, 53 DB_LOCK_WRITE, __db_reclaim_callback, NULL, 1)) != 0) 54 goto err; 55 if ((ret = __dbc_close(dbc)) != 0) 56 goto err; 57 if ((ret = __ham_release_meta(dbc)) != 0) 58 goto err; 59 return (0); 60 61err: if (hcp->hdr != NULL) 62 (void)__ham_release_meta(dbc); 63 (void)__dbc_close(dbc); 64 return (ret); 65} 66 67/* 68 * __ham_truncate -- 69 * Reclaim the pages from a subdatabase and return them to the 70 * parent free list. 71 * 72 * PUBLIC: int __ham_truncate __P((DBC *, u_int32_t *)); 73 */ 74int 75__ham_truncate(dbc, countp) 76 DBC *dbc; 77 u_int32_t *countp; 78{ 79 u_int32_t count; 80 int ret, t_ret; 81 82 if ((ret = __ham_get_meta(dbc)) != 0) 83 return (ret); 84 85 count = 0; 86 87 ret = __ham_traverse(dbc, 88 DB_LOCK_WRITE, __db_truncate_callback, &count, 1); 89 90 if ((t_ret = __ham_release_meta(dbc)) != 0 && ret == 0) 91 ret = t_ret; 92 93 if (countp != NULL) 94 *countp = count; 95 return (ret); 96} 97