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:
parent
2989b795b3
commit
a1c5aa388f
6 changed files with 185 additions and 36 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue