Exemplo n.º 1
0
/*****************************************************************************
 * Cache_GetNrEntries
 *****************************************************************************/
inline long 
Cache_GetNrEntries (const Cache* const cache)
{
	if (cache == NULL)
		return -1; // ---------->

#if CACHE_FIXED_SIZE
	return cache->nr_entries;
#else
	return hash_get_n_entries (cache->table);
#endif
}
Exemplo n.º 2
0
void
hash_print_statistics (const Hash_table *table, FILE *stream)
{
  unsigned n_entries = hash_get_n_entries (table);
  unsigned n_buckets = hash_get_n_buckets (table);
  unsigned n_buckets_used = hash_get_n_buckets_used (table);
  unsigned max_bucket_length = hash_get_max_bucket_length (table);

  fprintf (stream, "# entries:         %u\n", n_entries);
  fprintf (stream, "# buckets:         %u\n", n_buckets);
  fprintf (stream, "# buckets used:    %u (%.2f%%)\n", n_buckets_used,
	   (100.0 * n_buckets_used) / n_buckets);
  fprintf (stream, "max bucket length: %u\n", max_bucket_length);
}
Exemplo n.º 3
0
Arquivo: hash.c Projeto: aosm/gnutar
void
hash_print_statistics (const Hash_table *table, FILE *stream)
{
  size_t n_entries = hash_get_n_entries (table);
  size_t n_buckets = hash_get_n_buckets (table);
  size_t n_buckets_used = hash_get_n_buckets_used (table);
  size_t max_bucket_length = hash_get_max_bucket_length (table);

  fprintf (stream, "# entries:         %lu\n", (unsigned long int) n_entries);
  fprintf (stream, "# buckets:         %lu\n", (unsigned long int) n_buckets);
  fprintf (stream, "# buckets used:    %lu (%.2f%%)\n",
	   (unsigned long int) n_buckets_used,
	   (100.0 * n_buckets_used) / n_buckets);
  fprintf (stream, "max bucket length: %lu\n",
	   (unsigned long int) max_bucket_length);
}
Exemplo n.º 4
0
static void
cache_expire_entries (Cache* cache, time_t const now)
{	
	if (cache->max_age > 0 && now > cache->next_clean) {
		int i;
#if CACHE_FIXED_SIZE
		for (i = 0; i < cache->size; i++) {
			Entry* const ce = cache->table + i;
			if (ce->key && now > ce->rip) {
				Log_Printf (LOG_DEBUG, 
					    "CACHE_CLEAN (key='%s')", ce->key);
				if (cache->free_expired_data)
					cache->free_expired_data (ce->key, 
								  ce->data);
				ce->data = NULL;
				talloc_free (ce->key);
				ce->key = NULL;
				cache->nr_entries--;
			}
	
		}
#else
		size_t const n = hash_get_n_entries (cache->table);
		// Pb with "Hash_table" API : it is not allowed to modify 
		// the hash table when walking it. Therefore we have to get 
		// the entries first, then delete the expired ones.
		void* entries [n];
		size_t const nn = hash_get_entries (cache->table, entries, n);
		for (i = 0; i < nn; i++) {
			Entry* ce = (Entry*) entries[i];
			if (now > ce->rip) {
				Log_Printf (LOG_DEBUG, 
					    "CACHE_CLEAN (key='%s')", ce->key);
				ce = hash_delete (cache->table, ce);
				if (ce) {
					if (cache->free_expired_data)
						cache->free_expired_data 
							(ce->key, ce->data);
					ce->data = NULL;
					talloc_free (ce);
				}
			}
		}
#endif
		cache->next_clean = now + CACHE_CLEAN_PERIOD;
	}
}
Exemplo n.º 5
0
/* Return true if file names of some members in the archive were stripped off
   their leading components. We could have used
        return prefix_table[0] || prefix_table[1]
   but the following seems to be safer: */
