« Return to Thread: [patch 00/13] [RFC] Hashtable improvements and API changes

[patch 08/13] Introduce new osync_hashltable API

by Daniel Gollub :: Rate this Message:

Reply to Author | View in Thread

* The hashtable is now restricted to one object type/table.
* Instead of performing single SQL queries an internal
  hashtable data structure is used for temporary store.
* The persistent store of the hashtable is done by the
  function osync_hashtable_committedall(), which
  is using SQL transaction. Call this function in your
  committedall() plugin sink function.
* Hashtable needs to be loaded with function osync_hashtable_load()
* Added reference counting for hashtable object
* osync_hashtable_num_entries() return value changed from int to unsigned int
* osync_hashtable_nth_entry() got replaced by osync_hashtable_foreach(),
  which is more performant to iterate through the hashtable
* osync_hashtable_get_deleted() return value changed from char* Array to OSyncList
* osync_hashtable_update_hash() got by replaced osync_hashtable_update_change()
  which allows to use the OSyncChange object, since this contains changetype
  and UID. Depending on the changetype more specific SQL query get prepared.
* osync_hashtable_write()/osync_hashtable_delete() got dropped. No need - right?
* It's FAST now (seriously)!

---
 opensync/helper/opensync_hashtable.c           |  452 +++++++++++--------------
 opensync/helper/opensync_hashtable.h           |   26 -
 opensync/helper/opensync_hashtable_internals.h |   14
 3 files changed, 239 insertions(+), 253 deletions(-)

Index: opensync/opensync/helper/opensync_hashtable.c
===================================================================
--- opensync.orig/opensync/helper/opensync_hashtable.c
+++ opensync/opensync/helper/opensync_hashtable.c
@@ -38,17 +38,18 @@
 /*! @brief Creates the database table for the hashtable
  *
  * @param table The hashtable
- * @param objtype the object type of the hashtable
+ * @param ame The name of the hastable inside the database
  * @param error An error struct
  * @returns TRUE on success, or FALSE if an error occurred.
  *
  */
 
-static osync_bool osync_hashtable_create(OSyncHashTable *table, const char *objtype, OSyncError **error)
+static osync_bool osync_hashtable_create(OSyncHashTable *table, OSyncError **error)
 {
- osync_trace(TRACE_ENTRY, "%s(%p, %s, %p)", __func__, table, objtype, error);
+ osync_assert(table);
+ osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, table, error);
 
