summaryrefslogtreecommitdiff
path: root/btree/bt_reclaim.c
diff options
context:
space:
mode:
Diffstat (limited to 'btree/bt_reclaim.c')
-rw-r--r--btree/bt_reclaim.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/btree/bt_reclaim.c b/btree/bt_reclaim.c
new file mode 100644
index 0000000..835bf9f
--- /dev/null
+++ b/btree/bt_reclaim.c
@@ -0,0 +1,97 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1998-2009 Oracle. All rights reserved.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/lock.h"
+
+/*
+ * __bam_reclaim --
+ * Free a database.
+ *
+ * PUBLIC: int __bam_reclaim __P((DB *, DB_THREAD_INFO *, DB_TXN *));
+ */
+int
+__bam_reclaim(dbp, ip, txn)
+ DB *dbp;
+ DB_THREAD_INFO *ip;
+ DB_TXN *txn;
+{
+ DBC *dbc;
+ DB_LOCK meta_lock;
+ int ret, t_ret;
+
+ /* Acquire a cursor. */
+ if ((ret = __db_cursor(dbp, ip, txn, &dbc, 0)) != 0)
+ return (ret);
+
+ /* Write lock the metapage for deallocations. */
+ if ((ret = __db_lget(dbc,
+ 0, PGNO_BASE_MD, DB_LOCK_WRITE, 0, &meta_lock)) != 0)
+ goto err;
+
+ /* Avoid locking every page, we have the handle locked exclusive. */
+ F_SET(dbc, DBC_DONTLOCK);
+
+ /* Walk the tree, freeing pages. */
+ ret = __bam_traverse(dbc,
+ DB_LOCK_WRITE, dbc->internal->root, __db_reclaim_callback, NULL);
+
+ if ((t_ret = __TLPUT(dbc, meta_lock)) != 0 && ret == 0)
+ ret = t_ret;
+
+ /* Discard the cursor. */
+err: if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0)
+ ret = t_ret;
+
+ return (ret);
+}
+
+/*
+ * __bam_truncate --
+ * Truncate a database.
+ *
+ * PUBLIC: int __bam_truncate __P((DBC *, u_int32_t *));
+ */
+int
+__bam_truncate(dbc, countp)
+ DBC *dbc;
+ u_int32_t *countp;
+{
+ u_int32_t count;
+ int ret;
+
+#ifdef HAVE_COMPRESSION
+ u_int32_t comp_count;
+
+ comp_count = 0;
+ if (DB_IS_COMPRESSED(dbc->dbp) &&
+ (ret = __bam_compress_count(dbc, NULL, &comp_count)) != 0)
+ return (ret);
+#endif
+
+ count = 0;
+
+ /* Walk the tree, freeing pages. */
+ ret = __bam_traverse(dbc,
+ DB_LOCK_WRITE, dbc->internal->root, __db_truncate_callback, &count);
+
+#ifdef HAVE_COMPRESSION
+ if (DB_IS_COMPRESSED(dbc->dbp)) {
+ if (countp != NULL)
+ *countp = comp_count;
+ } else
+#endif
+ if (countp != NULL)
+ *countp = count;
+
+ return (ret);
+}