View Issue Details

IDProjectCategoryView StatusLast Update
0002046gnunet-gtkgnunet-fs-gtkpublic2012-02-28 11:06
ReporterLRN Assigned ToChristian Grothoff  
PrioritylowSeverityminorReproducibilityN/A
Status closedResolutionfixed 
Product VersionGit master 
Target Version0.9.2Fixed in Version0.9.2 
Summary0002046: [patch] Keywords are not forwarded to parent directories
DescriptionOnly metadata is counted and forwarded, not keywords. This becomes obvious, if you share a directory that contains files with similar names (say, having the same prefix). Keywords are generated from the filename right away (a recent development) in FS library, and GNUnet FS GTK does not take that into account and only counts metadata.

It probably means that we should add a separate multihashmap to count keywords...
TagsNo tags attached.
Attached Files
0003-Give-all-directories-embedded-names.patch (2,467 bytes)   
From 0946584ddd12919accccefb8708aece107c74b09 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=A0=D1=83=D1=81=D0=BB=D0=B0=D0=BD=20=D0=98=D0=B6=D0=B1=D1?=
 =?UTF-8?q?=83=D0=BB=D0=B0=D1=82=D0=BE=D0=B2?= <lrn1986@gmail.com>
Date: Wed, 28 Dec 2011 23:35:42 +0400
Subject: [PATCH 3/4] Give all directories embedded names

---
 src/fs/gnunet-fs-gtk-main_window_file_publish.c |   22 ++++++++++++----------
 1 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/src/fs/gnunet-fs-gtk-main_window_file_publish.c b/src/fs/gnunet-fs-gtk-main_window_file_publish.c
