/* * libopensync - A synchronization framework * Copyright (C) 2004-2005 Armin Bauer * Copyright (C) 2008 Daniel Gollub * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef OPENSYNC_HASHTABLE_H_ #define OPENSYNC_HASHTABLE_H_ typedef void (*OSyncHashtableForEach) (const char *uid, const char *hash, void *user_data); /** * @defgroup OSyncHashtableAPI OpenSync Hashtables * @ingroup OSyncHelper * @brief A Hashtable can be used to detect changes * * Hashtables can be used to detect changes since the last invocation. They do this * by keeping track of all reported uids and the hashes of the objects. * * A hash is a string that changes when an object is updated or when the content of * the object changes. So hashes can either be a real hash like an MD5, or something * like a timestamp. The only important thing is that the hash changes when the item * gets updated. * * The hashtable is created from a .db file using the osync_hashtable_new() function. * * With osync_hashtable_load() the pertinent database gets read and loads all hashtable * entries into memory. * * Now you can query and alter the hashtable in memory. You can ask if a item has changed * by doing: * * - osync_hashtable_get_changetype() * To get the changetype of a certain OSyncChange object. Don't forget to update the hash for * the change in advance. Update your OSyncChange with this detect changetype with * osync_change_set_changetype() * * - osync_hashtable_update_change() * When the changetype got updated for the OSyncChange object, update the hash entry with * calling osync_hashtable_update_change(). Call this function even if the entry has changetype * unmodified. Otherwise the hashtable will report this entry later as deleted. * * - osync_hashtable_get_deleted() * Once all available changes got reported call osync_hashtable_get_deleted() to get an OSyncList * of changes which got deleted since last sync. Entries get determined as deleted if they * got not reported as osync_hashtable_update_change(), independent of the changetype. * * - osync_hashtable_save() * For performance reason the hashtable in memory got only stored persistence with calling * osync_hashtable_save(). Call this function everytime when the synchronization finished. * This is usually inside the sync_done() function. * * After you are finished using the hashtable, call: * - osync_hashtable_unref() * * The hashtable works like this: * * First the items are reported with a certain uid or hash. If the uid does not yet * exist in the database it is reported as ADDED. If the uid exists and the hash is different * it is reported as MODIFIED. If the uid exists but the hash is the same it means that the * object is UNMODIFIED. * * To be able to report deleted objects the hashtables keeps track of the uids you reported. * After you are done with asking the hashtable for changes you can ask it for deleted objects. * All items that are in the hashtable but where not reported by you have to be DELETED. * */ /*@{*/ /** @brief Prepares the hashtable for a slowsync and flush the entire hashtable * * This function should be called to prepare the hashtable for a slowsync. * The entire database, which stores the values of the hashtable beyond the * synchronization, will be flushed. * * @param table The hashtable * @param error An error struct * @returns TRUE on success, or FALSE if an error occurred. * */ OSYNC_EXPORT osync_bool osync_hashtable_slowsync(OSyncHashTable *table, OSyncError **error); /** @brief Call a function over all of the entries * * @param table The hashtable to operate on * @param func The function to call for each entry * @param user_data Pointer to custom data to send to the function * */ OSYNC_EXPORT void osync_hashtable_foreach(OSyncHashTable *table, OSyncHashtableForEach func, void *user_data); /** @brief Update an entry from a change * * Updates the entry in the hashtable. Use this even if the change entry * is unmodified! Usually this function get called in get_changes(). In some * rare cases this get even called inside of the commit() plugin functions, * to update the UID inside the hashtable of a changed entry. * * @param table The hashtable * @param change The change object for the entry */ OSYNC_EXPORT void osync_hashtable_update_change(OSyncHashTable *table, OSyncChange *change); /** @brief Get a list of uids which are marked as deleted * * @param table The hashtable * @returns OSyncList containing UIDs of deleted entries. Caller is responsible for freeing the ist, * not the content, with osync_list_free() . * */ OSYNC_EXPORT OSyncList *osync_hashtable_get_deleted(OSyncHashTable *table); /** @brief Gets the changetype for the given OSyncChange object, by comparing the hashes * of the hashtable and OSyncChange object. * * This function does not report the change so if you only use this function then * the object will get reported as deleted! Please use osync_hashtable_update_change() for reporting * a change. * * @param table The hashtable * @param change The change object for the entry * @returns The changetype * */ OSYNC_EXPORT OSyncChangeType osync_hashtable_get_changetype(OSyncHashTable *table, OSyncChange *change); /** @brief Get the hash of an entry * * @param table The hashtable * @param uid the uid of the entry to find * @returns the hash for the entry, or NULL if not found * */ OSYNC_EXPORT const char *osync_hashtable_get_hash(OSyncHashTable *table, const char *uid); /*@}*/ #endif /* OPENSYNC_HASHTABLE_H_ */