Exemplo n.º 1
0
static void
file_builder_add_value (FileBuilder         *fb,
                        GVariant            *value,
                        struct gvdb_pointer *pointer)
{
  GVariant *variant, *normal;
  gpointer data;
  gsize size;

  if (fb->byteswap)
    {
      value = g_variant_byteswap (value);
      variant = g_variant_new_variant (value);
      g_variant_unref (value);
    }
  else
    variant = g_variant_new_variant (value);

  normal = g_variant_get_normal_form (variant);
  g_variant_unref (variant);

  size = g_variant_get_size (normal);
  data = file_builder_allocate (fb, 8, size, pointer);
  g_variant_store (normal, data);
  g_variant_unref (normal);
}
Exemplo n.º 2
0
static void
file_builder_allocate_for_hash (FileBuilder            *fb,
                                gsize                   n_buckets,
                                gsize                   n_items,
                                guint                   bloom_shift,
                                gsize                   n_bloom_words,
                                guint32_le            **bloom_filter,
                                guint32_le            **hash_buckets,
                                struct gvdb_hash_item **hash_items,
                                struct gvdb_pointer    *pointer)
{
  guint32_le bloom_hdr, table_hdr;
  guchar *data;
  gsize size;

  g_assert (n_bloom_words < (1u << 27));

  bloom_hdr = guint32_to_le (bloom_shift << 27 | n_bloom_words);
  table_hdr = guint32_to_le (n_buckets);

  size = sizeof bloom_hdr + sizeof table_hdr +
         n_bloom_words * sizeof (guint32_le) +
         n_buckets     * sizeof (guint32_le) +
         n_items       * sizeof (struct gvdb_hash_item);

  data = file_builder_allocate (fb, 4, size, pointer);

#define chunk(s) (size -= (s), data += (s), data - (s))
  memcpy (chunk (sizeof bloom_hdr), &bloom_hdr, sizeof bloom_hdr);
  memcpy (chunk (sizeof table_hdr), &table_hdr, sizeof table_hdr);
  *bloom_filter = (guint32_le *) chunk (n_bloom_words * sizeof (guint32_le));
  *hash_buckets = (guint32_le *) chunk (n_buckets * sizeof (guint32_le));
  *hash_items = (struct gvdb_hash_item *) chunk (n_items *
                  sizeof (struct gvdb_hash_item));
  g_assert (size == 0);
#undef chunk

  memset (*bloom_filter, 0, n_bloom_words * sizeof (guint32_le));

  /* NOTE - the code to actually fill in the bloom filter here is missing.
   * Patches welcome! 
   *
   * http://en.wikipedia.org/wiki/Bloom_filter
   * http://0pointer.de/blog/projects/bloom.html
   */
}
Exemplo n.º 3
0
static void
file_builder_allocate_for_hash (FileBuilder            *fb,
                                gsize                   n_buckets,
                                gsize                   n_items,
                                guint                   bloom_shift,
                                gsize                   n_bloom_words,
                                guint32_le            **bloom_filter,
                                guint32_le            **hash_buckets,
                                struct gvdb_hash_item **hash_items,
                                struct gvdb_pointer    *pointer)
{
  guint32_le bloom_hdr, table_hdr;
  guchar *data;
  gsize size;

  g_assert (n_bloom_words < (1u << 27));

  bloom_hdr = guint32_to_le (bloom_shift << 27 | n_bloom_words);
  table_hdr = guint32_to_le (n_buckets);

  size = sizeof bloom_hdr + sizeof table_hdr +
         n_bloom_words * sizeof (guint32_le) +
         n_buckets     * sizeof (guint32_le) +
         n_items       * sizeof (struct gvdb_hash_item);

  data = file_builder_allocate (fb, 4, size, pointer);

#define chunk(s) (size -= (s), data += (s), data - (s))
  memcpy (chunk (sizeof bloom_hdr), &bloom_hdr, sizeof bloom_hdr);
  memcpy (chunk (sizeof table_hdr), &table_hdr, sizeof table_hdr);
  *bloom_filter = (guint32_le *) chunk (n_bloom_words * sizeof (guint32_le));
  *hash_buckets = (guint32_le *) chunk (n_buckets * sizeof (guint32_le));
  *hash_items = (struct gvdb_hash_item *) chunk (n_items *
                  sizeof (struct gvdb_hash_item));
  g_assert (size == 0);
#undef chunk

  memset (*bloom_filter, 0, n_bloom_words * sizeof (guint32_le));
}
Exemplo n.º 4
0
static void
file_builder_add_hash (FileBuilder         *fb,
                       GHashTable          *table,
                       struct gvdb_pointer *pointer)
{
  guint32_le *buckets, *bloom_filter;
  struct gvdb_hash_item *items;
  HashTable *mytable;
  GvdbItem *item;
  guint32 index;
  gint bucket;

  mytable = hash_table_new (g_hash_table_size (table));
  g_hash_table_foreach (table, hash_table_insert, mytable);
  index = 0;

  for (bucket = 0; bucket < mytable->n_buckets; bucket++)
    for (item = mytable->buckets[bucket]; item; item = item->next)
      item->assigned_index = guint32_to_le (index++);

  file_builder_allocate_for_hash (fb, mytable->n_buckets, index, 5, 0,
                                  &bloom_filter, &buckets, &items, pointer);

  index = 0;
  for (bucket = 0; bucket < mytable->n_buckets; bucket++)
    {
      buckets[bucket] = guint32_to_le (index);

      for (item = mytable->buckets[bucket]; item; item = item->next)
        {
          struct gvdb_hash_item *entry = items++;
          const gchar *basename;

          g_assert (index == guint32_from_le (item->assigned_index));
          entry->hash_value = guint32_to_le (item->hash_value);
          entry->parent = item_to_index (item->parent);
          entry->unused = 0;

          if (item->parent != NULL)
            basename = item->key + strlen (item->parent->key);
          else
            basename = item->key;

          file_builder_add_string (fb, basename,
                                   &entry->key_start,
                                   &entry->key_size);

          if (item->value != NULL)
            {
              g_assert (item->child == NULL && item->table == NULL);

              file_builder_add_value (fb, item->value, &entry->value.pointer);
              entry->type = 'v';
            }

          if (item->child != NULL)
            {
              guint32 children = 0, i = 0;
              guint32_le *offsets;
              GvdbItem *child;

              g_assert (item->table == NULL);

              for (child = item->child; child; child = child->sibling)
                children++;

              offsets = file_builder_allocate (fb, 4, 4 * children,
                                               &entry->value.pointer);
              entry->type = 'L';

              for (child = item->child; child; child = child->sibling)
                offsets[i++] = child->assigned_index;

              g_assert (children == i);
            }

          if (item->table != NULL)
            {
              entry->type = 'H';
              file_builder_add_hash (fb, item->table, &entry->value.pointer);
            }

          index++;
        }
    }

  hash_table_free (mytable);
}