Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

idep_nimap.cxx

Go to the documentation of this file.
00001 // idep_nimap.c
00002 #include "idep_nameindexmap.h"
00003 #include "idep_namearray.h"
00004 
00005 #include <string.h>     // strcmp() 
00006 #include <memory.h>     // memcpy() memset()
00007 #include <iostream> 
00008 #include <cassert> 
00009 
00010                 // -*-*-*- static functions -*-*-*-
00011 
00012 enum { DEFAULT_TABLE_SIZE = 521 };
00013 enum { BAD_INDEX = -1 };
00014 
00015 static unsigned hash(register const char* name) // Note: returns unsigned!
00016 {
00017     register unsigned sum = 1000003; // 1,000,003 is the 78,498th prime number
00018     while (*name) {
00019         sum *= *name++; // integer multiplication is a subroutine on a SPARC
00020     }
00021     return sum; // unsigned ensures positive value for use with (%) operator.  
00022 }
00023 
00024                 // -*-*-*- idep_NameIndexMapLink -*-*-*-
00025 
00026 struct idep_NameIndexMapLink {
00027     const char *d_name_p;                       // name
00028     int d_index;                                // index of name
00029     idep_NameIndexMapLink *d_next_p;            // pointer to next link
00030 
00031     idep_NameIndexMapLink(const char *name, int index, 
00032                           idep_NameIndexMapLink *d_next_p);
00033 };
00034 
00035 idep_NameIndexMapLink::idep_NameIndexMapLink(const char *name, int index, 
00036                                                 idep_NameIndexMapLink *next)
00037 : d_name_p(name)
00038 , d_index(index)
00039 , d_next_p(next)
00040 {
00041 }
00042 
00043 static const idep_NameIndexMapLink *find(const idep_NameIndexMapLink *p, 
00044                                                             const char *name)
00045 {
00046     while (p && 0 != strcmp(p->d_name_p, name)) {
00047         p = p->d_next_p;
00048     }
00049     return p;
00050 }
00051 
00052                 // -*-*-*- idep_NameIndexMap_i -*-*-*-
00053 
00054 struct idep_NameIndexMap_i { 
00055     idep_NameArray d_array;                     // array of names
00056     idep_NameIndexMapLink **d_table_p;          // hash table of names
00057     int d_tableSize;                            // size of hash table
00058 
00059     idep_NameIndexMap_i(int size); 
00060         // create a map representation assuming the specified (max) size
00061 
00062     ~idep_NameIndexMap_i(); 
00063 
00064     idep_NameIndexMapLink *& findSlot(const char *name); 
00065         // find the appropriate slot for this name
00066 
00067     int insert(idep_NameIndexMapLink *& slot, const char *name);
00068         // insert name into specified slot
00069 };
00070 
00071 idep_NameIndexMap_i::idep_NameIndexMap_i(int size)
00072 : d_array(size)
00073 , d_tableSize(size > 0 ? size : DEFAULT_TABLE_SIZE)
00074 { 
00075     d_table_p = new idep_NameIndexMapLink *[d_tableSize];
00076     assert(d_table_p);
00077     memset(d_table_p, 0, d_tableSize * sizeof *d_table_p);
00078 }
00079 
00080 idep_NameIndexMap_i::~idep_NameIndexMap_i()
00081 { 
00082     for (int i = 0; i < d_tableSize; ++i) {
00083         idep_NameIndexMapLink *p = d_table_p[i];
00084         while (p) {
00085         idep_NameIndexMapLink *q = p;
00086             p = p->d_next_p;
00087             delete q;
00088         }
00089     }
00090     delete [] d_table_p;
00091 }
00092 
00093 idep_NameIndexMapLink *& idep_NameIndexMap_i::findSlot(const char *name)
00094 {
00095     int index = hash(name) % d_tableSize;
00096     assert(index >= 0 && index < d_tableSize);
00097     return d_table_p[index];
00098 }
00099 
00100 int idep_NameIndexMap_i::insert(idep_NameIndexMapLink *& slot, const char *nm)
00101 {
00102     int index = d_array.append(nm); // index is into a managed string array
00103     slot = new idep_NameIndexMapLink(d_array[index], index, slot);
00104     return index;
00105 }
00106 
00107                 // -*-*-*- idep_NameIndexMap -*-*-*-
00108 
00109 idep_NameIndexMap::idep_NameIndexMap(int maxEntriesHint)
00110 : d_this(new idep_NameIndexMap_i(maxEntriesHint))
00111 {
00112 } 
00113 
00114 idep_NameIndexMap::~idep_NameIndexMap()
00115 {
00116     delete d_this;
00117 }                                     
00118 
00119 int idep_NameIndexMap::add(const char* name)
00120 {
00121     idep_NameIndexMapLink *& slot = d_this->findSlot(name);
00122     return find(slot, name) ? BAD_INDEX : d_this->insert(slot, name);
00123 }
00124 
00125 int idep_NameIndexMap::entry(const char* name)
00126 {
00127     idep_NameIndexMapLink *& slot = d_this->findSlot(name);
00128     const idep_NameIndexMapLink *link = find(slot, name);
00129     return link ? link->d_index : d_this->insert(slot, name);
00130 }
00131 
00132 const char *idep_NameIndexMap::operator[](int i) const
00133 {
00134     return d_this->d_array[i];
00135 }
00136 
00137 int idep_NameIndexMap::length() const
00138 {
00139     return d_this->d_array.length();
00140 }
00141 
00142 int idep_NameIndexMap::lookup(const char *name) const
00143 {
00144     idep_NameIndexMapLink *& slot = d_this->findSlot(name);
00145     const idep_NameIndexMapLink *link = find(slot, name);
00146     return link ? link->d_index : BAD_INDEX;
00147 }
00148 
00149 std::ostream& operator<<(std::ostream& out, const idep_NameIndexMap& map)
00150 {
00151     int fieldWidth = 10;
00152     int maxIndex = map.length() - 1;
00153     assert (sizeof (long int) >= 4);
00154     long int x = 1000 * 1000 * 1000;    // requires 4-byte integer.
00155     while (fieldWidth > 1 && 0 == maxIndex / x) {
00156         --fieldWidth;
00157         x /= 10;
00158     }
00159  
00160     for (int i = 0; i < map.length(); ++i) {
00161         out.width(fieldWidth);
00162         out << i << ". " << map[i] << std::endl;
00163     }
00164  
00165     return out;
00166 }
00167 

Generated on Mon Feb 15 11:06:48 2010 for loon by  doxygen 1.3.9.1