Index: Lib/bsddb/test/test_basics.py =================================================================== --- Lib/bsddb/test/test_basics.py (revision 58846) +++ Lib/bsddb/test/test_basics.py (working copy) @@ -564,7 +564,31 @@ #---------------------------------------- + def test_compact(self): + if db.version() < (4,4): + # compact is a feature of BerkeleyDB 4.4 and above + return + d = self.d + if verbose: + print '\n', '-=' * 30 + print "Running %s.test_compact..." % self.__class__.__name__ + + self.assertEqual(0, d.compact(flags=db.DB_FREELIST_ONLY)) + self.assertEqual(0, d.compact(flags=db.DB_FREELIST_ONLY)) + d.put("abcde", "ABCDE"); + d.put("bcde", "BCDE"); + d.put("abc", "ABC"); + d.put("monty", "python"); + d.delete("abc") + d.delete("bcde") + d.compact(start='abcde', stop='monty', txn=None, + compact_fillpercent=42, compact_pages=1, + compact_timeout=50000000, + flags=db.DB_FREELIST_ONLY|db.DB_FREE_SPACE) + + + #---------------------------------------------------------------------- Index: Modules/_bsddb.c =================================================================== --- Modules/_bsddb.c (revision 58846) +++ Modules/_bsddb.c (working copy) @@ -448,7 +448,8 @@ unsigned int bytes_left; switch (err) { - case 0: /* successful, no error */ break; + case 0: /* successful, no error */ + return 0; #if (DBVER < 41) case DB_INCOMPLETE: @@ -1347,7 +1348,63 @@ RETURN_NONE(); } +#if DBVER >= 44 +static PyObject* +DB_compact(DBObject* self, PyObject* args, PyObject* kwargs) +{ + PyObject* txnobj = NULL; + PyObject *startobj = NULL, *stopobj = NULL; + int flags = 0; + DB_COMPACT c_data = { 0 }; + static char* kwnames[] = { "txn", "start", "stop", "flags", + "compact_fillpercent", "compact_pages", + "compact_timeout", NULL }; + DB_TXN *txn = NULL; + PyObject *retval; + DBT *start_p, *stop_p; + DBT start, stop; + int err; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOiiiI:compact", kwnames, + &txnobj, &startobj, &stopobj, &flags, + &c_data.compact_fillpercent, + &c_data.compact_pages, + &c_data.compact_timeout)) + return NULL; + CHECK_DB_NOT_CLOSED(self); + if (!checkTxnObj(txnobj, &txn)) { + return NULL; + } + if (startobj && make_key_dbt(self, startobj, &start, NULL)) { + start_p = &start; + } else { + start_p = NULL; + } + if (stopobj && make_key_dbt(self, stopobj, &stop, NULL)) { + stop_p = &stop; + } else { + stop_p = NULL; + } + + MYDB_BEGIN_ALLOW_THREADS; + err = self->db->compact(self->db, txn, start_p, stop_p, &c_data, + flags, NULL); + MYDB_END_ALLOW_THREADS; + if (makeDBError(err)) { + retval = NULL; + } else { + retval = PyLong_FromUnsignedLong(c_data.compact_pages_truncated); + } + + if (startobj) + FREE_DBT(start); + if (stopobj) + FREE_DBT(stop); + return retval; +} +#endif + static PyObject* DB_fd(DBObject* self, PyObject* args) { @@ -5007,6 +5064,9 @@ {"associate", (PyCFunction)DB_associate, METH_VARARGS|METH_KEYWORDS}, #endif {"close", (PyCFunction)DB_close, METH_VARARGS}, +#if (DBVER >= 44) + {"compact", (PyCFunction)DB_compact, METH_VARARGS|METH_KEYWORDS}, +#endif {"consume", (PyCFunction)DB_consume, METH_VARARGS|METH_KEYWORDS}, {"consume_wait", (PyCFunction)DB_consume_wait, METH_VARARGS|METH_KEYWORDS}, {"cursor", (PyCFunction)DB_cursor, METH_VARARGS|METH_KEYWORDS}, @@ -5762,6 +5822,8 @@ #if (DBVER >= 44) ADD_INT(d, DB_READ_UNCOMMITTED); /* replaces DB_DIRTY_READ in 4.4 */ ADD_INT(d, DB_READ_COMMITTED); + ADD_INT(d, DB_FREELIST_ONLY); + ADD_INT(d, DB_FREE_SPACE); #endif #if (DBVER >= 33)