- char *query = g_strdup_printf("CREATE TABLE tbl_hash_%s (id INTEGER PRIMARY KEY, uid VARCHAR UNIQUE, hash VARCHAR)", objtype);
+ char *query = g_strdup_printf("CREATE TABLE %s (id INTEGER PRIMARY KEY, uid VARCHAR UNIQUE, hash VARCHAR)", table->name);
  if (!osync_db_query(table->dbhandle, query, error)) {
  osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
  g_free(query);
@@ -116,42 +117,44 @@ static osync_bool osync_hashtable_create
  */
 OSyncHashTable *osync_hashtable_new(const char *path, const char *objtype, OSyncError **error)
 {
- osync_trace(TRACE_ENTRY, "%s(%s, %s, %p)", __func__, path, objtype, error);
+ osync_trace(TRACE_ENTRY, "%s(%s, %p)", __func__, path, error);
 
  OSyncHashTable *table = osync_try_malloc0(sizeof(OSyncHashTable), error);
- if (!table) {
- osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
- return NULL;
- }
+ if (!table)
+ goto error;
+
+ table->ref_count = 1;
 
- table->used_entries = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+
+ table->reported_entries = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+ table->db_entries = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
 
  table->dbhandle = osync_db_new(error);
  if (!table->dbhandle)
- goto error;
+ goto error_and_free_db;
 
  if (!osync_db_open(table->dbhandle, path, error))
  goto error_and_free;
 
- table->tablename = g_strdup_printf("tbl_hash_%s", objtype);
+ table->name = g_strdup_printf(OSYNC_HASHTABLE_DB_PREFIX"%s", objtype);
 
- int ret = osync_db_exists(table->dbhandle, table->tablename, error);
- if (ret > 0) {
- goto end;
- } else if (ret < 0) {
- goto error_and_free;
- }
- /* if ret == 0 then table does not exist yet. contiune and create one. */
+ int ret = osync_db_table_exists(table->dbhandle, table->name, error);
+ /* greater then 0 means evrything is O.k. */
+
+ if (ret < 0)
+ goto error;
+ else if (ret == 0)
+ /* if ret == 0 then table does not exist yet. contiune and create one. */
+ if (!osync_hashtable_create(table, error))
+ goto error;
 
- if (!osync_hashtable_create(table, objtype, error))
- goto error_and_free;
 
-end:
  osync_trace(TRACE_EXIT, "%s: %p", __func__, table);
  return table;
 
-error_and_free:
+error_and_free_db:
  g_free(table->dbhandle);
+error_and_free:
  g_free(table);
 error:
  osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
@@ -159,29 +162,132 @@ error:
 
 }
 
-/*! @brief Frees a hashtable
+/*! @brief Increase the refernece count of the hashtable.
+ *
+ * @param table The hashtable to increase the reference count
+ * @returns Pointer to increased hashtable object
+ */
+OSyncHashTable *osync_hashtable_ref(OSyncHashTable *table)
+{
+ osync_assert(table);
+
+ g_atomic_int_inc(&(table->ref_count));
+
+ return table;
+}
+
+/*! @brief Decrease the reference count of the hastable. Hashtable
+ *         gets freed if the reference count get less then one.
  *
- * @param table The hashtable to free
+ * @param table The hashtable to decrease the reference count
  *
  */
-void osync_hashtable_free(OSyncHashTable *table)
+void osync_hashtable_unref(OSyncHashTable *table)
 {
- osync_trace(TRACE_ENTRY, "%s(%p)", __func__, table);
  osync_assert(table);
-
- if (!osync_db_close(table->dbhandle, NULL))
- osync_trace(TRACE_INTERNAL, "Can't close database");
 
+ if (g_atomic_int_dec_and_test(&(table->ref_count))) {
+ osync_trace(TRACE_ENTRY, "%s(%p)", __func__, table);
+
+ OSyncError *error = NULL;
 
- g_hash_table_destroy(table->used_entries);
+ if (!osync_db_close(table->dbhandle, &error)) {
+ osync_trace(TRACE_ERROR, "Couldn't close database: %s", osync_error_print(&error));
+ osync_error_unref(&error);
+ }
+
+ g_hash_table_destroy(table->reported_entries);
+ g_hash_table_destroy(table->db_entries);
+
+ g_free(table->name);
+ g_free(table->dbhandle);
+ g_free(table);
 
- g_free(table->tablename);
- g_free(table->dbhandle);
- g_free(table);
+ osync_trace(TRACE_EXIT, "%s", __func__);
+ }
 
+}
+
+osync_bool osync_hashtable_load(OSyncHashTable *table, OSyncError **error)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, table, error);
+
+ char *query;
+ OSyncList *row, *result;
+
+ query = g_strdup_printf("SELECT uid, hash FROM %s", table->name);
+ result = osync_db_query_table(table->dbhandle, query, error);
+ g_free(query);
+
+ /* If result is NULL, this means no entries - just check for error. */
+ if (osync_error_is_set(error))
+ goto error;
+
+ for (row = result; row; row = row->next) {
+ OSyncList *column = row->data;
+
+ char *uid =  g_strdup(osync_list_nth_data(column, 0));
+ char *hash = g_strdup(osync_list_nth_data(column, 1));
+
+ g_hash_table_insert(table->db_entries, uid, hash);
+ }
+
  osync_trace(TRACE_EXIT, "%s", __func__);
+ return TRUE;
+
+error:
+ osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
+ return FALSE;
 }
 
