Return NULL if fgets returns NULL (dump_log): If both first_old and

2001-08-03  Bradford Hovinen  <hovinen@ximian.com>

	* config-log.c (load_log_entry): Return NULL if fgets returns NULL
	(dump_log): If both first_old and log_data are NULL, go ahead and
	dump the file, since nothing has been loaded yet
	(config_log_garbage_collect): Don't bother dumping the log file or
	reloading

2001-08-02  Bradford Hovinen  <hovinen@ximian.com>

	* config-log.c (config_log_garbage_collect): Implement
	(dump_log): Don't dump the old file if first_old is NULL

	* main.c (main): Support --garbage_collect

	* location.c (location_garbage_collect):
	(garbage_collect_cb): Implement
This commit is contained in:
Bradford Hovinen 2001-08-03 14:38:09 +00:00 committed by Bradford Hovinen (Gdict maintainer)
parent 2989b795b3
commit a1c5aa388f
6 changed files with 185 additions and 36 deletions

View file

@ -1,3 +1,21 @@
2001-08-03 Bradford Hovinen <hovinen@ximian.com>
* config-log.c (load_log_entry): Return NULL if fgets returns NULL
(dump_log): If both first_old and log_data are NULL, go ahead and
dump the file, since nothing has been loaded yet
(config_log_garbage_collect): Don't bother dumping the log file or
reloading
2001-08-02 Bradford Hovinen <hovinen@ximian.com>
* config-log.c (config_log_garbage_collect): Implement
(dump_log): Don't dump the old file if first_old is NULL
* main.c (main): Support --garbage_collect
* location.c (location_garbage_collect):
(garbage_collect_cb): Implement
2001-07-31 Bradford Hovinen <hovinen@ximian.com>
* config-log.c: Remove socket-based synchronization system

View file

