From laffer1 at midnightbsd.org  Mon May 27 10:30:31 2019
From: laffer1 at midnightbsd.org (laffer1 at midnightbsd.org)
Date: Mon, 27 May 2019 10:30:31 -0400 (EDT)
Subject: [Midnightbsd-cvs] src [12205] trunk/lib/libmport/db.c: add retry
 algorithm
Message-ID: <201905271430.x4REUVh5093823@stargazer.midnightbsd.org>

Revision: 12205
          http://svnweb.midnightbsd.org/src/?rev=12205
Author:   laffer1
Date:     2019-05-27 10:30:30 -0400 (Mon, 27 May 2019)
Log Message:
-----------
add retry algorithm

Modified Paths:
--------------
    trunk/lib/libmport/db.c

Modified: trunk/lib/libmport/db.c
===================================================================
--- trunk/lib/libmport/db.c	2019-05-26 17:22:01 UTC (rev 12204)
+++ trunk/lib/libmport/db.c	2019-05-27 14:30:30 UTC (rev 12205)
@@ -110,14 +110,19 @@
 		RETURN_ERROR(MPORT_ERR_FATAL, "Couldn't allocate memory for sql statement");
 
 	dispatch_sync(mportSQLSerial, ^{
+		int tries = 0;
 		int sqlcode = sqlite3_prepare_v2(db, sql, -1, stmt, NULL);
-		if (sqlcode == SQLITE_BUSY || sqlcode == SQLITE_LOCKED) {
-			sleep(1);
-			if (sqlite3_prepare_v2(db, sql, -1, stmt, NULL) != SQLITE_OK) {
+
+		while(sqlcode == SQLITE_BUSY || sqlcode == SQLITE_LOCKED) {
+			usleep(200000); // 0.2 second
+			sqlcode = sqlite3_prepare_v2(db, sql, -1, stmt, NULL);
+			if (tries > 10) {
 				err = (char *) sqlite3_errmsg(db);
 				result = MPORT_ERR_FATAL;
 			}
-		} else if (sqlcode != SQLITE_OK) {
+		}
+
+		if (sqlcode != SQLITE_OK) {
 			err = (char *) sqlite3_errmsg(db);
 			result = MPORT_ERR_FATAL;
 		}


From laffer1 at midnightbsd.org  Mon May 27 10:30:49 2019
From: laffer1 at midnightbsd.org (laffer1 at midnightbsd.org)
Date: Mon, 27 May 2019 10:30:49 -0400 (EDT)
Subject: [Midnightbsd-cvs] src [12206] trunk/lib/libmport/index_depends.c:
 use count function
Message-ID: <201905271430.x4REUnWJ093874@stargazer.midnightbsd.org>

Revision: 12206
          http://svnweb.midnightbsd.org/src/?rev=12206
Author:   laffer1
Date:     2019-05-27 10:30:48 -0400 (Mon, 27 May 2019)
Log Message:
-----------
use count function

Modified Paths:
--------------
    trunk/lib/libmport/index_depends.c

Modified: trunk/lib/libmport/index_depends.c
===================================================================
--- trunk/lib/libmport/index_depends.c	2019-05-27 14:30:30 UTC (rev 12205)
+++ trunk/lib/libmport/index_depends.c	2019-05-27 14:30:48 UTC (rev 12206)
@@ -55,36 +55,17 @@
   
 	MPORT_CHECK_FOR_INDEX(mport, "mport_index_depends_list()")
 
-	if (mport_db_prepare(mport->db, &stmt,
-	    "with RECURSIVE under_dep (parent, parent_ver, pkg, version, level) as ( values('?', '?',  %Q, %Q, 0) union all select depends.pkg as parent, depends.version as parent_ver, depends.d_pkg as pkg, depends.d_version as version, under_dep.level + 1 from depends JOIN under_dep on depends.pkg = under_dep.pkg) select count(*) FROM under_dep where level > 0;",
-	    pkgname, version) != MPORT_OK) {
-		sqlite3_finalize(stmt);
+	if (mport_db_count(mport->db, &count,
+		"with RECURSIVE under_dep (parent, parent_ver, pkg, version, level) as ( values('?', '?',  %Q, %Q, 0) union all select depends.pkg as parent, depends.version as parent_ver, depends.d_pkg as pkg, depends.d_version as version, under_dep.level + 1 from depends JOIN under_dep on depends.pkg = under_dep.pkg) select count(*) FROM under_dep where level > 0;",
+			   pkgname, version) != MPORT_OK)
 		RETURN_CURRENT_ERROR;
-	}
 
-	switch (sqlite3_step(stmt)) {
-		case SQLITE_ROW:
-			count = sqlite3_column_int(stmt, 0);
-			break;
-		case SQLITE_DONE:
-			ret = SET_ERROR(MPORT_ERR_FATAL,
-					"No rows returned from a 'SELECT COUNT(*)' query.");
-			goto DONE;
-			break;
-		default:
-			ret = SET_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(mport->db));
-			goto DONE;
-			break;
-	}
+	if (count == 0)
+		return MPORT_OK;
   
-	sqlite3_finalize(stmt);
-  
 	e = (mportDependsEntry **)calloc(count + 1, sizeof(mportDependsEntry *));
 	*entry_vec = e;
   
-	if (count == 0) 
-		return MPORT_OK;
-  
 	if (mport_db_prepare(mport->db, &stmt,
 		 "with RECURSIVE under_dep (parent, parent_ver, pkg, version, level) as ( values('?', '?',  %Q, %Q, 0) union all select depends.pkg as parent, depends.version as parent_ver, depends.d_pkg as pkg, depends.d_version as version, under_dep.level + 1 from depends JOIN under_dep on depends.pkg = under_dep.pkg) select parent, parent_ver, pkg, version, level FROM under_dep where level > 0;"
 		, pkgname, version) != MPORT_OK) {


From laffer1 at midnightbsd.org  Mon May 27 11:26:23 2019
From: laffer1 at midnightbsd.org (laffer1 at midnightbsd.org)
Date: Mon, 27 May 2019 11:26:23 -0400 (EDT)
Subject: [Midnightbsd-cvs] src [12207] trunk/lib/libmport: revert recursive
 query logic.
Message-ID: <201905271526.x4RFQNcS097203@stargazer.midnightbsd.org>

Revision: 12207
          http://svnweb.midnightbsd.org/src/?rev=12207
Author:   laffer1
Date:     2019-05-27 11:26:22 -0400 (Mon, 27 May 2019)
Log Message:
-----------
revert recursive query logic. does not play nice with libdispatch

Modified Paths:
--------------
    trunk/lib/libmport/bundle_read_install_pkg.c
    trunk/lib/libmport/db.c
    trunk/lib/libmport/error.c
    trunk/lib/libmport/index.c
    trunk/lib/libmport/index_depends.c
    trunk/lib/libmport/install.c
    trunk/lib/libmport/install_primative.c
    trunk/lib/libmport/mport.h

Modified: trunk/lib/libmport/bundle_read_install_pkg.c
===================================================================
--- trunk/lib/libmport/bundle_read_install_pkg.c	2019-05-27 14:30:48 UTC (rev 12206)
+++ trunk/lib/libmport/bundle_read_install_pkg.c	2019-05-27 15:26:22 UTC (rev 12207)
@@ -136,8 +136,7 @@
 	return MPORT_OK;
 
 	ERROR:
-	if (alist != NULL)
-		mport_assetlist_free(alist);
+	// TODO: asset list free
 	RETURN_CURRENT_ERROR;
 }
 
@@ -947,9 +946,6 @@
 		/* if we couldn't stat the file, we assume there isn't a pkg-msg */
 		return MPORT_OK;
 
-	if (st.st_size < 1)
-		return MPORT_OK;
-
 	if ((file = fopen(filename, "r")) == NULL)
 		RETURN_ERRORX(MPORT_ERR_FATAL, "Couldn't open %s: %s", filename, strerror(errno));
 

Modified: trunk/lib/libmport/db.c
===================================================================
--- trunk/lib/libmport/db.c	2019-05-27 14:30:48 UTC (rev 12206)
+++ trunk/lib/libmport/db.c	2019-05-27 15:26:22 UTC (rev 12207)
@@ -110,19 +110,14 @@
 		RETURN_ERROR(MPORT_ERR_FATAL, "Couldn't allocate memory for sql statement");
 
 	dispatch_sync(mportSQLSerial, ^{
-		int tries = 0;
 		int sqlcode = sqlite3_prepare_v2(db, sql, -1, stmt, NULL);
-
-		while(sqlcode == SQLITE_BUSY || sqlcode == SQLITE_LOCKED) {
-			usleep(200000); // 0.2 second
-			sqlcode = sqlite3_prepare_v2(db, sql, -1, stmt, NULL);
-			if (tries > 10) {
+		if (sqlcode == SQLITE_BUSY || sqlcode == SQLITE_LOCKED) {
+			sleep(1);
+			if (sqlite3_prepare_v2(db, sql, -1, stmt, NULL) != SQLITE_OK) {
 				err = (char *) sqlite3_errmsg(db);
 				result = MPORT_ERR_FATAL;
 			}
-		}
-
-		if (sqlcode != SQLITE_OK) {
+		} else if (sqlcode != SQLITE_OK) {
 			err = (char *) sqlite3_errmsg(db);
 			result = MPORT_ERR_FATAL;
 		}

Modified: trunk/lib/libmport/error.c
===================================================================
--- trunk/lib/libmport/error.c	2019-05-27 14:30:48 UTC (rev 12206)
+++ trunk/lib/libmport/error.c	2019-05-27 15:26:22 UTC (rev 12207)
@@ -37,7 +37,7 @@
 static char err_msg[256];
 
 /* This goes with the error codes in mport.h */
-static char default_error_msg[] = "An error occurred.";
+static char default_error_msg[] = "An error occured.";
 
 
 /* mport_err_code()
@@ -45,9 +45,8 @@
  * Return the current numeric error code. 
  */
 MPORT_PUBLIC_API int
-mport_err_code(void)
-{
-	return mport_err;
+mport_err_code(void) {
+    return mport_err;
 }
 
 /* mport_err_string()
@@ -55,9 +54,8 @@
  * Return the current error string (if any).  Do not free this memory, it is static. 
  */
 MPORT_PUBLIC_API const char *
-mport_err_string(void)
-{
-	return err_msg;
+mport_err_string(void) {
+    return err_msg;
 }
 
 
@@ -69,20 +67,19 @@
  * be used if msg is NULL
  */
 int
-mport_set_err(int code, const char *msg)
-{
-	mport_err = code;
+mport_set_err(int code, const char *msg) {
+    mport_err = code;
 
-	if (code == MPORT_OK) {
-		bzero(err_msg, sizeof(err_msg));
-	} else {
-		if (msg != NULL) {
-			strlcpy(err_msg, msg, sizeof(err_msg));
-		} else {
-			strlcpy(err_msg, default_error_msg, sizeof(err_msg));
-		}
-	}
-	return code;
+    if (code == MPORT_OK) {
+        bzero(err_msg, sizeof(err_msg));
+    } else {
+        if (msg != NULL) {
+            strlcpy(err_msg, msg, sizeof(err_msg));
+        } else {
+            strlcpy(err_msg, default_error_msg, sizeof(err_msg));
+        }
+    }
+    return code;
 }
 
 
@@ -94,19 +91,19 @@
  */
 int
 mport_set_errx(int code, const char *fmt, ...) {
-	va_list args;
-	char *err;
-	int ret;
+    va_list args;
+    char *err;
+    int ret;
 
-	va_start(args, fmt);
-	if (vasprintf(&err, fmt, args) == -1) {
-		fprintf(stderr, "fatal error: mport_set_errx can't format the string.\n");
-		exit(255);
-	}
-	ret = mport_set_err(code, err);
-	free(err);
+    va_start(args, fmt);
+    if (vasprintf(&err, fmt, args) == -1) {
+        fprintf(stderr, "fatal error: mport_set_errx can't format the string.\n");
+        exit(255);
+    }
+    ret = mport_set_err(code, err);
+    free(err);
 
-	va_end(args);
+    va_end(args);
 
-	return ret;
+    return ret;
 }

Modified: trunk/lib/libmport/index.c
===================================================================
--- trunk/lib/libmport/index.c	2019-05-27 14:30:48 UTC (rev 12206)
+++ trunk/lib/libmport/index.c	2019-05-27 15:26:22 UTC (rev 12207)
@@ -35,7 +35,6 @@
 #include <time.h>
 #include <string.h>
 #include <stdlib.h>
-#include <stdint.h>
 #include <errno.h>
 #include <stddef.h>
 

Modified: trunk/lib/libmport/index_depends.c
===================================================================
--- trunk/lib/libmport/index_depends.c	2019-05-27 14:30:48 UTC (rev 12206)
+++ trunk/lib/libmport/index_depends.c	2019-05-27 15:26:22 UTC (rev 12207)
@@ -55,20 +55,38 @@
   
 	MPORT_CHECK_FOR_INDEX(mport, "mport_index_depends_list()")
 
-	if (mport_db_count(mport->db, &count,
-		"with RECURSIVE under_dep (parent, parent_ver, pkg, version, level) as ( values('?', '?',  %Q, %Q, 0) union all select depends.pkg as parent, depends.version as parent_ver, depends.d_pkg as pkg, depends.d_version as version, under_dep.level + 1 from depends JOIN under_dep on depends.pkg = under_dep.pkg) select count(*) FROM under_dep where level > 0;",
-			   pkgname, version) != MPORT_OK)
+	if (mport_db_prepare(mport->db, &stmt,
+	    "SELECT COUNT(*) FROM idx.depends WHERE pkg = %Q and version = %Q",
+	    pkgname, version) != MPORT_OK) {
+		sqlite3_finalize(stmt);
 		RETURN_CURRENT_ERROR;
-
-	if (count == 0)
-		return MPORT_OK;
+	}
+ 
+	switch (sqlite3_step(stmt)) {
+	case SQLITE_ROW:
+		count = sqlite3_column_int(stmt, 0);
+		break;
+	case SQLITE_DONE:
+		ret = SET_ERROR(MPORT_ERR_FATAL,
+		    "No rows returned from a 'SELECT COUNT(*)' query.");
+		goto DONE;
+		break;
+	default:
+		ret = SET_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(mport->db));
+		goto DONE;
+		break;
+	}
   
+	sqlite3_finalize(stmt);
+  
 	e = (mportDependsEntry **)calloc(count + 1, sizeof(mportDependsEntry *));
 	*entry_vec = e;
   
+	if (count == 0) 
+		return MPORT_OK;
+  
 	if (mport_db_prepare(mport->db, &stmt,
-		 "with RECURSIVE under_dep (parent, parent_ver, pkg, version, level) as ( values('?', '?',  %Q, %Q, 0) union all select depends.pkg as parent, depends.version as parent_ver, depends.d_pkg as pkg, depends.d_version as version, under_dep.level + 1 from depends JOIN under_dep on depends.pkg = under_dep.pkg) select parent, parent_ver, pkg, version, level FROM under_dep where level > 0;"
-		, pkgname, version) != MPORT_OK) {
+	    "SELECT pkg, version, d_pkg, d_version FROM idx.depends WHERE pkg= %Q and version=%Q", pkgname, version) != MPORT_OK) {
 		ret = mport_err_code();
 		goto DONE;
 	}
@@ -81,16 +99,11 @@
 				ret = MPORT_ERR_FATAL;
 				goto DONE;
 			}
-
-			/* parent, parent_ver, pkg, version, level */
+      
 			e[i]->pkgname    = strdup(sqlite3_column_text(stmt, 0));
 			e[i]->version    = strdup(sqlite3_column_text(stmt, 1));
 			e[i]->d_pkgname  = strdup(sqlite3_column_text(stmt, 2));
 			e[i]->d_version  = strdup(sqlite3_column_text(stmt, 3));
-			e[i]->level = sqlite3_column_int(stmt, 4);
-			/* default these to false */
-			e[i]->already_installed = false;
-			e[i]->needs_upgrade = false;
       
 			if (e[i]->pkgname == NULL ||
 			    e[i]->version == NULL ||

Modified: trunk/lib/libmport/install.c
===================================================================
--- trunk/lib/libmport/install.c	2019-05-27 14:30:48 UTC (rev 12206)
+++ trunk/lib/libmport/install.c	2019-05-27 15:26:22 UTC (rev 12207)
@@ -36,82 +36,82 @@
 MPORT_PUBLIC_API int
 mport_install(mportInstance *mport, const char *pkgname, const char *version, const char *prefix)
 {
-	mportIndexEntry **e;
-	char *filename;
-	int ret = MPORT_OK;
-	int e_loc = 0;
+  mportIndexEntry **e;
+  char *filename;
+  int ret = MPORT_OK;
+  int e_loc = 0;
 
-	MPORT_CHECK_FOR_INDEX(mport, "mport_install()");
+  MPORT_CHECK_FOR_INDEX(mport, "mport_install()");
+  
+  if (mport_index_lookup_pkgname(mport, pkgname, &e) != MPORT_OK)
+    RETURN_CURRENT_ERROR;
 
-	if (mport_index_lookup_pkgname(mport, pkgname, &e) != MPORT_OK)
-		RETURN_CURRENT_ERROR;
+  /* we don't support installing more than one top-level package at a time.
+   * Consider a situation like this:
+   *
+   * mport_install(mport, "p5-Class-DBI*");
+   *
+   * Say this matches p5-Class-DBI and p5-Class-DBI-AbstractSearch
+   * and say the order from the index puts p5-Class-DBI-AbstractSearch 
+   * first.
+   * 
+   * p5-Class-DBI-AbstractSearch is installed, and its depends installed.  
+   * However, p5-Class-DBI is a depend of p5-Class-DBI-AbstractSearch, so 
+   * when it comes time to install p5-Class-DBI, we can't - because it is
+   * already installed.
+   *
+   * If a user facing application wants this functionality, it would be
+   * easy to piece together with mport_index_lookup_pkgname(), a
+   * check for already installed packages, and mport_install().
+   */
 
-	/* we don't support installing more than one top-level package at a time.
-	 * Consider a situation like this:
-	 *
-	 * mport_install(mport, "p5-Class-DBI*");
-	 *
-	 * Say this matches p5-Class-DBI and p5-Class-DBI-AbstractSearch
-	 * and say the order from the index puts p5-Class-DBI-AbstractSearch
-	 * first.
-	 *
-	 * p5-Class-DBI-AbstractSearch is installed, and its depends installed.
-	 * However, p5-Class-DBI is a depend of p5-Class-DBI-AbstractSearch, so
-	 * when it comes time to install p5-Class-DBI, we can't - because it is
-	 * already installed.
-	 *
-	 * If a user facing application wants this functionality, it would be
-	 * easy to piece together with mport_index_lookup_pkgname(), a
-	 * check for already installed packages, and mport_install().
-	 */
+  if (e[1] != NULL) {
+    if (version != NULL) {
+        while (e[e_loc] != NULL) {
+          if (strcmp(e[e_loc]->version, version) == 0) {
+            break;
+          }
+          e_loc++;
+        }
+        if (e[e_loc] == NULL) {
+          mport_index_entry_free_vec(e);
+          RETURN_ERRORX(MPORT_ERR_FATAL, "Cound not resolve '%s-%s'.",
+            pkgname, version);
+        }
+    } else {
+      mport_index_entry_free_vec(e);
+      RETURN_ERRORX(MPORT_ERR_FATAL, "Could not resolve '%s' to a single package.", pkgname);
+    }
+  }
+ 
+  asprintf(&filename, "%s/%s", MPORT_FETCH_STAGING_DIR, e[e_loc]->bundlefile);
+  if (filename == NULL) {
+    mport_index_entry_free_vec(e);
+    RETURN_ERROR(MPORT_ERR_FATAL, "Out of memory.");
+  }
 
-	if (e[1] != NULL) {
-		if (version != NULL) {
-			while (e[e_loc] != NULL) {
-				if (strcmp(e[e_loc]->version, version) == 0) {
-					break;
-				}
-				e_loc++;
-			}
-			if (e[e_loc] == NULL) {
-				mport_index_entry_free_vec(e);
-				RETURN_ERRORX(MPORT_ERR_FATAL, "Could not resolve '%s-%s'.",
-					      pkgname, version);
-			}
-		} else {
-			mport_index_entry_free_vec(e);
-			RETURN_ERRORX(MPORT_ERR_FATAL, "Could not resolve '%s' to a single package.", pkgname);
-		}
-	}
+  if (!mport_file_exists(filename)) {
+    if (mport_fetch_bundle(mport, e[e_loc]->bundlefile) != MPORT_OK) {
+      free(filename);
+      mport_index_entry_free_vec(e);
+      RETURN_CURRENT_ERROR;
+    }
+  }
 
-	asprintf(&filename, "%s/%s", MPORT_FETCH_STAGING_DIR, e[e_loc]->bundlefile);
-	if (filename == NULL) {
-		mport_index_entry_free_vec(e);
-		RETURN_ERROR(MPORT_ERR_FATAL, "Out of memory.");
-	}
+  if (mport_verify_hash(filename, e[e_loc]->hash) == 0) {
+    free(filename);
+    mport_index_entry_free_vec(e);
 
-	if (!mport_file_exists(filename)) {
-		if (mport_fetch_bundle(mport, e[e_loc]->bundlefile) != MPORT_OK) {
-			free(filename);
-			mport_index_entry_free_vec(e);
-			RETURN_CURRENT_ERROR;
-		}
-	}
+    if (unlink(filename) == 0)
+      RETURN_ERROR(MPORT_ERR_FATAL, "Package failed hash verification and was removed.\n");
+    else
+      RETURN_ERROR(MPORT_ERR_FATAL, "Package failed hash verification, but could not be removed.\n");
+  }
+ 
+  ret = mport_install_primative(mport, filename, prefix);
 
-	if (mport_verify_hash(filename, e[e_loc]->hash) == 0) {
-		free(filename);
-		mport_index_entry_free_vec(e);
-
-		if (unlink(filename) == 0)
-			RETURN_ERROR(MPORT_ERR_FATAL, "Package failed hash verification and was removed.\n");
-		else
-			RETURN_ERROR(MPORT_ERR_FATAL, "Package failed hash verification, but could not be removed.\n");
-	}
-
-	ret = mport_install_primative(mport, filename, prefix);
-
-	free(filename);
-	mport_index_entry_free_vec(e);
-
-	return ret;
+  free(filename);
+  mport_index_entry_free_vec(e);
+  
+  return ret;
 }

Modified: trunk/lib/libmport/install_primative.c
===================================================================
--- trunk/lib/libmport/install_primative.c	2019-05-27 14:30:48 UTC (rev 12206)
+++ trunk/lib/libmport/install_primative.c	2019-05-27 15:26:22 UTC (rev 12207)
@@ -59,10 +59,8 @@
 		if (prefix != NULL) {
 			/* override the default prefix with the given prefix */
 			free(pkg->prefix);
-			if ((pkg->prefix = strdup(prefix)) == NULL) {
-				/* all hope is lost! bail */
+			if ((pkg->prefix = strdup(prefix)) == NULL) /* all hope is lost! bail */
 				RETURN_ERROR(MPORT_ERR_FATAL, "Out of memory.");
-			}
 		}
 
 		if ((mport_check_preconditions(mport, pkg, MPORT_PRECHECK_INSTALLED | MPORT_PRECHECK_DEPENDS |
@@ -69,12 +67,9 @@
 		                                           MPORT_PRECHECK_CONFLICTS) != MPORT_OK)
 		    ||
 		    (mport_bundle_read_install_pkg(mport, bundle, pkg) != MPORT_OK)) {
-			if (pkg->name != NULL && pkg->version != NULL)
-				mport_call_msg_cb(mport, "Unable to install %s-%s: %s", pkg->name, pkg->version,
-						  mport_err_string());
-			else
-				mport_call_msg_cb(mport, "Unknown error. State is invalid.");
-
+			mport_call_msg_cb(mport, "Unable to install %s-%s: %s", pkg->name, pkg->version,
+			                  mport_err_string());
+			/* TODO: WHY WAS THIS HERE mport_set_err(MPORT_OK, NULL); */
 			error = true;
 			break; /* do not keep going if we have a package failure! */
 		}

Modified: trunk/lib/libmport/mport.h
===================================================================
--- trunk/lib/libmport/mport.h	2019-05-27 14:30:48 UTC (rev 12206)
+++ trunk/lib/libmport/mport.h	2019-05-27 15:26:22 UTC (rev 12207)
@@ -36,7 +36,6 @@
 #include <sqlite3.h>
 #include <sys/queue.h>
 #include <stdio.h>
-#include <stdbool.h>
 
 #include "mport_dispatch.h"
 
@@ -166,9 +165,6 @@
   char *version;
   char *d_pkgname;
   char *d_version;
-  int level;
-  bool already_installed;
-  bool needs_upgrade;
 } mportDependsEntry;
 
 int mport_index_depends_list(mportInstance *, const char *, const char *, mportDependsEntry ***);


From laffer1 at midnightbsd.org  Mon May 27 11:27:11 2019
From: laffer1 at midnightbsd.org (laffer1 at midnightbsd.org)
Date: Mon, 27 May 2019 11:27:11 -0400 (EDT)
Subject: [Midnightbsd-cvs] src [12208] trunk/usr.sbin/mport/mport.c: revert
 recursive sqlite query approach.
Message-ID: <201905271527.x4RFRBrQ097298@stargazer.midnightbsd.org>

Revision: 12208
          http://svnweb.midnightbsd.org/src/?rev=12208
Author:   laffer1
Date:     2019-05-27 11:27:10 -0400 (Mon, 27 May 2019)
Log Message:
-----------
revert recursive sqlite query approach.

Modified Paths:
--------------
    trunk/usr.sbin/mport/mport.c

Modified: trunk/usr.sbin/mport/mport.c
===================================================================
--- trunk/usr.sbin/mport/mport.c	2019-05-27 15:26:22 UTC (rev 12207)
+++ trunk/usr.sbin/mport/mport.c	2019-05-27 15:27:10 UTC (rev 12208)
@@ -36,7 +36,6 @@
 #include <err.h>
 #include <dispatch/dispatch.h>
 #include <mport.h>
-#include "../libmport/mport.h"
 
 #define MPORT_TOOLS_PATH "/usr/libexec/"
 #define MPORT_LOCAL_PKG_PATH "/var/db/mport/downloads"
@@ -44,7 +43,7 @@
 static void usage(void);
 static void loadIndex(mportInstance *);
 static mportIndexEntry ** lookupIndex(mportInstance *, const char *);
-static int install_depends(mportInstance *, const char *, const char *, bool first);
+static int install_depends(mportInstance *, const char *, const char *);
 static int install(mportInstance *, const char *);
 static int cpeList(mportInstance *);
 static int configGet(mportInstance *, const char *);
@@ -245,28 +244,26 @@
 		__block int local_argc = argc;
 		__block char *const * local_argv = argv;
 		local_argv++;
-			if (local_argc > 2) {
-				int ch, qflag, oflag;
-				qflag = oflag = 0;
-				while ((ch = getopt(local_argc, local_argv, "qo")) != -1) {
-					switch (ch) {
-						case 'q':
-							qflag = 1;
-							break;
-						case 'o':
-							oflag = 1;
-							break;
-						default:
-							break;
-					}
+                if (local_argc > 2) {
+			int ch, qflag, oflag;
+			qflag = oflag = 0;
+		        while ((ch = getopt(local_argc, local_argv, "qo")) != -1) {
+				switch (ch) {
+			 		case 'q':
+					qflag = 1;
+					break;
+					case 'o':
+	                                oflag = 1;
+        	                        break;
 				}
-				local_argc -= optind;
-				local_argv += optind;
+			}
+			local_argc -= optind;
+			local_argv += optind;
 
-				which(mport, *local_argv, qflag, oflag);
-			} else {
-				usage();
-			}
+			which(mport, *local_argv, qflag, oflag);
+                } else {
+                        usage();
+                }
                 });
 	} else {
 		mport_instance_free(mport);
@@ -481,7 +478,7 @@
 
 /* recursive function */ 
 int
-install_depends(mportInstance *mport, const char *packageName, const char *version, bool first) {
+install_depends(mportInstance *mport, const char *packageName, const char *version) {
 	mportPackageMeta **packs;
 	mportDependsEntry **depends;
 
@@ -504,15 +501,13 @@
 	} else if (packs == NULL) {
 		/* Package is not installed */
 		while (*depends != NULL) {
-			install_depends(mport, (*depends)->d_pkgname, (*depends)->d_version, first);
+			install_depends(mport, (*depends)->d_pkgname, (*depends)->d_version);
 			depends++;
-		}
-
+        	}
 		if (mport_install(mport, packageName, version, NULL) != MPORT_OK) {
 			warnx("%s", mport_err_string());
 			return mport_err_code();
 		}
-
 		mport_index_depends_free_vec(depends);
 	} else {
 		/* already installed */
@@ -557,7 +552,7 @@
 		}
 	}
 
-	resultCode = install_depends(mport, (*indexEntry)->pkgname, (*indexEntry)->version, true);
+	resultCode = install_depends(mport, (*indexEntry)->pkgname, (*indexEntry)->version);
 
 	mport_index_entry_free_vec(indexEntry);
 


From laffer1 at midnightbsd.org  Tue May 28 09:29:39 2019
From: laffer1 at midnightbsd.org (laffer1 at midnightbsd.org)
Date: Tue, 28 May 2019 09:29:39 -0400 (EDT)
Subject: [Midnightbsd-cvs] src [12209] trunk/lib/libmport: Add public domain
 hashmap implementation.
Message-ID: <201905281329.x4SDTdXU058676@stargazer.midnightbsd.org>

Revision: 12209
          http://svnweb.midnightbsd.org/src/?rev=12209
Author:   laffer1
Date:     2019-05-28 09:29:38 -0400 (Tue, 28 May 2019)
Log Message:
-----------
Add public domain hashmap implementation.

Modified Paths:
--------------
    trunk/lib/libmport/Makefile

Added Paths:
-----------
    trunk/lib/libmport/hashmap.c
    trunk/lib/libmport/hashmap.h

Modified: trunk/lib/libmport/Makefile
===================================================================
--- trunk/lib/libmport/Makefile	2019-05-27 15:27:10 UTC (rev 12208)
+++ trunk/lib/libmport/Makefile	2019-05-28 13:29:38 UTC (rev 12209)
@@ -8,7 +8,7 @@
 		default_cbs.c  merge_primative.c bundle_read_install_pkg.c \
 		update_primative.c bundle_read_update_pkg.c pkgmeta.c \
     	fetch.c index.c index_depends.c install.c clean.c setting.c  \
-   		stats.c verify.c lock.c mkdir.c
+   		stats.c verify.c lock.c mkdir.c hashmap.c
 INCS=	mport.h mport_dispatch.h
 
 CFLAGS+=	-I${.CURDIR} -fblocks -g

Added: trunk/lib/libmport/hashmap.c
===================================================================
--- trunk/lib/libmport/hashmap.c	                        (rev 0)
+++ trunk/lib/libmport/hashmap.c	2019-05-28 13:29:38 UTC (rev 12209)
@@ -0,0 +1,403 @@
+/*
+ * Generic map implementation.
+ * $MidnightBSD$
+ */
+#include "hashmap.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define INITIAL_SIZE (256)
+#define MAX_CHAIN_LENGTH (8)
+
+/* We need to keep keys and values */
+typedef struct _hashmap_element{
+	char* key;
+	int in_use;
+	any_t data;
+} hashmap_element;
+
+/* A hashmap has some maximum size and current size,
+ * as well as the data to hold. */
+typedef struct _hashmap_map{
+	int table_size;
+	int size;
+	hashmap_element *data;
+} hashmap_map;
+
+unsigned long crc32(const unsigned char *s, unsigned int len);
+unsigned int hashmap_hash_int(hashmap_map * m, char* keystring);
+int hashmap_hash(map_t in, char* key);
+int hashmap_rehash(map_t in);
+
+/*
+ * Return an empty hashmap, or NULL on failure.
+ */
+map_t hashmap_new() {
+	hashmap_map* m = (hashmap_map*) malloc(sizeof(hashmap_map));
+	if(!m) goto err;
+
+	m->data = (hashmap_element*) calloc(INITIAL_SIZE, sizeof(hashmap_element));
+	if(!m->data) goto err;
+
+	m->table_size = INITIAL_SIZE;
+	m->size = 0;
+
+	return m;
+	err:
+		if (m)
+			hashmap_free(m);
+		return NULL;
+}
+
+/* The implementation here was originally done by Gary S. Brown.  I have
+   borrowed the tables directly, and made some minor changes to the
+   crc32-function (including changing the interface). //ylo */
+
+  /* ============================================================= */
+  /*  COPYRIGHT (C) 1986 Gary S. Brown.  You may use this program, or       */
+  /*  code or tables extracted from it, as desired without restriction.     */
+  /*                                                                        */
+  /*  First, the polynomial itself and its table of feedback terms.  The    */
+  /*  polynomial is                                                         */
+  /*  X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0   */
+  /*                                                                        */
+  /*  Note that we take it "backwards" and put the highest-order term in    */
+  /*  the lowest-order bit.  The X^32 term is "implied"; the LSB is the     */
+  /*  X^31 term, etc.  The X^0 term (usually shown as "+1") results in      */
+  /*  the MSB being 1.                                                      */
+  /*                                                                        */
+  /*  Note that the usual hardware shift register implementation, which     */
+  /*  is what we're using (we're merely optimizing it by doing eight-bit    */
+  /*  chunks at a time) shifts bits into the lowest-order term.  In our     */
+  /*  implementation, that means shifting towards the right.  Why do we     */
+  /*  do it this way?  Because the calculated CRC must be transmitted in    */
+  /*  order from highest-order term to lowest-order term.  UARTs transmit   */
+  /*  characters in order from LSB to MSB.  By storing the CRC this way,    */
+  /*  we hand it to the UART in the order low-byte to high-byte; the UART   */
+  /*  sends each low-bit to hight-bit; and the result is transmission bit   */
+  /*  by bit from highest- to lowest-order term without requiring any bit   */
+  /*  shuffling on our part.  Reception works similarly.                    */
+  /*                                                                        */
+  /*  The feedback terms table consists of 256, 32-bit entries.  Notes:     */
+  /*                                                                        */
+  /*      The table can be generated at runtime if desired; code to do so   */
+  /*      is shown later.  It might not be obvious, but the feedback        */
+  /*      terms simply represent the results of eight shift/xor opera-      */
+  /*      tions for all combinations of data and CRC register values.       */
+  /*                                                                        */
+  /*      The values must be right-shifted by eight bits by the "updcrc"    */
+  /*      logic; the shift must be unsigned (bring in zeroes).  On some     */
+  /*      hardware you could probably optimize the shift in assembler by    */
+  /*      using byte-swap instructions.                                     */
+  /*      polynomial $edb88320                                              */
+  /*                                                                        */
+  /*  --------------------------------------------------------------------  */
+
+static unsigned long crc32_tab[] = {
+      0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
+      0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
+      0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
+      0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
+      0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
+      0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+      0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
+      0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+      0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
+      0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
+      0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
+      0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+      0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
+      0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
+      0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
+      0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+      0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
+      0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+      0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
+      0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
+      0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
+      0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
+      0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
+      0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+      0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
+      0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
+      0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
+      0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
+      0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
+      0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+      0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
+      0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+      0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
+      0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+      0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
+      0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+      0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
+      0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
+      0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
+      0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+      0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
+      0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+      0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
+      0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
+      0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
+      0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
+      0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
+      0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+      0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
+      0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
+      0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
+      0x2d02ef8dL
+   };
+
+/* Return a 32-bit CRC of the contents of the buffer. */
+
+unsigned long crc32(const unsigned char *s, unsigned int len)
+{
+  unsigned int i;
+  unsigned long crc32val;
+  
+  crc32val = 0;
+  for (i = 0;  i < len;  i ++)
+    {
+      crc32val =
+	crc32_tab[(crc32val ^ s[i]) & 0xff] ^
+	  (crc32val >> 8);
+    }
+  return crc32val;
+}
+
+/*
+ * Hashing function for a string
+ */
+unsigned int hashmap_hash_int(hashmap_map * m, char* keystring){
+
+    unsigned long key = crc32((unsigned char*)(keystring), strlen(keystring));
+
+	/* Robert Jenkins' 32 bit Mix Function */
+	key += (key << 12);
+	key ^= (key >> 22);
+	key += (key << 4);
+	key ^= (key >> 9);
+	key += (key << 10);
+	key ^= (key >> 2);
+	key += (key << 7);
+	key ^= (key >> 12);
+
+	/* Knuth's Multiplicative Method */
+	key = (key >> 3) * 2654435761;
+
+	return key % m->table_size;
+}
+
+/*
+ * Return the integer of the location in data
+ * to store the point to the item, or MAP_FULL.
+ */
+int hashmap_hash(map_t in, char* key){
+	int curr;
+	int i;
+
+	/* Cast the hashmap */
+	hashmap_map* m = (hashmap_map *) in;
+
+	/* If full, return immediately */
+	if(m->size >= (m->table_size/2)) return MAP_FULL;
+
+	/* Find the best index */
+	curr = hashmap_hash_int(m, key);
+
+	/* Linear probing */
+	for(i = 0; i< MAX_CHAIN_LENGTH; i++){
+		if(m->data[curr].in_use == 0)
+			return curr;
+
+		if(m->data[curr].in_use == 1 && (strcmp(m->data[curr].key,key)==0))
+			return curr;
+
+		curr = (curr + 1) % m->table_size;
+	}
+
+	return MAP_FULL;
+}
+
+/*
+ * Doubles the size of the hashmap, and rehashes all the elements
+ */
+int hashmap_rehash(map_t in){
+	int i;
+	int old_size;
+	hashmap_element* curr;
+
+	/* Setup the new elements */
+	hashmap_map *m = (hashmap_map *) in;
+	hashmap_element* temp = (hashmap_element *)
+		calloc(2 * m->table_size, sizeof(hashmap_element));
+	if(!temp) return MAP_OMEM;
+
+	/* Update the array */
+	curr = m->data;
+	m->data = temp;
+
+	/* Update the size */
+	old_size = m->table_size;
+	m->table_size = 2 * m->table_size;
+	m->size = 0;
+
+	/* Rehash the elements */
+	for(i = 0; i < old_size; i++){
+        int status;
+
+        if (curr[i].in_use == 0)
+            continue;
+            
+		status = hashmap_put(m, curr[i].key, curr[i].data);
+		if (status != MAP_OK)
+			return status;
+	}
+
+	free(curr);
+
+	return MAP_OK;
+}
+
+/*
+ * Add a pointer to the hashmap with some key
+ */
+int hashmap_put(map_t in, char* key, any_t value){
+	int index;
+	hashmap_map* m;
+
+	/* Cast the hashmap */
+	m = (hashmap_map *) in;
+
+	/* Find a place to put our value */
+	index = hashmap_hash(in, key);
+	while(index == MAP_FULL){
+		if (hashmap_rehash(in) == MAP_OMEM) {
+			return MAP_OMEM;
+		}
+		index = hashmap_hash(in, key);
+	}
+
+	/* Set the data */
+	m->data[index].data = value;
+	m->data[index].key = key;
+	m->data[index].in_use = 1;
+	m->size++; 
+
+	return MAP_OK;
+}
+
+/*
+ * Get your pointer out of the hashmap with a key
+ */
+int hashmap_get(map_t in, char* key, any_t *arg){
+	int curr;
+	int i;
+	hashmap_map* m;
+
+	/* Cast the hashmap */
+	m = (hashmap_map *) in;
+
+	/* Find data location */
+	curr = hashmap_hash_int(m, key);
+
+	/* Linear probing, if necessary */
+	for(i = 0; i<MAX_CHAIN_LENGTH; i++){
+
+        int in_use = m->data[curr].in_use;
+        if (in_use == 1){
+            if (strcmp(m->data[curr].key,key)==0){
+                *arg = (m->data[curr].data);
+                return MAP_OK;
+            }
+		}
+
+		curr = (curr + 1) % m->table_size;
+	}
+
+	*arg = NULL;
+
+	/* Not found */
+	return MAP_MISSING;
+}
+
+/*
+ * Iterate the function parameter over each element in the hashmap.  The
+ * additional any_t argument is passed to the function as its first
+ * argument and the hashmap element is the second.
+ */
+int hashmap_iterate(map_t in, PFany f, any_t item) {
+	int i;
+
+	/* Cast the hashmap */
+	hashmap_map* m = (hashmap_map*) in;
+
+	/* On empty hashmap, return immediately */
+	if (hashmap_length(m) <= 0)
+		return MAP_MISSING;	
+
+	/* Linear probing */
+	for(i = 0; i< m->table_size; i++)
+		if(m->data[i].in_use != 0) {
+			any_t data = (any_t) (m->data[i].data);
+			int status = f(item, data);
+			if (status != MAP_OK) {
+				return status;
+			}
+		}
+
+    return MAP_OK;
+}
+
+/*
+ * Remove an element with that key from the map
+ */
+int hashmap_remove(map_t in, char* key){
+	int i;
+	int curr;
+	hashmap_map* m;
+
+	/* Cast the hashmap */
+	m = (hashmap_map *) in;
+
+	/* Find key */
+	curr = hashmap_hash_int(m, key);
+
+	/* Linear probing, if necessary */
+	for(i = 0; i<MAX_CHAIN_LENGTH; i++){
+
+        int in_use = m->data[curr].in_use;
+        if (in_use == 1){
+            if (strcmp(m->data[curr].key,key)==0){
+                /* Blank out the fields */
+                m->data[curr].in_use = 0;
+                m->data[curr].data = NULL;
+                m->data[curr].key = NULL;
+
+                /* Reduce the size */
+                m->size--;
+                return MAP_OK;
+            }
+		}
+		curr = (curr + 1) % m->table_size;
+	}
+
+	/* Data not found */
+	return MAP_MISSING;
+}
+
+/* Deallocate the hashmap */
+void hashmap_free(map_t in){
+	hashmap_map* m = (hashmap_map*) in;
+	free(m->data);
+	free(m);
+}
+
+/* Return the length of the hashmap */
+int hashmap_length(map_t in){
+	hashmap_map* m = (hashmap_map *) in;
+	if(m != NULL) return m->size;
+	else return 0;
+}


Property changes on: trunk/lib/libmport/hashmap.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/lib/libmport/hashmap.h
===================================================================
--- trunk/lib/libmport/hashmap.h	                        (rev 0)
+++ trunk/lib/libmport/hashmap.h	2019-05-28 13:29:38 UTC (rev 12209)
@@ -0,0 +1,82 @@
+/*
+ * Generic hashmap manipulation functions
+ *
+ * Originally by Elliot C Back - http://elliottback.com/wp/hashmap-implementation-in-c/
+ *
+ * Modified by Pete Warden to fix a serious performance problem, support strings as keys
+ * and removed thread synchronization - http://petewarden.typepad.com
+ * $MidnightBSD$
+ */
+#ifndef __HASHMAP_H__
+#define __HASHMAP_H__
+
+#define MAP_MISSING -3  /* No such element */
+#define MAP_FULL -2 	/* Hashmap is full */
+#define MAP_OMEM -1 	/* Out of Memory */
+#define MAP_OK 0 	/* OK */
+
+/*
+ * any_t is a pointer.  This allows you to put arbitrary structures in
+ * the hashmap.
+ */
+typedef void *any_t;
+
+/*
+ * PFany is a pointer to a function that can take two any_t arguments
+ * and return an integer. Returns status code..
+ */
+typedef int (*PFany)(any_t, any_t);
+
+/*
+ * map_t is a pointer to an internally maintained data structure.
+ * Clients of this package do not need to know how hashmaps are
+ * represented.  They see and manipulate only map_t's.
+ */
+typedef any_t map_t;
+
+/*
+ * Return an empty hashmap. Returns NULL if empty.
+*/
+map_t hashmap_new(void);
+
+/*
+ * Iteratively call f with argument (item, data) for
+ * each element data in the hashmap. The function must
+ * return a map status code. If it returns anything other
+ * than MAP_OK the traversal is terminated. f must
+ * not reenter any hashmap functions, or deadlock may arise.
+ */
+int hashmap_iterate(map_t in, PFany f, any_t item);
+
+/*
+ * Add an element to the hashmap. Return MAP_OK or MAP_OMEM.
+ */
+int hashmap_put(map_t in, char* key, any_t value);
+
+/*
+ * Get an element from the hashmap. Return MAP_OK or MAP_MISSING.
+ */
+int hashmap_get(map_t in, char* key, any_t *arg);
+
+/*
+ * Remove an element from the hashmap. Return MAP_OK or MAP_MISSING.
+ */
+int hashmap_remove(map_t in, char* key);
+
+/*
+ * Get any element. Return MAP_OK or MAP_MISSING.
+ * remove - should the element be removed from the hashmap
+ */
+int hashmap_get_one(map_t in, any_t *arg, int remove);
+
+/*
+ * Free the hashmap
+ */
+void hashmap_free(map_t in);
+
+/*
+ * Get the current size of a hashmap
+ */
+int hashmap_length(map_t in);
+
+#endif


Property changes on: trunk/lib/libmport/hashmap.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property