+static void _osync_hashtable_prepare_insert_query(const char *uid, const char *hash, void *user_data)
+{
+ OSyncHashTable *table = user_data;
+
+ char *escaped_uid = osync_db_sql_escape(uid);
+ char *escaped_hash = osync_db_sql_escape(hash);
+
+ g_string_append_printf(table->query,
+ "REPLACE INTO %s ('uid', 'hash') VALUES('%s', '%s');",
+ table->name, escaped_uid, escaped_hash);
+
+ g_free(escaped_uid);
+ g_free(escaped_hash);
+}
+
+osync_bool osync_hashtable_committedall(OSyncHashTable *table, OSyncError **error)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %s, %p)", __func__, table, error);
+
+ osync_bool ret;
+
+ /* Should only be used by this function */
+ osync_assert(!table->query);
+
+ table->query = g_string_new("BEGIN TRANSACTION;");
+
+ osync_hashtable_foreach(table, _osync_hashtable_prepare_insert_query, table);
+
+ table->query = g_string_append(table->query, "COMMIT TRANSACTION;");
+
+ char *query = g_string_free(table->query, FALSE);
+ ret = osync_db_query(table->dbhandle, query, error);
+ g_free(query);
+
+ table->query = NULL;
+
+ if (!ret)
+ goto error;
+
+ osync_trace(TRACE_EXIT, "%s", __func__);
+ return TRUE;
+
+error:
+ osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
+ return FALSE;
+}
+
+
 /*! @brief Prepares the hashtable for a slowsync and flush the entire hashtable
  *
  * This function should be called to prepare the hashtable for a slowsync.
@@ -199,13 +305,21 @@ osync_bool osync_hashtable_slowsync(OSyn
  osync_assert(table);
  osync_assert(table->dbhandle);
 
- if (!osync_db_reset(table->dbhandle, table->tablename, error)) {
- osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
- return FALSE;
- }
+ osync_bool ret = FALSE;
+
+ /* Reset hashtable in database */
+ ret = osync_db_reset_table(table->dbhandle, table->name, error);
+
+ if (!ret)
+ goto error;
 
  osync_trace(TRACE_EXIT, "%s", __func__);
  return TRUE;
+
+error:
+ osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
+ return FALSE;
+
 }
 
 #if !GLIB_CHECK_VERSION(2,12,0)
@@ -237,199 +351,46 @@ void osync_hashtable_reset_reports(OSync
  /* Only free the internal hashtable of reported entries.
    Don't flush the real database. */
 #if GLIB_CHECK_VERSION(2,12,0)
- g_hash_table_remove_all(table->used_entries);
+ g_hash_table_remove_all(table->reported_entries);
 #else
- g_hash_table_foreach_remove(table->used_entries, remove_entry, NULL);
+ g_hash_table_foreach_remove(table->reported_entries, remove_entry, NULL);
 #endif
 
  osync_trace(TRACE_EXIT, "%s", __func__);
 }
 