@ -518,7 +518,7 @@ config_log_reset_filenames (ConfigLog *config_log)
}
/**
* config_log_reload
* config_log_reload:
* @config_log:
*
* Reloads the entire config log, throwing out any newly created entries
@ -535,6 +535,84 @@ config_log_reload (ConfigLog *config_log)
do_load (config_log);
}
/**
* config_log_garbage_collect:
* @config_log:
* @backend_id: Backend on which to iterate
* @callback: Callback to issue on any log entry to be culled
* @data: Arbitrary data to pass to callback
*
* Iterates through the configuration log and culls excess entries for the given
* backend.
*
* The algorithm we use is the following: We scan entries in temporal order. For
* each consecutive pair of entries, let t1 be the time at which the former was
* made and t2 be the time of the latter. If K_CONST * (t2 - t1) < t2, then we
* delete the former entry and issue the callback. We select K_CONST
* appropriately, i.e. a user will likely not want to keep entries separated by
* under five minutes for very long, while she may want to keep entries
* separated by two weeks for much longer.
*/
#define K_CONST 15
void
config_log_garbage_collect (ConfigLog *config_log,
gchar *backend_id,
GarbageCollectCB callback,
gpointer data)
{
GList *node, *list = NULL;
ConfigLogEntry *e1, *e2;
time_t t1, t2, now;
g_return_if_fail (config_log != NULL);
g_return_if_fail (IS_CONFIG_LOG (config_log));
if (config_log->p->log_data == NULL)
config_log->p->log_data =
load_log_entry (config_log, NULL);
node = config_log->p->log_data;
/* We build a list of config log nodes to facilitate removing the nodes
* from the main cache at a later point
*/
while (1) {
node = find_config_log_entry_backend
(config_log, node, backend_id);
if (node == NULL)
break;
list = g_list_prepend (list, node);
node = node->next;
}
if (list == NULL) return;
now = time (NULL);
for (node = list; node->next != NULL; node = node->next) {
e1 = ((GList *) node->data)->data;
e2 = ((GList *) node->next->data)->data;
t1 = mktime (e1->date);
t2 = mktime (e2->date);
if (K_CONST * (t2 - t1) < now - t2) {
config_log->p->log_data =
g_list_remove_link (config_log->p->log_data, node->data);
callback (config_log, backend_id, e1->id, data);
}
}
g_list_free (list);
config_log->p->first_old = NULL;
}
/* Find the config log entry with the id given, starting at the given
* node. Return a pointer to the node.
*/
@ -663,7 +741,8 @@ load_log_entry (ConfigLog *config_log,
if (feof (config_log->p->file_stream))
return NULL;
fgets (buffer, 1024, config_log->p->file_stream);
if (fgets (buffer, 1024, config_log->p->file_stream) == NULL)
return NULL;
entry = g_new0 (ConfigLogEntry, 1);
entry->date = g_new0 (struct tm, 1);
@ -780,6 +859,7 @@ do_load (ConfigLog *config_log)
g_return_val_if_fail (IS_CONFIG_LOG (config_log), FALSE);
config_log->p->file_stream = fopen (config_log->p->filename, "r");
config_log->p->first_old = NULL;
return TRUE;
}
@ -791,8 +871,6 @@ do_load (ConfigLog *config_log)
static void
do_unload (ConfigLog *config_log, gboolean write_log)
{
GList *tmp;
g_return_if_fail (config_log != NULL);
g_return_if_fail (IS_CONFIG_LOG (config_log));
@ -808,13 +886,9 @@ do_unload (ConfigLog *config_log, gboolean write_log)
config_log->p->filename = NULL;
}
while (config_log->p->log_data != NULL) {
tmp = config_log->p->log_data->next;
config_log_entry_destroy
((ConfigLogEntry *) config_log->p->log_data->data);
g_list_free_1 (config_log->p->log_data);
config_log->p->log_data = tmp;
}
g_list_foreach (config_log->p->log_data, (GFunc) config_log_entry_destroy, NULL);
g_list_free (config_log->p->log_data);
config_log->p->log_data = NULL;
}
/* Returns the next id number in the sequence */
@ -905,13 +979,16 @@ dump_log (ConfigLog *config_log)
first = first->next)
write_log (output, first->data);
config_log->p->first_old = config_log->p->log_data;
if (config_log->p->file_stream) {
if (config_log->p->file_stream != NULL &&
((config_log->p->first_old == NULL && config_log->p->log_data == NULL) ||
(config_log->p->first_old != NULL && config_log->p->log_data != NULL)))
{
rewind (config_log->p->file_stream);
dump_file (config_log->p->file_stream, output);
}
config_log->p->first_old = config_log->p->log_data;
fclose (output);
if (config_log->p->filename)

View file

@ -40,6 +40,7 @@ typedef struct _Location Location;
typedef gint (*ConfigLogIteratorCB) (ConfigLog *, gint, gchar *,
struct tm *, gpointer);
typedef void (*GarbageCollectCB) (ConfigLog *, gchar *, gint, gpointer);
struct _ConfigLog
{
@ -81,4 +82,9 @@ void config_log_iterate (ConfigLog *config_log,
void config_log_reset_filenames (ConfigLog *config_log);
void config_log_reload (ConfigLog *config_log);
void config_log_garbage_collect (ConfigLog *config_log,
gchar *backend_id,
GarbageCollectCB callback,
gpointer data);
#endif /* __CONFIG_LOG */

View file

@ -1280,6 +1280,42 @@ location_get_config_log (Location *location)
return location->p->config_log;
}
/* location_garbage_collect:
* @location:
*
* Iterates through backends and eliminates excess archived data from the
* configuration log and the XML archive
*/
static void
garbage_collect_cb (ConfigLog *config_log, gchar *backend_id, gint id, Location *location)
{
gchar *filename;
filename = g_strdup_printf ("%s/%08x.xml", location->p->fullpath, id);
DEBUG_MSG ("Removing %s", filename);
unlink (filename);
g_free (filename);
}
void
location_garbage_collect (Location *location)
{
GList *node;
BackendNote *note;
g_return_if_fail (location != NULL);
g_return_if_fail (IS_LOCATION (location));
for (node = location->p->contains_list; node != NULL; node = node->next) {
note = node->data;
config_log_garbage_collect (location->p->config_log,
note->backend_id,
(GarbageCollectCB) garbage_collect_cb,
location);
}
}
static gint
get_backends_cb (BackendList *backend_list, gchar *backend_id,
Location *location)
@ -1292,8 +1328,7 @@ get_backends_cb (BackendList *backend_list, gchar *backend_id,
/* Construct the directory structure for a given location
*
* FIXME: Better error reporting
*/
* FIXME: Better error reporting */
static gboolean
do_create (Location *location)

View file

@ -149,4 +149,6 @@ gboolean location_does_backend_change (Location *location,
ConfigLog *location_get_config_log (Location *location);
void location_garbage_collect (Location *location);
#endif /* __LOCATION */

View file

@ -44,6 +44,7 @@ static gboolean rollback;
static gboolean change_location;
static gboolean rename_location;
static gboolean push_config;
static gboolean garbage_collect;
static gboolean add_location;
static gboolean remove_location;
@ -91,6 +92,8 @@ static struct poptOption archiver_operations[] = {
N_("Add a given backend to the given location")},
{"remove-backend", '\0', POPT_ARG_NONE, &remove_backend, 0,
N_("Remove the given backend from the given location")},
{"garbage-collect", '\0', POPT_ARG_NONE, &garbage_collect, 0,
N_("Perform garbage collection on the given location")},
{NULL, '\0', 0, NULL, 0}
};
@ -297,6 +300,12 @@ do_remove_backend (Location *location)
location_remove_backend (location, backend_id);
}
static void
do_garbage_collect (Location *location)
{
location_garbage_collect (location);
}
int
main (int argc, char **argv)
{
@ -365,6 +374,8 @@ main (int argc, char **argv)
do_add_backend (location);
else if (remove_backend)
do_remove_backend (location);
else if (garbage_collect)
do_garbage_collect (location);
archive_close (archive);