[gvfs] Implement metadata journal rollover
- From: Alexander Larsson <alexl src gnome org>
- To: svn-commits-list gnome org
- Subject: [gvfs] Implement metadata journal rollover
- Date: Tue, 23 Jun 2009 11:10:53 -0400 (EDT)
commit 29311f8169487f9549945157fe056e789c30e9a2
Author: Alexander Larsson <alexl redhat com>
Date: Mon Jun 22 11:33:34 2009 +0200
Implement metadata journal rollover
metadata/metatree.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 157 insertions(+), 15 deletions(-)
---
diff --git a/metadata/metatree.c b/metadata/metatree.c
index 315b603..26407f0 100644
--- a/metadata/metatree.c
+++ b/metadata/metatree.c
@@ -447,6 +447,22 @@ meta_tree_has_new_journal_entries (MetaTree *tree)
return journal->last_entry_num < num_entries;
}
+
+/* Must be called with a write lock held */
+static void
+meta_tree_refresh_locked (MetaTree *tree)
+{
+ /* Needs to recheck since we dropped read lock */
+ if (meta_tree_needs_rereading (tree))
+ {
+ if (tree->header)
+ meta_tree_clear (tree);
+ meta_tree_init (tree);
+ }
+ else if (meta_tree_has_new_journal_entries (tree))
+ meta_journal_validate_more (tree->journal);
+}
+
void
meta_tree_refresh (MetaTree *tree)
{
@@ -461,22 +477,9 @@ meta_tree_refresh (MetaTree *tree)
if (needs_refresh)
{
g_static_rw_lock_writer_lock (&metatree_lock);
-
- /* Needs to recheck since we dropped read lock */
- if (meta_tree_needs_rereading (tree))
- {
- if (tree->header)
- meta_tree_clear (tree);
- meta_tree_init (tree);
- }
- else if (meta_tree_has_new_journal_entries (tree))
- meta_journal_validate_more (tree->journal);
-
+ meta_tree_refresh_locked (tree);
g_static_rw_lock_writer_unlock (&metatree_lock);
}
- else
- {
- }
}
struct FindName {
@@ -1753,11 +1756,150 @@ meta_tree_enumerate_keys (MetaTree *tree,
g_static_rw_lock_reader_unlock (&metatree_lock);
}
+
+static void
+copy_tree_to_builder (MetaTree *tree,
+ MetaFileDirEnt *dirent,
+ MetaFile *builder_file)
+{
+ MetaFile *builder_child;
+ MetaFileData *data;
+ MetaFileDataEnt *ent;
+ MetaFileDir *dir;
+ MetaFileDirEnt *child_dirent;
+ MetaKeyType type;
+ char *child_name, *key_name, *value;
+ guint32 i, num_keys, num_children;
+ guint32 key_id;
+
+ /* Copy metadata */
+ data = verify_metadata_block (tree, dirent->metadata);
+ if (data)
+ {
+ num_keys = GUINT32_FROM_BE (data->num_keys);
+ for (i = 0; i < num_keys; i++)
+ {
+ ent = &data->keys[i];
+
+ key_id = GUINT32_FROM_BE (ent->key) & ~KEY_IS_LIST_MASK;
+ if (GUINT32_FROM_BE (ent->key) & KEY_IS_LIST_MASK)
+ type = META_KEY_TYPE_STRINGV;
+ else
+ type = META_KEY_TYPE_STRING;
+
+ if (key_id >= tree->num_attributes)
+ continue;
+
+ key_name = tree->attributes[key_id];
+ if (key_name == NULL)
+ continue;
+
+ if (type == META_KEY_TYPE_STRING)
+ {
+ value = verify_string (tree, ent->value);
+ metafile_key_set_value (builder_file,
+ key_name, value);
+ }
+ else
+ {
+ g_print ("TODO: Handle stringv metadata from tree\n");
+ }
+ }
+ }
+
+ /* Copy last changed time */
+ builder_file->last_changed = get_time_t (tree, dirent->last_changed);
+
+ /* Copy children */
+ if (dirent->children != 0 &&
+ (dir = verify_children_block (tree, dirent->children)) != NULL)
+ {
+ num_children = GUINT32_FROM_BE (dir->num_children);
+ for (i = 0; i < num_children; i++)
+ {
+ child_dirent = &dir->children[i];
+ child_name = verify_string (tree, child_dirent->name);
+ if (child_name != NULL)
+ {
+ builder_child = metafile_new (child_name, builder_file);
+ copy_tree_to_builder (tree, child_dirent, builder_child);
+ }
+ }
+ }
+}
+
+static void
+apply_journal_to_builder (MetaTree *tree,
+ MetaBuilder *builder)
+{
+ MetaJournal *journal;
+ MetaJournalEntry *entry;
+ guint32 *sizep;
+ char *journal_path, *journal_key, *source_path;
+ char *value;
+ MetaFile *file;
+
+ journal = tree->journal;
+
+ entry = journal->first_entry;
+ while (entry < journal->last_entry)
+ {
+ journal_path = &entry->path[0];
+
+ switch (entry->entry_type)
+ {
+ case JOURNAL_OP_SET_KEY:
+ journal_key = get_next_arg (journal_path);
+ value = get_next_arg (journal_key);
+ file = meta_builder_lookup (builder, journal_path, TRUE);
+ metafile_key_set_value (file,
+ journal_key,
+ value);
+ break;
+ case JOURNAL_OP_SETV_KEY:
+ journal_key = get_next_arg (journal_path);
+ value = get_next_arg (journal_key);
+ /* TODO */
+ break;
+ case JOURNAL_OP_UNSET_KEY:
+ journal_key = get_next_arg (journal_path);
+ /* TODO */
+ break;
+ case JOURNAL_OP_COPY_PATH:
+ source_path = get_next_arg (journal_path);
+ /* TODO */
+ break;
+ case JOURNAL_OP_REMOVE_PATH:
+ /* TODO */
+ break;
+ default:
+ break;
+ }
+
+ sizep = (guint32 *)entry;
+ entry = (MetaJournalEntry *)((char *)entry + GUINT32_FROM_BE (*(sizep)));
+ }
+}
+
+
/* Needs write lock */
static gboolean
meta_tree_flush_locked (MetaTree *tree)
{
- /* TODO: roll over */
+ MetaBuilder *builder;
+
+ builder = meta_builder_new ();
+
+ copy_tree_to_builder (tree, tree->root, builder->root);
+
+ if (tree->journal)
+ apply_journal_to_builder (tree, builder);
+
+ meta_builder_write (builder,
+ meta_tree_get_filename (tree));
+
+ meta_tree_refresh_locked (tree);
+
return FALSE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]