-/*! @brief Returns the number of entries in this hashtable
- *
- * @param table The hashtable
- * @returns The number of entries, or -1 if an error occurred
- *
- */
-int osync_hashtable_num_entries(OSyncHashTable *table)
-{
- osync_trace(TRACE_ENTRY, "%s(%p)", __func__, table);
- osync_assert(table);
- osync_assert(table->dbhandle);
-
- char *query = g_strdup_printf("SELECT * FROM %s", table->tablename);
- int ret = osync_db_count(table->dbhandle, query, NULL);
- g_free(query);
-
- if (ret < 0) {
- osync_trace(TRACE_EXIT_ERROR, "%s: Cannot count number of hashtable entries!", __func__);
- return -1;
- }
-
- osync_trace(TRACE_EXIT, "%s: %i", __func__, ret);
- return ret;
-}
-
-/*! @brief Gets the nth entry from the table
- *
- * This is mainly useful for debugging or special purposes
+/*! @brief Update the an entry
  *
- * @param table The hashtable
- * @param nth The number of the entry to return
- * @param uid A pointer to a char * that will hold the uid. The caller is responsible for freeing this.
- * @param hash A pointer to a char * that will hold the hash. The caller is responsible for freeing this.
- * @returns TRUE if successful, FALSE otherwise
- *
- */
-osync_bool osync_hashtable_nth_entry(OSyncHashTable *table, int nth, char **uid, char **hash)
-{
- osync_assert(table);
- osync_assert(table->dbhandle);
-
- GList *list = NULL;
- OSyncError *error = NULL;
-
-
- char *query = g_strdup_printf("SELECT uid, hash FROM %s LIMIT 1 OFFSET %i", table->tablename, nth);
- list = osync_db_query_table(table->dbhandle, query, &error);
- g_free(query);
-
- if (osync_error_is_set(&error)) {
- osync_trace(TRACE_EXIT_ERROR, "%s: Cannot get #%i entry from hashtable: %s", __func__, nth, osync_error_print(&error));
- osync_error_unref(&error);
- return FALSE;
- }
-
- GList *column = list->data;
-
- *uid = g_strdup((char*)g_list_nth_data(column, 0));
- *hash = g_strdup((char*)g_list_nth_data(column, 1));
-
- osync_db_free_list(list);
-
- return TRUE;
-}
-
-/*! @brief Gets the hash value for given uid
- *
- * @param table The hashtable
- * @param uid The uid to lookup
- * @returns The hash. Has to be freed by the caller.
- */
-char *osync_hashtable_get_hash(OSyncHashTable *table, const char *uid)
-{
-       osync_assert(uid);
-       osync_assert(table);
-       osync_assert(table->dbhandle);
-
-       char *hash = NULL;
-       GList *list = NULL;
-       OSyncError *error = NULL;
-       char *escaped_uid = osync_db_sql_escape(uid);
-
-       char *query = g_strdup_printf("SELECT hash FROM %s WHERE uid= '%s' LIMIT 1",
-                                     table->tablename, escaped_uid);
-       list = osync_db_query_table(table->dbhandle, query, &error);
-       g_free(query);
-       g_free(escaped_uid);
-
-       if (osync_error_is_set(&error)) {
-               osync_trace(TRACE_EXIT_ERROR, "%s: Cannot get hash for '%s': %s",
-                           __func__, uid, osync_error_print(&error));
-               osync_error_unref(&error);
-               return NULL;
-       }
-
-       if (list && list->data) {
-               GList *column = list->data;
-               hash = g_strdup((char *)g_list_nth_data(column, 0));
-       }
-
-       osync_db_free_list(list);
-
-       return hash;
-}
-
-/*! @brief Write the hash value for given uid
- *
- * @param table The hashtable
- * @param uid The uid
- * @param hash The hash
- */
-void osync_hashtable_write(OSyncHashTable *table, const char *uid, const char *hash)
-{
- osync_trace(TRACE_ENTRY, "%s(%p, %s, %s)", __func__, table, uid, hash);
- osync_assert(table);
- osync_assert(table->dbhandle);
-
- char *escaped_uid = osync_db_sql_escape(uid);
- char *escaped_hash = osync_db_sql_escape(hash);
- char *query = g_strdup_printf("REPLACE INTO %s ('uid', 'hash') VALUES('%s', '%s')", table->tablename, escaped_uid, escaped_hash);
- g_free(escaped_uid);
- g_free(escaped_hash);
-
- if (!osync_db_query(table->dbhandle, query, NULL)) {
- g_free(query);
- osync_trace(TRACE_EXIT, "%s: Cannot write hashtable entry.", __func__);
- return;
- }
- g_free(query);
-
- osync_trace(TRACE_EXIT, "%s", __func__);
-}
-
-/*! @brief Delete hashtable entries for given uid
- *
- * @param table The hashtable
- * @param uid The uid of the entry to delete
- */
-void osync_hashtable_delete(OSyncHashTable *table, const char *uid)
-{
- osync_trace(TRACE_ENTRY, "%s(%p, %s)", __func__, table, uid);
- osync_assert(table);
- osync_assert(table->dbhandle);
-
- char *escaped_uid = osync_db_sql_escape(uid);
- char *query = g_strdup_printf("DELETE FROM %s WHERE uid='%s'", table->tablename, escaped_uid);
- g_free(escaped_uid);
-
- if (!osync_db_query(table->dbhandle, query, NULL)) {
- g_free(query);
- osync_trace(TRACE_EXIT_ERROR, "%s: Cannot delete hashtable entry.", __func__);
- return;
- /* TODO: Error handling */
- }
- g_free(query);
-
- osync_trace(TRACE_EXIT, "%s", __func__);
-}
-
-/*! @brief Update the hash for a entry
- *
- * Updates the hash for a entry in the hashtable. Do this after you see that a hash
+ * Updates the entry in the hashtable. Do this after you see that a hash
  * has changed, for example after reading it during get_changes or after you
- * wrote it
+ * wrote it.
  *
  * @param table The hashtable
  * @param type The type of change (added, modified, etc.)
  * @param uid the uid of the changed entry
  * @param hash the new hash of the changed entry
  */