index 61a1c70..95dbdf2 100644
--- a/src/fs/gnunet-fs-gtk-main_window_file_publish.c
+++ b/src/fs/gnunet-fs-gtk-main_window_file_publish.c
@@ -741,6 +741,7 @@ scan_directory (void *cls, const char *filename)
     return GNUNET_OK;
   if (S_ISDIR (sbuf.st_mode))
   {
+    const char *ss, *short_fn;
     parent = adc->parent;
     mhm = adc->metamap;
     mcm = adc->metacounter;
@@ -760,6 +761,17 @@ scan_directory (void *cls, const char *filename)
     adc->metacounter = mcm;
     adc->parent = parent;
     adc->dir_entry_count = pc + 1;
+
+    short_fn = filename;
+    while (NULL != (ss = strstr (short_fn, DIR_SEPARATOR_STR)) && ss[1] != '\0')
+      short_fn = 1 + ss;
+
+    GNUNET_CONTAINER_meta_data_insert (pd->meta, "<gnunet-gtk>",
+                                       EXTRACTOR_METATYPE_FILENAME,
+                                       EXTRACTOR_METAFORMAT_UTF8,
+                                       "text/plain", short_fn,
+                                       strlen (short_fn) + 1);
+
     if (adc->metamap != NULL)
     {
       GNUNET_CRYPTO_hash (filename, strlen (filename), &hc);
@@ -769,18 +781,8 @@ scan_directory (void *cls, const char *filename)
     }
     else
     {
-      const char *ss, *short_fn;
-
       GNUNET_assert (mcm == NULL);
       /* we're top-level */
-      short_fn = filename;
-      while (NULL != (ss = strstr (short_fn, DIR_SEPARATOR_STR)))
-        short_fn = 1 + ss;
-      GNUNET_CONTAINER_meta_data_insert (pd->meta, "<gnunet-gtk>",
-                                         EXTRACTOR_METATYPE_FILENAME,
-                                         EXTRACTOR_METAFORMAT_UTF8,
-                                         "text/plain", filename,
-                                         strlen (filename) + 1);
       add_entry_to_ts (adc->ts, &pd->iter, filename, &adc->bo, adc->do_index,
                        NULL, pd->meta);
     }
-- 
1.7.4

0004-Count-and-propagate-keywords-instead-of-metadata.patch (14,487 bytes)   
From fd30a251baab44bae0bb4e1287596ea6e9bbfec6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=A0=D1=83=D1=81=D0=BB=D0=B0=D0=BD=20=D0=98=D0=B6=D0=B1=D1?=
 =?UTF-8?q?=83=D0=BB=D0=B0=D1=82=D0=BE=D0=B2?= <lrn1986@gmail.com>
Date: Fri, 30 Dec 2011 04:12:08 +0400
Subject: [PATCH 4/4] Count and propagate keywords instead of metadata

---
 src/fs/gnunet-fs-gtk-main_window_file_publish.c |  190 ++++++++++-------------
 1 files changed, 79 insertions(+), 111 deletions(-)

diff --git a/src/fs/gnunet-fs-gtk-main_window_file_publish.c b/src/fs/gnunet-fs-gtk-main_window_file_publish.c
index 95dbdf2..f953a9c 100644
--- a/src/fs/gnunet-fs-gtk-main_window_file_publish.c
+++ b/src/fs/gnunet-fs-gtk-main_window_file_publish.c
@@ -329,6 +329,11 @@ struct PublishData
   struct GNUNET_CONTAINER_MetaData *meta;
 
   /**
+   * Keywords for the file (derived from metadata).
+   */
+  struct GNUNET_FS_Uri *ksk_uri;
+
+  /**
    * Iterator for the entry.
    */
   GtkTreeIter iter;
@@ -336,10 +341,10 @@ struct PublishData
 
 
 /**
- * Entry for each unique meta data entry to track how often
+ * Entry for each unique keyword to track how often
  * it occured.  Contains the keyword and the counter.
  */
-struct MetaCounter
+struct KeywordCounter
 {
 
   /**
@@ -348,21 +353,6 @@ struct MetaCounter
   const char *value;
 
   /**
-   * Mimetype of the value.
-   */
-  const char *value_mimetype;
-
-  /**
-   * Type of the value.
-   */
-  enum EXTRACTOR_MetaType type;
-
-  /**
-   * Format of the value.
-   */
-  enum EXTRACTOR_MetaFormat format;
-
-  /**
    * How many files have meta entries matching this value?
    * (type and format do not have to match).
    */
@@ -388,11 +378,11 @@ struct AddDirContext
   GtkTreeStore *ts;
 
   /**
-   * Map from the hash over the meta value to an 'struct MetaCounter'
-   * counter that says how often this value was
+   * Map from the hash over the keyword to an 'struct KeywordCounter'
+   * counter that says how often this keyword was
    * encountered in the current directory.
    */
-  struct GNUNET_CONTAINER_MultiHashMap *metacounter;
+  struct GNUNET_CONTAINER_MultiHashMap *keywordcounter;
 
   /**
    * Map from the hash of a filename in the current directory
@@ -401,10 +391,10 @@ struct AddDirContext
   struct GNUNET_CONTAINER_MultiHashMap *metamap;
 
   /**
-   * Metadata to exclude from using for KSK since it'll be associated
+   * Keywords to exclude from using for KSK since they'll be associated
    * with the parent as well.  NULL for nothing blocked.
    */
-  struct GNUNET_CONTAINER_MetaData *no_ksk;
+  struct GNUNET_FS_Uri *exclude_ksk;
 
   /**
    * Block options to use.
@@ -424,71 +414,45 @@ struct AddDirContext
 
 
 /**
- * Add the given meta data item to the
- * meta data statistics tracker.
+ * Add the given keyword to the
+ * keyword statistics tracker.
  *
  * @param cls closure (user-defined)
- * @param plugin_name name of the plugin that produced this value;
- *        special values can be used (i.e. '<zlib>' for zlib being
- *        used in the main libextractor library and yielding
- *        meta data).
- * @param type libextractor-type describing the meta data
- * @param format basic format information about data
- * @param data_mime_type mime-type of data (not of the original file);
- *        can be NULL (if mime-type is not known)
- * @param data actual meta-data found
- * @param data_len number of bytes in data
- * @return 0 to continue extracting, 1 to abort
+ * @param keyword the keyword to count
+ * @param is_mandatory ignored
+ * @return always GNUNET_OK
  */
 static int
-add_to_meta_counter (void *cls, const char *plugin_name,
-                     enum EXTRACTOR_MetaType type,
-                     enum EXTRACTOR_MetaFormat format,
-                     const char *data_mime_type, const char *data,
-                     size_t data_len)
+add_to_keyword_counter (void *cls, const char *keyword, int is_mandatory)
 {
   struct GNUNET_CONTAINER_MultiHashMap *mcm = cls;
-  struct MetaCounter *cnt;
+  struct KeywordCounter *cnt;
   GNUNET_HashCode hc;
-  size_t mlen;
-  size_t dlen;
-
-  if ((format != EXTRACTOR_METAFORMAT_UTF8) &&
-      (format != EXTRACTOR_METAFORMAT_C_STRING))
-    return 0;
-  dlen = strlen (data) + 1;
-  GNUNET_CRYPTO_hash (data, dlen - 1, &hc);
+  size_t klen;
+
+  klen = strlen (keyword) + 1;
+  GNUNET_CRYPTO_hash (keyword, klen - 1, &hc);
   cnt = GNUNET_CONTAINER_multihashmap_get (mcm, &hc);
   if (cnt == NULL)
   {
-    mlen = strlen (data_mime_type) + 1;
-    cnt = GNUNET_malloc (sizeof (struct MetaCounter) + dlen + mlen);
+    cnt = GNUNET_malloc (sizeof (struct KeywordCounter) + klen);
     cnt->count = 1;
     cnt->value = (const char *) &cnt[1];
-    cnt->value_mimetype = &cnt->value[dlen];
-    memcpy (&cnt[1], data, dlen);
-    memcpy ((char *) cnt->value_mimetype, data_mime_type, mlen);
-    cnt->type = type;
-    cnt->format = format;
+    memcpy (&cnt[1], keyword, klen);
     GNUNET_CONTAINER_multihashmap_put (mcm, &hc, cnt,
                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
-
   }
   else
   {
     cnt->count++;
-    if (cnt->format == EXTRACTOR_METAFORMAT_C_STRING)
-      cnt->format = format;     /* possibly improve to UTF8 */
-    if (cnt->type == EXTRACTOR_METATYPE_UNKNOWN)
-      cnt->type = type;
   }
-  return 0;
+  return GNUNET_OK;
 }
 
 
 /**
  * Extract metadata from a file and add it to the metamap and
- * the metacounter.
+ * the keywordcounter.
  *
  * @param adc context to modify
  * @param filename name of the file to process
@@ -517,11 +481,13 @@ extract_file (struct AddDirContext *adc, const char *filename)
                                      short_fn, strlen (short_fn) + 1);
 
   gtk_tree_store_insert_before (adc->ts, &pd->iter, adc->parent, NULL);
+
   GNUNET_CRYPTO_hash (filename, strlen (filename), &hc);
   GNUNET_CONTAINER_multihashmap_put (adc->metamap, &hc, pd,
                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
-  GNUNET_CONTAINER_meta_data_iterate (pd->meta, &add_to_meta_counter,
-                                      adc->metacounter);
+
+  pd->ksk_uri = GNUNET_FS_uri_ksk_create_from_meta_data (pd->meta);
+  GNUNET_FS_uri_ksk_get_keywords (pd->ksk_uri, &add_to_keyword_counter, adc->keywordcounter);
 }
 
 
@@ -545,21 +511,22 @@ remove_keyword (void *cls, const char *keyword, int is_mandatory)
 
 /**
  * Add the specifics of the given entry to the tree store.
- * Derive KSK from the given meta data, but exclude meta
- * data given in "md_no_ksk" for keyword generation.
+ * Use keywords from ksk_uri, but exclude the ones given in
+ * "md_no_ksk".
  *
  * @param ts tree store to modify
  * @param iter position in the tree store for this file
  * @param filename file to add
  * @param bo block options
  * @param do_index should we index or insert?
- * @param md_no_ksk metadata with keywords NOT to add
- * @param meta metadata for the file
+ * @param ksk_uri keywords to use. Will be destroyed at the end.
+ * @param exclude_ksk keywords NOT to use. Won't be modified.
+ * @param meta metadata for the file. Will be destroyed at the end.
  */
 static void
 add_entry_to_ts (GtkTreeStore * ts, GtkTreeIter * iter, const char *filename,
                  const struct GNUNET_FS_BlockOptions *bo, int do_index,
-                 struct GNUNET_CONTAINER_MetaData *md_no_ksk,
+                 struct GNUNET_FS_Uri *ksk_uri, struct GNUNET_FS_Uri *exclude_ksk,
                  struct GNUNET_CONTAINER_MetaData *meta)
 {
   char *file_size_fancy;
@@ -567,8 +534,6 @@ add_entry_to_ts (GtkTreeStore * ts, GtkTreeIter * iter, const char *filename,
   GtkTreeRowReference *row_reference;
   GtkTreePath *path;
   uint64_t file_size;
-  struct GNUNET_FS_Uri *ksk_uri;
-  struct GNUNET_FS_Uri *kill_ksk;
   const char *ss;
   const char *short_fn;
   struct stat sbuf;
@@ -587,12 +552,9 @@ add_entry_to_ts (GtkTreeStore * ts, GtkTreeIter * iter, const char *filename,
       return;
     }
   }
-  ksk_uri = GNUNET_FS_uri_ksk_create_from_meta_data (meta);
-  kill_ksk = GNUNET_FS_uri_ksk_create_from_meta_data (md_no_ksk);
-  if (kill_ksk != NULL)
+  if (exclude_ksk != NULL)
   {
-    GNUNET_FS_uri_ksk_get_keywords (kill_ksk, &remove_keyword, ksk_uri);
-    GNUNET_FS_uri_destroy (kill_ksk);
+    GNUNET_FS_uri_ksk_get_keywords (exclude_ksk, &remove_keyword, ksk_uri);
   }
   path = gtk_tree_model_get_path (GTK_TREE_MODEL (ts), iter);
   row_reference = gtk_tree_row_reference_new (GTK_TREE_MODEL (ts), path);
@@ -647,7 +609,7 @@ publish_entry (void *cls, const char *filename)
   GNUNET_CRYPTO_hash (filename, strlen (filename), &hc);
   pd = GNUNET_CONTAINER_multihashmap_get (adc->metamap, &hc);
   add_entry_to_ts (adc->ts, &pd->iter, filename, &adc->bo, adc->do_index,
-                   adc->no_ksk, pd->meta);
+                   pd->ksk_uri, adc->exclude_ksk, pd->meta);
   GNUNET_CONTAINER_multihashmap_remove (adc->metamap, &hc, pd);
   GNUNET_free (pd);
   return GNUNET_OK;
@@ -657,12 +619,12 @@ publish_entry (void *cls, const char *filename)
 /**
  * Context passed to 'migrate_and_drop'.
  */
-struct MetaProcessContext
+struct KeywordProcessContext
 {
   /**
-   * Metadata with all the keywords we migrated to the parent.
+   * All the keywords we migrated to the parent.
    */
-  struct GNUNET_CONTAINER_MetaData *md;
+  struct GNUNET_FS_Uri *ksk;
 
   /**
    * How often does a keyword have to occur to be
@@ -673,22 +635,19 @@ struct MetaProcessContext
 
 
 /**
- * Copy "frequent" meta data entries over to the
- * target meta data struct, free the counters.
+ * Copy "frequent" keywords over to the
+ * target ksk uri, free the counters.
  *
  */
 static int
 migrate_and_drop (void *cls, const GNUNET_HashCode * key, void *value)
 {
-  struct MetaProcessContext *mpc = cls;
-  struct MetaCounter *counter = value;
+  struct KeywordProcessContext *kpc = cls;
+  struct KeywordCounter *counter = value;
 
-  if (counter->count >= mpc->threshold && counter->count > 1)
+  if (counter->count >= kpc->threshold && counter->count > 1)
   {
-    GNUNET_CONTAINER_meta_data_insert (mpc->md, "<gnunet-gtk>", counter->type,
-                                       counter->format, counter->value_mimetype,
-                                       counter->value,
-                                       strlen (counter->value) + 1);
+    GNUNET_FS_uri_ksk_add_keyword (kpc->ksk, counter->value, GNUNET_NO);
   }
   GNUNET_free (counter);
   return GNUNET_YES;
@@ -696,24 +655,31 @@ migrate_and_drop (void *cls, const GNUNET_HashCode * key, void *value)
 
 
 /**
- * Go over the collected meta data from all entries in the
- * directory and push common meta data up one level (by
+ * Go over the collected keywords from all entries in the
+ * directory and push common keywords up one level (by
  * adding it to the returned struct).
  *
  * @param adc collection of child meta data
  * @return meta data to moved to parent
  */
-static struct GNUNET_CONTAINER_MetaData *
-process_metadata (struct AddDirContext *adc)
+static struct GNUNET_FS_Uri *
+process_keywords (struct AddDirContext *adc)
 {
-  struct MetaProcessContext mpc;
-
-  mpc.md = GNUNET_CONTAINER_meta_data_create ();
-  mpc.threshold = (adc->dir_entry_count + 1) / 2;       /* 50% */
-  GNUNET_CONTAINER_multihashmap_iterate (adc->metacounter, &migrate_and_drop,
-                                         &mpc);
-  GNUNET_CONTAINER_multihashmap_destroy (adc->metacounter);
-  return mpc.md;
+  struct KeywordProcessContext kpc;
+  struct GNUNET_CONTAINER_MetaData *tmp;
+
+  tmp = GNUNET_CONTAINER_meta_data_create ();
+
+  /* Surprisingly, it's impossible to create a ksk with 0 keywords directly.
+   * But we can create one from an empty metadata set
+   */
+  kpc.ksk = GNUNET_FS_uri_ksk_create_from_meta_data (tmp);
+  GNUNET_CONTAINER_meta_data_destroy (tmp);
+  kpc.threshold = (adc->dir_entry_count + 1) / 2;       /* 50% */
+  GNUNET_CONTAINER_multihashmap_iterate (adc->keywordcounter, &migrate_and_drop,
+                                         &kpc);
+  GNUNET_CONTAINER_multihashmap_destroy (adc->keywordcounter);
+  return kpc.ksk;
 }
 
 
@@ -734,7 +700,7 @@ scan_directory (void *cls, const char *filename)
   struct PublishData *pd;
   GNUNET_HashCode hc;
   struct GNUNET_CONTAINER_MultiHashMap *mhm;
-  struct GNUNET_CONTAINER_MultiHashMap *mcm;
+  struct GNUNET_CONTAINER_MultiHashMap *kcm;
   unsigned int pc;
 
   if (0 != STAT (filename, &sbuf))
@@ -744,21 +710,22 @@ scan_directory (void *cls, const char *filename)
     const char *ss, *short_fn;
     parent = adc->parent;
     mhm = adc->metamap;
-    mcm = adc->metacounter;
+    kcm = adc->keywordcounter;
     pc = adc->dir_entry_count;
     adc->metamap = GNUNET_CONTAINER_multihashmap_create (1024);
-    adc->metacounter = GNUNET_CONTAINER_multihashmap_create (1024);
+    adc->keywordcounter = GNUNET_CONTAINER_multihashmap_create (1024);
     adc->dir_entry_count = 0;
     pd = GNUNET_malloc (sizeof (struct PublishData));
     gtk_tree_store_insert_before (adc->ts, &pd->iter, parent, NULL);
     adc->parent = &pd->iter;
     GNUNET_DISK_directory_scan (filename, &scan_directory, adc);
-    pd->meta = process_metadata (adc);
-    adc->no_ksk = pd->meta;
+    pd->ksk_uri = process_keywords (adc);
+    pd->meta = GNUNET_CONTAINER_meta_data_create ();
+    adc->exclude_ksk = GNUNET_FS_uri_dup (pd->ksk_uri);
     GNUNET_DISK_directory_scan (filename, &publish_entry, adc);
     GNUNET_CONTAINER_multihashmap_destroy (adc->metamap);
     adc->metamap = mhm;
-    adc->metacounter = mcm;
+    adc->keywordcounter = kcm;
     adc->parent = parent;
     adc->dir_entry_count = pc + 1;
 
@@ -777,15 +744,16 @@ scan_directory (void *cls, const char *filename)
       GNUNET_CRYPTO_hash (filename, strlen (filename), &hc);
       GNUNET_CONTAINER_multihashmap_put (adc->metamap, &hc, pd,
                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
-      GNUNET_CONTAINER_meta_data_iterate (pd->meta, &add_to_meta_counter, mcm);
+      GNUNET_FS_uri_ksk_get_keywords (pd->ksk_uri, &add_to_keyword_counter, kcm);
     }
     else
     {
-      GNUNET_assert (mcm == NULL);
+      GNUNET_assert (kcm == NULL);
       /* we're top-level */
       add_entry_to_ts (adc->ts, &pd->iter, filename, &adc->bo, adc->do_index,
-                       NULL, pd->meta);
+                       pd->ksk_uri, NULL, pd->meta);
     }
+    GNUNET_FS_uri_destroy (adc->exclude_ksk);
   }
   else
   {
-- 
1.7.4

Activities

LRN

2011-12-29 19:12

developer   ~0005215

Actually, it's not clear to me whether we want to reduce the number of keywords, of metadata entries, or both.

Also, more precise description of what is happening: GNUnet-fs-gtk first scans the directory tree and counts metadata entries, and only then walks the tree again, publishing files/directories, and that is when it calculates keywords, and which point it's too late to count and forward them.
So now GNUnet-fs-gtk has to be modified to generate keywords right away, when file info is extracted, then store them, count them, and forward some of them to parent directory.

LRN

2011-12-30 00:07

developer   ~0005216

Since +1 keyword means +1KBlock (up to 60k per KBlock), and +1 metadata entry means +N bytes in every KBlock, and considering the fact that metadata might include unique-to-a-file (and thus non-propagatable) preview images that are large compared to string-type metadata, i'm assuming that it's actually OK to keep metadata in files, even if it is duplicated for every file. Reducing the amount of metadata will only make KBlocks slightly smaller, but that's it.

Also, having full metadata for every file seems to be beneficial in the sense that keywords get propagated to the parent directory, and you'll find a directory by searching for these keywords, but you probably wanted some files, not the whole directory. If metadata is kept for all files in the directory, you can download it and decide which files you want to download. If it gets propagated upwards, you have no choice other than to download the whole directory.

LRN

2011-12-30 01:22

developer   ~0005217

Added two patches.

0003-Give-all-directories-embedded-names.patch is not really about propagation, it just adds embedded names to directories (for some reason they weren't getting embedded names). The next patch depends on it though.

0004-Count-and-propagate-keywords-instead-of-metadata.patch counts and propagates keywords instead of metadata. Works for me as intended - i have a directory with 11 similarly named files (with the same '_'-delimited prefix in their names), and the duplicate keywords produced from their names are now correctly propagated to their parent directory, which normally wouldn't get these keywords on its own (directories don't really get any keywords themselves other than their name and mime type)

Christian Grothoff

2011-12-30 21:42

manager   ~0005219

Last edited: 2011-12-30 21:43

Propagation is all about reducing the number of keywords. Metadata should obviously not be repetitive (as in, it does not make sense to take the words of the title of a piece and also add them as individual EXTRACTOR_KEYWORDS to the metadata or turn them into the subject); however, there is no problem in repeating the author/artist/album-title/year/etc. for each track of an album or the dimensions/gps-coordinates/photographer for each image in a directory, even if they are all the same.

However, publishing 10,000 images of 800x600 resolution each under keywords 800, 600, 800x600, image, jpeg and image/jpeg would be horrific (as each keyword would cost us close to 64k (metadata includes thumbnail, so the KBlock can be close to 64k in this case!)) and thus we might end up with 640k extra space (and ultimately bandwidth) per image!

I short: I totally agree with what you wrote before.

Christian Grothoff

2011-12-30 23:22

manager   ~0005220

Both patches do not cleanly apply. I fixed the conflicts for 0003, but maybe I should find other patches to apply first... Where are those?

LRN

2011-12-30 23:44

developer   ~0005222

In my working copy i have patches from 0002049 and 0002045 before this one.

Christian Grothoff

2011-12-31 00:53

manager   ~0005226

Fixed in SVN 18862.

Issue History

Date Modified Username Field Change
2011-12-28 21:17 LRN New Issue
2011-12-29 19:12 LRN Note Added: 0005215
2011-12-30 00:07 LRN Note Added: 0005216
2011-12-30 01:19 LRN File Added: 0003-Give-all-directories-embedded-names.patch
2011-12-30 01:19 LRN File Added: 0004-Count-and-propagate-keywords-instead-of-metadata.patch
2011-12-30 01:22 LRN Note Added: 0005217
2011-12-30 01:22 LRN Summary Keywords are not forwarded to parent directories => [patch] Keywords are not forwarded to parent directories
2011-12-30 21:42 Christian Grothoff Note Added: 0005219
2011-12-30 21:43 Christian Grothoff Note Edited: 0005219
2011-12-30 23:22 Christian Grothoff Note Added: 0005220
2011-12-30 23:44 LRN Note Added: 0005222
2011-12-31 00:53 Christian Grothoff Note Added: 0005226
2011-12-31 00:53 Christian Grothoff Status new => resolved
2011-12-31 00:53 Christian Grothoff Fixed in Version => 0.9.2
2011-12-31 00:53 Christian Grothoff Resolution open => fixed
2011-12-31 00:53 Christian Grothoff Assigned To => Christian Grothoff
2011-12-31 00:53 Christian Grothoff Target Version => 0.9.2
2012-02-28 11:06 Christian Grothoff Status resolved => closed