bool
removed_prefixes_p (void)
{
  return (prefix_table[0] && hash_get_n_entries (prefix_table[0]) != 0)
         || (prefix_table[1] && hash_get_n_entries (prefix_table[1]) != 0);
}
Exemplo n.º 6
0
int
main (int argc, char **argv)
{
  unsigned int i;
  unsigned int k;
  unsigned int table_size[] = {1, 2, 3, 4, 5, 23, 53};
  Hash_table *ht;
  Hash_tuning tuning;

  hash_reset_tuning (&tuning);
  tuning.shrink_threshold = 0.3;
  tuning.shrink_factor = 0.707;
  tuning.growth_threshold = 1.5;
  tuning.growth_factor = 2.0;
  tuning.is_n_buckets = true;

  if (1 < argc)
    {
      unsigned int seed;
      if (get_seed (argv[1], &seed) != 0)
        {
          fprintf (stderr, "invalid seed: %s\n", argv[1]);
          exit (EXIT_FAILURE);
        }

      srand (seed);
    }

  for (i = 0; i < ARRAY_CARDINALITY (table_size); i++)
    {
      size_t sz = table_size[i];
      ht = hash_initialize (sz, NULL, hash_pjw, hash_compare_strings, NULL);
      ASSERT (ht);
      insert_new (ht, "a");
      {
        char *str1 = strdup ("a");
        char *str2;
        ASSERT (str1);
        str2 = hash_insert (ht, str1);
        ASSERT (str1 != str2);
        ASSERT (STREQ (str1, str2));
        free (str1);
      }
      insert_new (ht, "b");
      insert_new (ht, "c");
      i = 0;
      ASSERT (hash_do_for_each (ht, walk, &i) == 3);
      ASSERT (i == 7);
      {
        void *buf[5] = { NULL };
        ASSERT (hash_get_entries (ht, NULL, 0) == 0);
        ASSERT (hash_get_entries (ht, buf, 5) == 3);
        ASSERT (STREQ (buf[0], "a") || STREQ (buf[0], "b") || STREQ (buf[0], "c"));
      }
      ASSERT (hash_delete (ht, "a"));
      ASSERT (hash_delete (ht, "a") == NULL);
      ASSERT (hash_delete (ht, "b"));
      ASSERT (hash_delete (ht, "c"));

      ASSERT (hash_rehash (ht, 47));
      ASSERT (hash_rehash (ht, 467));

      /* Free an empty table. */
      hash_clear (ht);
      hash_free (ht);

      ht = hash_initialize (sz, NULL, hash_pjw, hash_compare_strings, NULL);
      ASSERT (ht);

      insert_new (ht, "z");
      insert_new (ht, "y");
      insert_new (ht, "x");
      insert_new (ht, "w");
      insert_new (ht, "v");
      insert_new (ht, "u");

      hash_clear (ht);
      ASSERT (hash_get_n_entries (ht) == 0);
      hash_free (ht);

      /* Test pointer hashing.  */
      ht = hash_initialize (sz, NULL, NULL, NULL, NULL);
      ASSERT (ht);
      {
        char *str = strdup ("a");
        ASSERT (str);
        insert_new (ht, "a");
        insert_new (ht, str);
        ASSERT (hash_lookup (ht, str) == str);
        free (str);
      }
      hash_free (ht);
    }

  hash_reset_tuning (&tuning);
  tuning.shrink_threshold = 0.3;
  tuning.shrink_factor = 0.707;
  tuning.growth_threshold = 1.5;
  tuning.growth_factor = 2.0;
  tuning.is_n_buckets = true;
  /* Invalid tuning.  */
  ht = hash_initialize (4651, &tuning, hash_pjw, hash_compare_strings,
                        hash_freer);
  ASSERT (!ht);

  /* Alternate tuning.  */
  tuning.growth_threshold = 0.89;

  /* Run with default tuning, then with custom tuning settings.  */
  for (k = 0; k < 2; k++)
    {
      Hash_tuning const *tune = (k == 0 ? NULL : &tuning);
      /* Now, each entry is malloc'd.  */
      ht = hash_initialize (4651, tune, hash_pjw,
                            hash_compare_strings, hash_freer);
      ASSERT (ht);
      for (i = 0; i < 10000; i++)
        {
          unsigned int op = rand () % 10;
          switch (op)
            {
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
              {
                char buf[50];
                char const *p = uinttostr (i, buf);
                char *p_dup = strdup (p);
                ASSERT (p_dup);
                insert_new (ht, p_dup);
              }
              break;

            case 6:
              {
                size_t n = hash_get_n_entries (ht);
                ASSERT (hash_rehash (ht, n + rand () % 20));
              }
              break;

            case 7:
              {
                size_t n = hash_get_n_entries (ht);
                size_t delta = rand () % 20;
                if (delta < n)
                  ASSERT (hash_rehash (ht, n - delta));
              }
              break;

            case 8:
            case 9:
              {
                /* Delete a random entry.  */
                size_t n = hash_get_n_entries (ht);
                if (n)
                  {
                    size_t kk = rand () % n;
                    void const *p;
                    void *v;
                    for (p = hash_get_first (ht); kk;
                         --kk, p = hash_get_next (ht, p))
                      {
                        /* empty */
                      }
                    ASSERT (p);
                    v = hash_delete (ht, p);
                    ASSERT (v);
                    free (v);
                  }
                break;
              }
            }
          ASSERT (hash_table_ok (ht));
        }

      hash_free (ht);
    }

  return 0;
}