Changeset 70608


Ignore:
Timestamp:
Aug 15, 2010, 4:24:06 AM (10 years ago)
Author:
jmr@…
Message:

vacuum registry database before closing if any entries have been deleted

Location:
trunk/base/src
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/base/src/cregistry/registry.c

    r70122 r70608  
    402402    }
    403403}
     404
     405/**
     406 * Runs VACUUM (compact/defragment) on the given db file.
     407 * Works on a path rather than an open db pointer because you can't vacuum an
     408 * attached db, which is what the rest of the registry uses for some reason.
     409 *
     410 * @param [in] db_path path to db file to vacuum
     411 * @return             true if success; false if failure
     412 */
     413int reg_vacuum(char *db_path) {
     414    sqlite3* db;
     415    sqlite3_stmt* stmt = NULL;
     416    int result = 0;
     417    reg_error err;
     418
     419    if (sqlite3_open(db_path, &db) == SQLITE_OK) {
     420        if (!init_db(db, &err)) {
     421            sqlite3_close(db);
     422            return 0;
     423        }
     424    } else {
     425        return 0;
     426    }
     427
     428    if (sqlite3_prepare(db, "VACUUM", -1, &stmt, NULL) == SQLITE_OK) {
     429        int r;
     430        /* XXX: Busy waiting, consider using sqlite3_busy_handler/timeout */
     431        do {
     432            sqlite3_step(stmt);
     433            r = sqlite3_reset(stmt);
     434            if (r == SQLITE_OK) {
     435                result = 1;
     436            }
     437        } while (r == SQLITE_BUSY);
     438    }
     439    if (stmt) {
     440        sqlite3_finalize(stmt);
     441    }
     442    sqlite3_close(db);
     443    return result;
     444}
  • trunk/base/src/cregistry/registry.h

    r28029 r70608  
    8484int reg_rollback(reg_registry* reg, reg_error* errPtr);
    8585
     86int reg_vacuum(char* db_path);
     87
    8688#endif /* _CREG_H */
  • trunk/base/src/macports1.0/macports.tcl

    r70174 r70608  
    973973            }
    974974        }
     975    }
     976}
     977
     978# call this just before you exit
     979proc mportshutdown {} {
     980    global macports::registry.format
     981    if {${registry.format} == "receipt_sqlite"} {
     982        # close it down so the cleanup stuff is called, e.g. vacuuming the db
     983        registry::close
    975984    }
    976985}
  • trunk/base/src/port/port.tcl

    r70321 r70608  
    44674467}
    44684468
     4469# shut down macports1.0
     4470mportshutdown
     4471
    44694472# Return with exit_status
    44704473exit $exit_status
  • trunk/base/src/registry2.0/entry.c

    r64304 r70608  
    163163        }
    164164        Tcl_DeleteCommand(interp, Tcl_GetString(objv[2]));
     165        /* set flag so that the db will be vacuumed when we close it */
     166        Tcl_SetAssocData(interp, "registry::needs_vacuum", NULL, (ClientData)1);
    165167        return TCL_OK;
    166168    }
  • trunk/base/src/registry2.0/registry.c

    r64304 r70608  
    3333#include <stdio.h>
    3434#include <stdlib.h>
     35#include <string.h>
    3536#include <unistd.h>
    3637#include <tcl.h>
     
    107108 * Then it will leak memory :(
    108109 */
    109 static void delete_reg(ClientData reg, Tcl_Interp* interp UNUSED) {
     110static void delete_reg(ClientData reg, Tcl_Interp* interp) {
    110111    reg_error error;
    111112    if (((reg_registry*)reg)->status & reg_attached) {
     113        if (Tcl_GetAssocData(interp, "registry::needs_vacuum", NULL) != NULL) {
     114            reg_vacuum(Tcl_GetAssocData(interp, "registry::db_path", NULL));
     115            Tcl_DeleteAssocData(interp, "registry::needs_vacuum");
     116        }
    112117        if (!registry_tcl_detach(interp, (reg_registry*)reg, &error)) {
    113118            fprintf(stderr, "%s", error.description);
     
    119124        reg_error_destruct(&error);
    120125    }
     126}
     127
     128/* simple destructor for malloc()ed assoc data */
     129static void free_assoc_data(ClientData ptr, Tcl_Interp* interp UNUSED) {
     130    free(ptr);
    121131}
    122132
     
    169179        reg_registry* reg = registry_for(interp, 0);
    170180        reg_error error;
     181        if (Tcl_GetAssocData(interp, "registry::db_path", NULL) == NULL) {
     182            char *pathCopy = strdup(path);
     183            Tcl_SetAssocData(interp, "registry::db_path", free_assoc_data, pathCopy);
     184        }
    171185        if (reg == NULL) {
    172186            return TCL_ERROR;
     
    190204        } else {
    191205            reg_error error;
     206            if (Tcl_GetAssocData(interp, "registry::needs_vacuum", NULL) != NULL) {
     207                reg_vacuum(Tcl_GetAssocData(interp, "registry::db_path", NULL));
     208                Tcl_DeleteAssocData(interp, "registry::needs_vacuum");
     209            }
    192210            if (registry_tcl_detach(interp, reg, &error)) {
    193211                return TCL_OK;
Note: See TracChangeset for help on using the changeset viewer.