-void osync_hashtable_update_hash(OSyncHashTable *table, OSyncChangeType type, const char *uid, const char *hash)
+void osync_hashtable_update_change(OSyncHashTable *table, OSyncChange *change, const char *hash)
 {
- osync_trace(TRACE_ENTRY, "%s(%p, %i, %s, %s)", __func__, table, type, uid, hash);
  osync_assert(table);
  osync_assert(table->dbhandle);
+ osync_assert(change);
 
- switch (type) {
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %s)", __func__, table, change, __NULLSTR(hash));
+
+ const char *uid = osync_change_get_uid(change);
+
+ switch (osync_change_get_changetype(change)) {
  case OSYNC_CHANGE_TYPE_DELETED:
- osync_hashtable_delete(table, uid);
+ g_hash_table_remove(table->db_entries, uid);
  break;
  case OSYNC_CHANGE_TYPE_UNMODIFIED:
  case OSYNC_CHANGE_TYPE_UNKNOWN:
  case OSYNC_CHANGE_TYPE_MODIFIED:
+ g_hash_table_replace(table->db_entries, g_strdup(uid), g_strdup(hash));
+ break;
  case OSYNC_CHANGE_TYPE_ADDED:
- osync_hashtable_write(table, uid, hash);
+ g_hash_table_insert(table->db_entries, g_strdup(uid), g_strdup(hash));
  break;
  }
 
@@ -448,51 +409,44 @@ void osync_hashtable_update_hash(OSyncHa
  */
 void osync_hashtable_report(OSyncHashTable *table, const char *uid)
 {
- osync_trace(TRACE_ENTRY, "%s(%p, %s)", __func__, table, uid);
  osync_assert(table);
  osync_assert(table->dbhandle);
+ osync_assert(uid);
+
+ osync_trace(TRACE_ENTRY, "%s(%p, %s)", __func__, table, uid);
 
- g_hash_table_insert(table->used_entries, g_strdup(uid), GINT_TO_POINTER(1));
+ g_hash_table_insert(table->reported_entries, g_strdup(uid), GINT_TO_POINTER(1));
 
  osync_trace(TRACE_EXIT, "%s", __func__);
 }
 
-/*! @brief Get the uid of all deleted items
+/*! @brief Get a list of uids which deleted
  *
  * @param table The hashtable
- * @returns A null-terminated array of uids. The uids and this array have to be freed by the caller.
+ * @returns OSyncList containing UIDs of deleted entries. Caller is responsible for freeing the list, not the content.
  *
  */
-char **osync_hashtable_get_deleted(OSyncHashTable *table)
+OSyncList *osync_hashtable_get_deleted(OSyncHashTable *table)
 {
- osync_trace(TRACE_ENTRY, "%s(%p)", __func__, table);
-
  osync_assert(table);
  osync_assert(table->dbhandle);
 
- GList *row = NULL, *result = NULL;
+ osync_trace(TRACE_ENTRY, "%s(%p)", __func__, table);
 
- char *query = g_strdup_printf("SELECT uid FROM %s", table->tablename);
- result = osync_db_query_table(table->dbhandle, query, NULL);
- g_free(query);
+ GList *e, *db_entries;
+ OSyncList *deleted_entries = NULL;
 
- int numrows = g_list_length(result);
- char **ret = g_malloc0((numrows + 1) * sizeof(char *));
-
- int num = 0;
- for (row = result; row; row = row->next) {
- GList *column = row->data;
+ db_entries = g_hash_table_get_keys(table->db_entries);
 
- const char *uid = (const char *) g_list_nth_data(column, 0);
+ for (e = db_entries; e; e = e->next) {
+ const char *uid = e->data;
 
- if (!g_hash_table_lookup(table->used_entries, uid))
- ret[num++] = g_strdup(uid);
+ if (!g_hash_table_lookup(table->reported_entries, uid))
+ deleted_entries = osync_list_prepend(deleted_entries, (char *) uid);
  }
 
- osync_db_free_list(result);
-
- osync_trace(TRACE_EXIT, "%s: %p(%i)", __func__, ret, num);
- return ret;
+ osync_trace(TRACE_EXIT, "%s: %p", __func__, deleted_entries);
+ return deleted_entries;
 }
 
 /*! @brief Gets the changetype for a given uid and hash
@@ -509,21 +463,16 @@ char **osync_hashtable_get_deleted(OSync
  */
 OSyncChangeType osync_hashtable_get_changetype(OSyncHashTable *table, const char *uid, const char *hash)
 {
- osync_trace(TRACE_ENTRY, "%s(%p, %s, %s)", __func__, table, uid, hash);
  osync_assert(table);
  osync_assert(table->dbhandle);
+ osync_assert(uid);
+ osync_assert(hash);
 
- char *orighash = NULL;
-
- OSyncChangeType retval = OSYNC_CHANGE_TYPE_UNMODIFIED;
+ osync_trace(TRACE_ENTRY, "%s(%p, %s, %s)", __func__, table, uid, hash);
 
- char *escaped_uid = osync_db_sql_escape(uid);
- char *query = g_strdup_printf("SELECT hash FROM %s WHERE uid='%s'", table->tablename, escaped_uid);
- orighash = osync_db_query_single_string(table->dbhandle, query, NULL);
- g_free(query);
- g_free(escaped_uid);
-
- osync_trace(TRACE_INTERNAL, "Comparing %s with %s", hash, orighash);
+ OSyncChangeType retval = OSYNC_CHANGE_TYPE_UNKNOWN;
+
+ const char *orighash = osync_hashtable_get_hash(table, uid);
 
  if (orighash) {
  if (!strcmp(hash, orighash))
@@ -533,10 +482,27 @@ OSyncChangeType osync_hashtable_get_chan
  } else
  retval = OSYNC_CHANGE_TYPE_ADDED;
 
- g_free(orighash);
 
  osync_trace(TRACE_EXIT, "%s: %i", __func__, retval);
  return retval;
 }
 
+unsigned int osync_hashtable_num_entries(OSyncHashTable *table)
+{
+ osync_assert(table);
+ return g_hash_table_size(table->db_entries);
+}
+
+void osync_hashtable_foreach(OSyncHashTable *table, OSyncHashtableForEach func, void *user_data)
+{
+ osync_assert(table);
+ g_hash_table_foreach(table->db_entries, (GHFunc) func, user_data);
+}
+
+const char *osync_hashtable_get_hash(OSyncHashTable *table, const char *uid)
+{
+ osync_assert(table);
+ return (const char *)  g_hash_table_lookup(table->db_entries, uid);
+}
+
 /*@}*/
Index: opensync/opensync/helper/opensync_hashtable.h
===================================================================
--- opensync.orig/opensync/helper/opensync_hashtable.h
+++ opensync/opensync/helper/opensync_hashtable.h
@@ -1,6 +1,7 @@
 /*
  * libopensync - A synchronization framework
  * Copyright (C) 2004-2005  Armin Bauer <armin.bauer@...>
+ * Copyright (C) 2008  Daniel Gollub <dgollub@...>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -21,22 +22,28 @@
 #ifndef OPENSYNC_HASHTABLE_H_
 #define OPENSYNC_HASHTABLE_H_
 
+typedef void (*OSyncHashtableForEach) (const char *uid, const char *hash, void *user_data);
+
 OSYNC_EXPORT OSyncHashTable *osync_hashtable_new(const char *path, const char *objtype, OSyncError **error);
-OSYNC_EXPORT void osync_hashtable_free(OSyncHashTable *table);
+
+OSYNC_EXPORT OSyncHashTable *osync_hashtable_ref(OSyncHashTable *table);
+OSYNC_EXPORT void osync_hashtable_unref(OSyncHashTable *table);
+
+OSYNC_EXPORT osync_bool osync_hashtable_load(OSyncHashTable *table, OSyncError **error);
+OSYNC_EXPORT osync_bool osync_hashtable_committedall(OSyncHashTable *table, OSyncError **error);
 
 OSYNC_EXPORT osync_bool osync_hashtable_slowsync(OSyncHashTable *table, OSyncError **error);
 
-OSYNC_EXPORT int osync_hashtable_num_entries(OSyncHashTable *table);
-OSYNC_EXPORT osync_bool osync_hashtable_nth_entry(OSyncHashTable *table, int i, char **uid, char **hash);
-OSYNC_EXPORT void osync_hashtable_write(OSyncHashTable *table, const char *uid, const char *hash);
-OSYNC_EXPORT void osync_hashtable_delete(OSyncHashTable *table, const char *uid);
-OSYNC_EXPORT void osync_hashtable_update_hash(OSyncHashTable *table, OSyncChangeType type, const char *uid, const char *hash);
+OSYNC_EXPORT unsigned int osync_hashtable_num_entries(OSyncHashTable *table);
+OSYNC_EXPORT void osync_hashtable_foreach(OSyncHashTable *table, OSyncHashtableForEach func, void *user_data);
+
+OSYNC_EXPORT void osync_hashtable_update_change(OSyncHashTable *table, OSyncChange *change, const char *hash);
 
 OSYNC_EXPORT void osync_hashtable_report(OSyncHashTable *table, const char *uid);
 OSYNC_EXPORT void osync_hashtable_reset_reports(OSyncHashTable *table);
 
-OSYNC_EXPORT char **osync_hashtable_get_deleted(OSyncHashTable *table);
+OSYNC_EXPORT OSyncList *osync_hashtable_get_deleted(OSyncHashTable *table);
 OSYNC_EXPORT OSyncChangeType osync_hashtable_get_changetype(OSyncHashTable *table, const char *uid, const char *hash);
-OSYNC_EXPORT char *osync_hashtable_get_hash(OSyncHashTable *table, const char *uid);
+OSYNC_EXPORT const char *osync_hashtable_get_hash(OSyncHashTable *table, const char *uid);
 
 #endif /* OPENSYNC_HASHTABLE_H_ */
Index: opensync/opensync/helper/opensync_hashtable_internals.h
===================================================================
--- opensync.orig/opensync/helper/opensync_hashtable_internals.h
+++ opensync/opensync/helper/opensync_hashtable_internals.h
@@ -22,11 +22,21 @@
 #ifndef _OPENSYNC_HASHTABLE_INTERNALS_H_
 #define _OPENSYNC_HASHTABLE_INTERNALS_H_
 
+#define OSYNC_HASHTABLE_DB_PREFIX "tbl_hash_"
+
 /*! @brief Represent a hashtable which can be used to check if changes have been modifed or deleted */
 struct OSyncHashTable {
+ int ref_count;
  OSyncDB *dbhandle;
- GHashTable *used_entries;
- char *tablename;
+
+ GHashTable *reported_entries;
+
+ GHashTable *db_entries;
+
+ char *name;
+
+ /* Only to build transaction queries */
+ GString *query;
 };
 
 #endif /*_OPENSYNC_HASHTABLE_INTERNALS_H_*/


-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Opensync-devel mailing list
Opensync-devel@...
https://lists.sourceforge.net/lists/listinfo/opensync-devel

 « Return to Thread: [patch 00/13] [RFC] Hashtable improvements and API changes

LightInTheBox - Buy quality products at wholesale price