[78973] branches/gsoc11-rev-upgrade/base/src
cal at macports.org
cal at macports.org
Sat May 28 09:39:41 PDT 2011
Revision: 78973
http://trac.macports.org/changeset/78973
Author: cal at macports.org
Date: 2011-05-28 09:39:40 -0700 (Sat, 28 May 2011)
Log Message:
-----------
rev-upgrade:
registry2.0/
util.{h,c}:
- today in your "alchemy for the 21st century"-lesson: Reducing O(n^2) to O(n)
- removed unused function all_objects and it's dependency type set_object_function
entry.c, file.c:
- changes required by the interface change of unique_name
cregistry/
entry.c, util.{h,c}, registry.h:
- changes required by the interface change of unique_name
registry.c:
- changed reg->open_files Tcl HashMap to use string keys
file.c:
- changed adding entries to reg->open_files Tcl HashMap to use string keys
- changes required by the interface change of unique_name
- removed unused function reg_file_free
Modified Paths:
--------------
branches/gsoc11-rev-upgrade/base/src/cregistry/entry.c
branches/gsoc11-rev-upgrade/base/src/cregistry/file.c
branches/gsoc11-rev-upgrade/base/src/cregistry/registry.c
branches/gsoc11-rev-upgrade/base/src/cregistry/registry.h
branches/gsoc11-rev-upgrade/base/src/cregistry/util.c
branches/gsoc11-rev-upgrade/base/src/cregistry/util.h
branches/gsoc11-rev-upgrade/base/src/registry2.0/entry.c
branches/gsoc11-rev-upgrade/base/src/registry2.0/file.c
branches/gsoc11-rev-upgrade/base/src/registry2.0/util.c
branches/gsoc11-rev-upgrade/base/src/registry2.0/util.h
Modified: branches/gsoc11-rev-upgrade/base/src/cregistry/entry.c
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/cregistry/entry.c 2011-05-28 16:21:31 UTC (rev 78972)
+++ branches/gsoc11-rev-upgrade/base/src/cregistry/entry.c 2011-05-28 16:39:40 UTC (rev 78973)
@@ -77,7 +77,7 @@
* @return true if success; false if failure
*/
static int reg_stmt_to_entry(void* userdata, void** entry, void* stmt,
- reg_error* errPtr UNUSED) {
+ void* calldata UNUSED, reg_error* errPtr UNUSED) {
int is_new;
reg_registry* reg = (reg_registry*)userdata;
sqlite_int64 id = sqlite3_column_int64(stmt, 0);
@@ -182,6 +182,7 @@
reg_entry* entry = NULL;
char* query = "SELECT id FROM registry.ports WHERE name=? AND version=? "
"AND revision=? AND variants=? AND epoch=?";
+ int lower_bound = 0;
if ((sqlite3_prepare(reg->db, query, -1, &stmt, NULL) == SQLITE_OK)
&& (sqlite3_bind_text(stmt, 1, name, -1, SQLITE_STATIC)
== SQLITE_OK)
@@ -198,7 +199,7 @@
r = sqlite3_step(stmt);
switch (r) {
case SQLITE_ROW:
- reg_stmt_to_entry(reg, (void**)&entry, stmt, errPtr);
+ reg_stmt_to_entry(reg, (void**)&entry, stmt, &lower_bound, errPtr);
break;
case SQLITE_DONE:
errPtr->code = REG_NOT_FOUND;
@@ -339,8 +340,9 @@
*/
static int reg_all_entries(reg_registry* reg, char* query, int query_len,
reg_entry*** objects, reg_error* errPtr) {
+ int lower_bound = 0;
return reg_all_objects(reg, query, query_len, (void***)objects,
- reg_stmt_to_entry, NULL, errPtr);
+ reg_stmt_to_entry, &lower_bound, NULL, errPtr);
}
/**
@@ -486,6 +488,7 @@
int result = 0;
sqlite3_stmt* stmt = NULL;
char* query = "SELECT id FROM registry.files WHERE actual_path=? AND active";
+ int lower_bound = 0;
if ((sqlite3_prepare(reg->db, query, -1, &stmt, NULL) == SQLITE_OK)
&& (sqlite3_bind_text(stmt, 1, path, -1, SQLITE_STATIC)
== SQLITE_OK)) {
@@ -495,7 +498,7 @@
switch (r) {
case SQLITE_ROW:
result = reg_stmt_to_entry(reg, (void**)entry, stmt,
- errPtr);
+ &lower_bound, errPtr);
break;
case SQLITE_DONE:
*entry = NULL;
Modified: branches/gsoc11-rev-upgrade/base/src/cregistry/file.c
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/cregistry/file.c 2011-05-28 16:21:31 UTC (rev 78972)
+++ branches/gsoc11-rev-upgrade/base/src/cregistry/file.c 2011-05-28 16:39:40 UTC (rev 78973)
@@ -52,33 +52,42 @@
* @return true if success; false if failure
*/
static int reg_stmt_to_file(void* userdata, void** file, void* stmt,
- reg_error* errPtr UNUSED) {
+ void* calldata UNUSED, reg_error* errPtr UNUSED) {
int is_new;
reg_registry* reg = (reg_registry*)userdata;
reg_file_pk key;
Tcl_HashEntry* hash;
+ char* hashkey;
key.id = sqlite3_column_int64(stmt, 0);
- key.path = (char *) sqlite3_column_text(stmt, 1);
+ key.path = strdup((const char*) sqlite3_column_text(stmt, 1));
+ if (!key.path) {
+ return 0;
+ }
+ hashkey = sqlite3_mprintf("%lld:%s", key.id, key.path);
+ if (!hashkey) {
+ free(key.path);
+ return 0;
+ }
hash = Tcl_CreateHashEntry(®->open_files,
- (const char*)&key.id, &is_new);
+ hashkey, &is_new);
+ sqlite3_free(hashkey);
+
if (is_new) {
reg_file* f = malloc(sizeof(reg_file));
if (!f) {
+ free(key.path);
return 0;
}
f->reg = reg;
f->key.id = key.id;
- f->key.path = strdup(key.path);
- if (!f->key.path) {
- free(f);
- return 0;
- }
+ f->key.path = key.path;
f->proc = NULL;
*file = f;
Tcl_SetHashValue(hash, f);
} else {
+ free(key.path);
*file = Tcl_GetHashValue(hash);
}
return 1;
@@ -98,6 +107,7 @@
sqlite3_stmt* stmt = NULL;
reg_file* file = NULL;
char* query = "SELECT id, path FORM registry.files WHERE id=? AND version=?";
+ int lower_bound = 0;
if ((sqlite3_prepare(reg->db, query, -1, &stmt, NULL) == SQLITE_OK)
&& (sqlite3_bind_text(stmt, 1, id, -1, SQLITE_STATIC)
@@ -109,7 +119,8 @@
r = sqlite3_step(stmt);
switch (r) {
case SQLITE_ROW:
- reg_stmt_to_file(reg, (void**)&file, stmt, errPtr);
+ reg_stmt_to_file(reg, (void**)&file, stmt, &lower_bound,
+ errPtr);
break;
case SQLITE_DONE:
errPtr->code = REG_NOT_FOUND;
@@ -134,26 +145,6 @@
}
/**
- * Frees a file. Normally this is unnecessary, as open entries will be
- * automatically freed when the registry is detached. Calling this method
- * externally should only be necessary following `reg_entry_delete`.
- *
- * @param [in] entry the entry to free
- */
-void reg_file_free(reg_file* file) {
- Tcl_HashEntry* hash = Tcl_FindHashEntry(&file->reg->open_files,
- (const char*)&file->key.id);
- Tcl_DeleteHashEntry(hash);
- if (file->proc != NULL) {
- free(file->proc);
- }
- if (file->key.path) {
- free(file->key.path);
- }
- free(file);
-}
-
-/**
* Type-safe version of `reg_all_objects` for `reg_file`.
*
* @param [in] reg registry to select entries from
@@ -165,8 +156,9 @@
*/
static int reg_all_files(reg_registry* reg, char* query, int query_len,
reg_file*** objects, reg_error* errPtr) {
+ int lower_bound = 0;
return reg_all_objects(reg, query, query_len, (void***)objects,
- reg_stmt_to_file, NULL, errPtr);
+ reg_stmt_to_file, &lower_bound, NULL, errPtr);
}
/**
Modified: branches/gsoc11-rev-upgrade/base/src/cregistry/registry.c
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/cregistry/registry.c 2011-05-28 16:21:31 UTC (rev 78972)
+++ branches/gsoc11-rev-upgrade/base/src/cregistry/registry.c 2011-05-28 16:39:40 UTC (rev 78973)
@@ -212,8 +212,7 @@
Tcl_InitHashTable(®->open_entries,
sizeof(sqlite_int64)/sizeof(int));
Tcl_InitHashTable(®->open_files,
- (sizeof(sqlite_int64)+sizeof(char*)) /
- sizeof(int));
+ TCL_STRING_KEYS);
reg->status |= reg_attached;
result = 1;
}
Modified: branches/gsoc11-rev-upgrade/base/src/cregistry/registry.h
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/cregistry/registry.h 2011-05-28 16:21:31 UTC (rev 78972)
+++ branches/gsoc11-rev-upgrade/base/src/cregistry/registry.h 2011-05-28 16:39:40 UTC (rev 78973)
@@ -57,7 +57,7 @@
void reg_throw(reg_error* errPtr, char* code, char* fmt, ...);
typedef int (cast_function)(void* userdata, void** dst, void* src,
- reg_error* errPtr);
+ void* calldata, reg_error* errPtr);
typedef void (free_function)(void* userdata, void* item);
enum {
Modified: branches/gsoc11-rev-upgrade/base/src/cregistry/util.c
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/cregistry/util.c 2011-05-28 16:21:31 UTC (rev 78972)
+++ branches/gsoc11-rev-upgrade/base/src/cregistry/util.c 2011-05-28 16:39:40 UTC (rev 78973)
@@ -127,8 +127,8 @@
* @return the number of objects if success; negative if failure
*/
int reg_all_objects(reg_registry* reg, char* query, int query_len,
- void*** objects, cast_function* fn, free_function* del,
- reg_error* errPtr) {
+ void*** objects, cast_function* fn, void* castcalldata,
+ free_function* del, reg_error* errPtr) {
void** results = malloc(10*sizeof(void*));
int result_count = 0;
int result_space = 10;
@@ -143,7 +143,7 @@
r = sqlite3_step(stmt);
switch (r) {
case SQLITE_ROW:
- if (fn(reg, &row, stmt, errPtr)) {
+ if (fn(reg, &row, stmt, castcalldata, errPtr)) {
if (!reg_listcat(&results, &result_count, &result_space, row)) {
r = SQLITE_ERROR;
}
Modified: branches/gsoc11-rev-upgrade/base/src/cregistry/util.h
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/cregistry/util.h 2011-05-28 16:21:31 UTC (rev 78972)
+++ branches/gsoc11-rev-upgrade/base/src/cregistry/util.h 2011-05-28 16:39:40 UTC (rev 78973)
@@ -45,8 +45,8 @@
int reg_strcat(char** dst, size_t* dst_len, size_t* dst_space, char* src);
int reg_listcat(void*** dst, int* dst_len, int* dst_space, void* src);
int reg_all_objects(reg_registry* reg, char* query, int query_len,
- void*** objects, cast_function* fn, free_function* del,
- reg_error* errPtr);
+ void*** objects, cast_function* fn, void* castcalldata,
+ free_function* del, reg_error* errPtr);
char* reg_strategy_op(reg_strategy strategy, reg_error* errPtr);
#endif /* _CUTIL_H */
Modified: branches/gsoc11-rev-upgrade/base/src/registry2.0/entry.c
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/registry2.0/entry.c 2011-05-28 16:21:31 UTC (rev 78972)
+++ branches/gsoc11-rev-upgrade/base/src/registry2.0/entry.c 2011-05-28 16:39:40 UTC (rev 78973)
@@ -114,7 +114,7 @@
variants, epoch, &error);
if (entry != NULL) {
Tcl_Obj* result;
- if (entry_to_obj(interp, &result, entry, &error)) {
+ if (entry_to_obj(interp, &result, entry, NULL, &error)) {
Tcl_SetObjResult(interp, result);
return TCL_OK;
}
@@ -194,7 +194,7 @@
variants, epoch, &error);
if (entry != NULL) {
Tcl_Obj* result;
- if (entry_to_obj(interp, &result, entry, &error)) {
+ if (entry_to_obj(interp, &result, entry, NULL, &error)) {
Tcl_SetObjResult(interp, result);
return TCL_OK;
}
@@ -457,7 +457,7 @@
return TCL_OK;
} else {
Tcl_Obj* result;
- if (entry_to_obj(interp, &result, entry, &error)) {
+ if (entry_to_obj(interp, &result, entry, NULL, &error)) {
Tcl_SetObjResult(interp, result);
return TCL_OK;
}
Modified: branches/gsoc11-rev-upgrade/base/src/registry2.0/file.c
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/registry2.0/file.c 2011-05-28 16:21:31 UTC (rev 78972)
+++ branches/gsoc11-rev-upgrade/base/src/registry2.0/file.c 2011-05-28 16:39:40 UTC (rev 78973)
@@ -90,7 +90,7 @@
reg_file* file = reg_file_open(reg, id, path, &error);
if (file != NULL) {
Tcl_Obj* result;
- if (file_to_obj(interp, &result, file, &error)) {
+ if (file_to_obj(interp, &result, file, NULL, &error)) {
Tcl_SetObjResult(interp, result);
return TCL_OK;
}
Modified: branches/gsoc11-rev-upgrade/base/src/registry2.0/util.c
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/registry2.0/util.c 2011-05-28 16:21:31 UTC (rev 78972)
+++ branches/gsoc11-rev-upgrade/base/src/registry2.0/util.c 2011-05-28 16:39:40 UTC (rev 78973)
@@ -46,24 +46,28 @@
* Tcl interp context. This behavior is similar to that of the builtin
* `interp create` command, and is intended to generate names for created
* objects of a similar nature.
- *
- * TODO: add a int* parameter so that functions which need large numbers of
- * unique names can keep track of the lower bound between calls,thereby turning
- * N^2 to N. It'll be alchemy for the 21st century.
*/
-char* unique_name(Tcl_Interp* interp, char* prefix) {
+char* unique_name(Tcl_Interp* interp, char* prefix, int* lower_bound) {
int result_size = strlen(prefix) + TCL_INTEGER_SPACE + 1;
char* result = malloc(result_size);
Tcl_CmdInfo info;
int i;
if (!result)
return NULL;
- for (i=0; ; i++) {
+ if (lower_bound == NULL) {
+ i = 0;
+ } else {
+ i = *lower_bound;
+ }
+ for (; ; i++) {
snprintf(result, result_size, "%s%d", prefix, i);
if (Tcl_GetCommandInfo(interp, result, &info) == 0) {
break;
}
}
+ if (lower_bound != NULL) {
+ *lower_bound = i + 1;
+ }
return result;
}
@@ -226,47 +230,6 @@
}
}
-/**
- * Sets the result of the interpreter to all objects returned by a query.
- *
- * This function executes `query` on `db` It expects that the query will return
- * records of a single column, `rowid`. It will then use `prefix` to construct
- * unique names for these records, and call `setter` to construct their proc
- * objects. The result of `interp` will be set to a list of all such objects.
- *
- * If TCL_OK is returned, then a list is in the result. If TCL_ERROR is, then an
- * error is there.
- */
-int all_objects(Tcl_Interp* interp, sqlite3* db, char* query, char* prefix,
- set_object_function* setter) {
- sqlite3_stmt* stmt;
- if (sqlite3_prepare(db, query, -1, &stmt, NULL) == SQLITE_OK) {
- Tcl_Obj* result = Tcl_NewListObj(0, NULL);
- Tcl_SetObjResult(interp, result);
- while (sqlite3_step(stmt) == SQLITE_ROW) {
- sqlite_int64 rowid = sqlite3_column_int64(stmt, 0);
- char* name = unique_name(interp, prefix);
- if (!name) {
- return TCL_ERROR;
- }
- if (setter(interp, name, rowid) == TCL_OK) {
- Tcl_Obj* element = Tcl_NewStringObj(name, -1);
- Tcl_ListObjAppendElement(interp, result, element);
- free(name);
- } else {
- free(name);
- return TCL_ERROR;
- }
- }
- sqlite3_finalize(stmt);
- return TCL_OK;
- } else {
- sqlite3_finalize(stmt);
- set_sqlite_result(interp, db, query);
- return TCL_ERROR;
- }
-}
-
const char* string_or_null(Tcl_Obj* obj) {
const char* string = Tcl_GetString(obj);
if (string[0] == '\0') {
@@ -276,15 +239,16 @@
}
}
-int recast(void* userdata, cast_function* fn, free_function* del, void*** outv,
- void** inv, int inc, reg_error* errPtr) {
+int recast(void* userdata, cast_function* fn, void* castcalldata,
+ free_function* del, void*** outv, void** inv, int inc,
+ reg_error* errPtr) {
void** result = malloc(inc*sizeof(void*));
int i;
if (!result) {
return 0;
}
for (i=0; i<inc; i++) {
- if (!fn(userdata, &result[i], inv[i], errPtr)) {
+ if (!fn(userdata, &result[i], inv[i], castcalldata, errPtr)) {
if (del != NULL) {
for ( ; i>=0; i--) {
del(userdata, result[i]);
@@ -299,9 +263,9 @@
}
int entry_to_obj(Tcl_Interp* interp, Tcl_Obj** obj, reg_entry* entry,
- reg_error* errPtr) {
+ int* lower_bound, reg_error* errPtr) {
if (entry->proc == NULL) {
- char* name = unique_name(interp, "::registry::entry");
+ char* name = unique_name(interp, "::registry::entry", lower_bound);
if (!name) {
return 0;
}
@@ -316,9 +280,9 @@
}
int file_to_obj(Tcl_Interp* interp, Tcl_Obj** obj, reg_file* file,
- reg_error* errPtr) {
+ int* lower_bound, reg_error* errPtr) {
if (file->proc == NULL) {
- char* name = unique_name(interp, "::registry::file");
+ char* name = unique_name(interp, "::registry::file", lower_bound);
if (!name) {
return 0;
}
@@ -326,6 +290,7 @@
free(name);
return 0;
}
+ free(name);
}
*obj = Tcl_NewStringObj(file->proc, -1);
return 1;
@@ -333,30 +298,32 @@
int list_entry_to_obj(Tcl_Interp* interp, Tcl_Obj*** objs,
reg_entry** entries, int entry_count, reg_error* errPtr) {
- return recast(interp, (cast_function*)entry_to_obj, NULL, (void***)objs,
- (void**)entries, entry_count, errPtr);
+ int lower_bound = 0;
+ return recast(interp, (cast_function*)entry_to_obj, &lower_bound, NULL,
+ (void***)objs, (void**)entries, entry_count, errPtr);
}
int list_file_to_obj(Tcl_Interp* interp, Tcl_Obj*** objs,
reg_file** files, int file_count, reg_error* errPtr) {
- return recast(interp, (cast_function*)file_to_obj, NULL, (void***)objs,
- (void**)files, file_count, errPtr);
+ int lower_bound = 0;
+ return recast(interp, (cast_function*)file_to_obj, &lower_bound, NULL,
+ (void***)objs, (void**)files, file_count, errPtr);
}
static int obj_to_string(void* userdata UNUSED, char** string, Tcl_Obj* obj,
- reg_error* errPtr UNUSED) {
+ void* param UNUSED, reg_error* errPtr UNUSED) {
*string = Tcl_GetString(obj);
return 1;
}
int list_obj_to_string(char*** strings, Tcl_Obj** objv, int objc,
reg_error* errPtr) {
- return recast(NULL, (cast_function*)obj_to_string, NULL, (void***)strings,
+ return recast(NULL, (cast_function*)obj_to_string, NULL, NULL, (void***)strings,
(void**)objv, objc, errPtr);
}
static int string_to_obj(void* userdata UNUSED, Tcl_Obj** obj, char* string,
- reg_error* errPtr UNUSED) {
+ void* param UNUSED, reg_error* errPtr UNUSED) {
*obj = Tcl_NewStringObj(string, -1);
return 1;
}
@@ -367,6 +334,6 @@
int list_string_to_obj(Tcl_Obj*** objv, char** strings, int objc,
reg_error* errPtr) {
- return recast(NULL, (cast_function*)string_to_obj, (free_function*)free_obj,
+ return recast(NULL, (cast_function*)string_to_obj, NULL, (free_function*)free_obj,
(void***)objv, (void**)strings, objc, errPtr);
}
Modified: branches/gsoc11-rev-upgrade/base/src/registry2.0/util.h
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/registry2.0/util.h 2011-05-28 16:21:31 UTC (rev 78972)
+++ branches/gsoc11-rev-upgrade/base/src/registry2.0/util.h 2011-05-28 16:39:40 UTC (rev 78973)
@@ -46,7 +46,7 @@
#define END_FLAGS 0
-char* unique_name(Tcl_Interp* interp, char* prefix);
+char* unique_name(Tcl_Interp* interp, char* prefix, int* lower_bound);
int parse_flags(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[], int* start,
option_spec options[], int* flags);
@@ -58,28 +58,24 @@
int set_entry(Tcl_Interp* interp, char* name, reg_entry* entry,
reg_error* errPtr);
int set_file(Tcl_Interp* interp, char* name, reg_file* file,
- reg_error* errPtr);
+ reg_error* errPtr);
void set_sqlite_result(Tcl_Interp* interp, sqlite3* db, const char* query);
-typedef int set_object_function(Tcl_Interp* interp, char* name,
- sqlite_int64 rowid);
-int all_objects(Tcl_Interp* interp, sqlite3* db, char* query, char* prefix,
- set_object_function* setter);
-
const char* string_or_null(Tcl_Obj* obj);
-int recast(void* userdata, cast_function* fn, free_function* del, void*** outv,
- void** inv, int inc, reg_error* errPtr);
+int recast(void* userdata, cast_function* fn, void* castcalldata,
+ free_function* del, void*** outv, void** inv, int inc,
+ reg_error* errPtr);
int entry_to_obj(Tcl_Interp* interp, Tcl_Obj** obj, reg_entry* entry,
- reg_error* errPtr);
+ int* lower_bound, reg_error* errPtr);
int list_entry_to_obj(Tcl_Interp* interp, Tcl_Obj*** objs,
reg_entry** entries, int entry_count, reg_error* errPtr);
int file_to_obj(Tcl_Interp* interp, Tcl_Obj** ibj, reg_file* file,
- reg_error* errPtr);
+ int* lower_bound, reg_error* errPtr);
int list_file_to_obj(Tcl_Interp* interp, Tcl_Obj*** objs,
- reg_file** files, int file_count, reg_error* errPtr);
+ reg_file** files, int file_count, reg_error* errPtr);
void free_strings(void* userdata UNUSED, char** strings, int count);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20110528/ae5fe014/attachment-0001.html>
More information about the macports-changes
mailing list