[70608] trunk/base/src
jmr at macports.org
jmr at macports.org
Sat Aug 14 21:24:09 PDT 2010
Revision: 70608
http://trac.macports.org/changeset/70608
Author: jmr at macports.org
Date: 2010-08-14 21:24:06 -0700 (Sat, 14 Aug 2010)
Log Message:
-----------
vacuum registry database before closing if any entries have been deleted
Modified Paths:
--------------
trunk/base/src/cregistry/registry.c
trunk/base/src/cregistry/registry.h
trunk/base/src/macports1.0/macports.tcl
trunk/base/src/port/port.tcl
trunk/base/src/registry2.0/entry.c
trunk/base/src/registry2.0/registry.c
Modified: trunk/base/src/cregistry/registry.c
===================================================================
--- trunk/base/src/cregistry/registry.c 2010-08-15 03:22:13 UTC (rev 70607)
+++ trunk/base/src/cregistry/registry.c 2010-08-15 04:24:06 UTC (rev 70608)
@@ -401,3 +401,44 @@
return 0;
}
}
+
+/**
+ * Runs VACUUM (compact/defragment) on the given db file.
+ * Works on a path rather than an open db pointer because you can't vacuum an
+ * attached db, which is what the rest of the registry uses for some reason.
+ *
+ * @param [in] db_path path to db file to vacuum
+ * @return true if success; false if failure
+ */
+int reg_vacuum(char *db_path) {
+ sqlite3* db;
+ sqlite3_stmt* stmt = NULL;
+ int result = 0;
+ reg_error err;
+
+ if (sqlite3_open(db_path, &db) == SQLITE_OK) {
+ if (!init_db(db, &err)) {
+ sqlite3_close(db);
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+
+ if (sqlite3_prepare(db, "VACUUM", -1, &stmt, NULL) == SQLITE_OK) {
+ int r;
+ /* XXX: Busy waiting, consider using sqlite3_busy_handler/timeout */
+ do {
+ sqlite3_step(stmt);
+ r = sqlite3_reset(stmt);
+ if (r == SQLITE_OK) {
+ result = 1;
+ }
+ } while (r == SQLITE_BUSY);
+ }
+ if (stmt) {
+ sqlite3_finalize(stmt);
+ }
+ sqlite3_close(db);
+ return result;
+}
Modified: trunk/base/src/cregistry/registry.h
===================================================================
--- trunk/base/src/cregistry/registry.h 2010-08-15 03:22:13 UTC (rev 70607)
+++ trunk/base/src/cregistry/registry.h 2010-08-15 04:24:06 UTC (rev 70608)
@@ -83,4 +83,6 @@
int reg_commit(reg_registry* reg, reg_error* errPtr);
int reg_rollback(reg_registry* reg, reg_error* errPtr);
+int reg_vacuum(char* db_path);
+
#endif /* _CREG_H */
Modified: trunk/base/src/macports1.0/macports.tcl
===================================================================
--- trunk/base/src/macports1.0/macports.tcl 2010-08-15 03:22:13 UTC (rev 70607)
+++ trunk/base/src/macports1.0/macports.tcl 2010-08-15 04:24:06 UTC (rev 70608)
@@ -975,6 +975,15 @@
}
}
+# call this just before you exit
+proc mportshutdown {} {
+ global macports::registry.format
+ if {${registry.format} == "receipt_sqlite"} {
+ # close it down so the cleanup stuff is called, e.g. vacuuming the db
+ registry::close
+ }
+}
+
proc macports::worker_init {workername portpath porturl portbuildpath options variations} {
global macports::portinterp_options macports::portinterp_deferred_options registry.installtype
Modified: trunk/base/src/port/port.tcl
===================================================================
--- trunk/base/src/port/port.tcl 2010-08-15 03:22:13 UTC (rev 70607)
+++ trunk/base/src/port/port.tcl 2010-08-15 04:24:06 UTC (rev 70608)
@@ -4466,5 +4466,8 @@
set exit_status [process_command_files $ui_options(ports_commandfiles)]
}
+# shut down macports1.0
+mportshutdown
+
# Return with exit_status
exit $exit_status
Modified: trunk/base/src/registry2.0/entry.c
===================================================================
--- trunk/base/src/registry2.0/entry.c 2010-08-15 03:22:13 UTC (rev 70607)
+++ trunk/base/src/registry2.0/entry.c 2010-08-15 04:24:06 UTC (rev 70608)
@@ -162,6 +162,8 @@
reg_entry_free(entry);
}
Tcl_DeleteCommand(interp, Tcl_GetString(objv[2]));
+ /* set flag so that the db will be vacuumed when we close it */
+ Tcl_SetAssocData(interp, "registry::needs_vacuum", NULL, (ClientData)1);
return TCL_OK;
}
}
Modified: trunk/base/src/registry2.0/registry.c
===================================================================
--- trunk/base/src/registry2.0/registry.c 2010-08-15 03:22:13 UTC (rev 70607)
+++ trunk/base/src/registry2.0/registry.c 2010-08-15 04:24:06 UTC (rev 70608)
@@ -32,6 +32,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <tcl.h>
@@ -106,9 +107,13 @@
*
* Then it will leak memory :(
*/
-static void delete_reg(ClientData reg, Tcl_Interp* interp UNUSED) {
+static void delete_reg(ClientData reg, Tcl_Interp* interp) {
reg_error error;
if (((reg_registry*)reg)->status & reg_attached) {
+ if (Tcl_GetAssocData(interp, "registry::needs_vacuum", NULL) != NULL) {
+ reg_vacuum(Tcl_GetAssocData(interp, "registry::db_path", NULL));
+ Tcl_DeleteAssocData(interp, "registry::needs_vacuum");
+ }
if (!registry_tcl_detach(interp, (reg_registry*)reg, &error)) {
fprintf(stderr, "%s", error.description);
reg_error_destruct(&error);
@@ -120,6 +125,11 @@
}
}
+/* simple destructor for malloc()ed assoc data */
+static void free_assoc_data(ClientData ptr, Tcl_Interp* interp UNUSED) {
+ free(ptr);
+}
+
/**
* Returns the sqlite3 DB associated with interp.
*
@@ -168,6 +178,10 @@
char* path = Tcl_GetString(objv[1]);
reg_registry* reg = registry_for(interp, 0);
reg_error error;
+ if (Tcl_GetAssocData(interp, "registry::db_path", NULL) == NULL) {
+ char *pathCopy = strdup(path);
+ Tcl_SetAssocData(interp, "registry::db_path", free_assoc_data, pathCopy);
+ }
if (reg == NULL) {
return TCL_ERROR;
} else if (reg_attach(reg, path, &error)) {
@@ -189,6 +203,10 @@
return TCL_ERROR;
} else {
reg_error error;
+ if (Tcl_GetAssocData(interp, "registry::needs_vacuum", NULL) != NULL) {
+ reg_vacuum(Tcl_GetAssocData(interp, "registry::db_path", NULL));
+ Tcl_DeleteAssocData(interp, "registry::needs_vacuum");
+ }
if (registry_tcl_detach(interp, reg, &error)) {
return TCL_OK;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20100814/00886279/attachment.html>
More information about the macports-changes
mailing list