import gdb-1999-12-06 snapshot
[deliverable/binutils-gdb.git] / gdb / bcache.h
index ec383244a478988a7516fa8dd9eb56d8304ca4d8..1350bea66a029bafa0fe073a5c814c91d673ef85 100644 (file)
@@ -1,6 +1,7 @@
 /* Include file cached obstack implementation.
-   Written by Fred Fish (fnf@cygnus.com)
-   Copyright 1995 Free Software Foundation, Inc.
+   Written by Fred Fish <fnf@cygnus.com>
+   Rewritten by Jim Blandy <jimb@cygnus.com>
+   Copyright 1999 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #ifndef BCACHE_H
 #define BCACHE_H 1
 
-#define BCACHE_HASHLENGTH      12      /* Number of bits in hash value */
-#define BCACHE_HASHSIZE        (1 << BCACHE_HASHLENGTH)
-#define BCACHE_MAXLENGTH       128
-
-/* Note that the user data is stored in data[].  Since it can be any type,
-   it needs to have the same alignment  as the most strict alignment of 
-   any type on the host machine.  So do it the same way obstack does. */
-
-struct hashlink
-  {
-    struct hashlink *next;
-    union
-      {
-       char data[1];
-       double dummy;
-      }
-    d;
-  };
-
-/* BCACHE_DATA is used to get the address of the cached data. */
-
-#define BCACHE_DATA(p) ((p)->d.data)
-
-/* BCACHE_DATA_ALIGNMENT is used to get the offset of the start of
-   cached data within the hashlink struct.  This value, plus the
-   size of the cached data, is the amount of space to allocate for
-   a hashlink struct to hold the next pointer and the data. */
-
-#define BCACHE_DATA_ALIGNMENT \
-       (((char *) BCACHE_DATA((struct hashlink*) 0) - (char *) 0))
-
-struct bcache
+/* A bcache is a data structure for factoring out duplication in
+   read-only structures.  You give the bcache some string of bytes S.
+   If the bcache already contains a copy of S, it hands you back a
+   pointer to its copy.  Otherwise, it makes a fresh copy of S, and
+   hands you back a pointer to that.  In either case, you can throw
+   away your copy of S, and use the bcache's.
+
+   The "strings" in question are arbitrary strings of bytes --- they
+   can contain zero bytes.  You pass in the length explicitly when you
+   call the bcache function.
+
+   This means that you can put ordinary C objects in a bcache.
+   However, if you do this, remember that structs can contain `holes'
+   between members, added for alignment.  These bytes usually contain
+   garbage.  If you try to bcache two objects which are identical from
+   your code's point of view, but have different garbage values in the
+   structure's holes, then the bcache will treat them as separate
+   strings, and you won't get the nice elimination of duplicates you
+   were hoping for.  So, remember to memset your structures full of
+   zeros before bcaching them!
+
+   You shouldn't modify the strings you get from a bcache, because:
+
+   - You don't necessarily know who you're sharing space with.  If I
+     stick eight bytes of text in a bcache, and then stick an
+     eight-byte structure in the same bcache, there's no guarantee
+     those two objects don't actually comprise the same sequence of
+     bytes.  If they happen to, the bcache will use a single byte
+     string for both of them.  Then, modifying the structure will
+     change the string.  In bizarre ways.
+
+   - Even if you know for some other reason that all that's okay,
+     there's another problem.  A bcache stores all its strings in a
+     hash table.  If you modify a string's contents, you will probably
+     change its hash value.  This means that the modified string is
+     now in the wrong place in the hash table, and future bcache
+     probes will never find it.  So by mutating a string, you give up
+     any chance of sharing its space with future duplicates.  */
+
+
+/* The type used to hold a single bcache string.  The user data is
+   stored in d.data.  Since it can be any type, it needs to have the
+   same alignment as the most strict alignment of any type on the host
+   machine.  I don't know of any really correct way to do this in
+   stock ANSI C, so just do it the same way obstack.h does.
+
+   It would be nicer to have this stuff hidden away in bcache.c, but
+   struct objstack contains a struct bcache directly --- not a pointer
+   to one --- and then the memory-mapped stuff makes this a real pain.
+   We don't strictly need to expose struct bstring, but it's better to
+   have it all in one place.  */
+
+struct bstring {
+  struct bstring *next;
+  size_t length;
+
+  union
   {
-    struct obstack cache;
-    struct hashlink **indextable[BCACHE_MAXLENGTH];
-    int cache_hits;
-    int cache_misses;
-    int cache_bytes;
-    int cache_savings;
-    int bcache_overflows;
-  };
-
-extern void *
-  bcache PARAMS ((void *bytes, int count, struct bcache * bcachep));
-
-extern void
-print_bcache_statistics PARAMS ((struct bcache *, char *));
+    char data[1];
+    double dummy;
+  }
+  d;
+};
+
+
+/* The structure for a bcache itself.
+   To initialize a bcache, just fill it with zeros.  */
+struct bcache {
+  /* All the bstrings are allocated here.  */
+  struct obstack cache;
+
+  /* How many hash buckets we're using.  */
+  int num_buckets;
+  
+  /* Hash buckets.  This table is allocated using malloc, so when we
+     grow the table we can return the old table to the system.  */
+  struct bstring **bucket;
+
+  /* Statistics.  */
+  long unique_count;   /* number of unique strings */
+  long total_count;    /* total number of strings cached, including dups */
+  long unique_size;    /* size of unique strings, in bytes */
+  long total_size;      /* total number of bytes cached, including dups */
+  long structure_size; /* total size of bcache, including infrastructure */
+};
+
+
+/* Find a copy of the LENGTH bytes at ADDR in BCACHE.  If BCACHE has
+   never seen those bytes before, add a copy of them to BCACHE.  In
+   either case, return a pointer to BCACHE's copy of that string.  */
+extern void *bcache (void *addr, int length, struct bcache *bcache);
+
+/* Free all the storage that BCACHE refers to.  The result is a valid,
+   but empty, bcache.  This does not free BCACHE itself, since that
+   might be part of some larger object.  */
+extern void free_bcache (struct bcache *bcache);
+
+/* Print statistics on BCACHE's memory usage and efficacity at
+   eliminating duplication.  TYPE should be a string describing the
+   kind of data BCACHE holds.  Statistics are printed using
+   `printf_filtered' and its ilk.  */
+extern void print_bcache_statistics (struct bcache *bcache, char *type);
 
 #endif /* BCACHE_H */
This page took 0.024878 seconds and 4 git commands to generate.