home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / comp / lang / cplus / 13515 < prev    next >
Encoding:
Text File  |  1992-09-10  |  4.0 KB  |  128 lines

  1. Newsgroups: comp.lang.c++
  2. Path: sparky!uunet!sun-barr!ames!xn.ll.mit.edu!xn!haydens
  3. From: haydens@bullwinkle.juliet.ll.mit.edu (Hayden Schultz x3685 g42)
  4. Subject: Re: zero-length datatype
  5. In-Reply-To: tmb@arolla.idiap.ch's message of 10 Sep 92 16:02:06 GMT
  6. Message-ID: <HAYDENS.92Sep10103208@bullwinkle.juliet.ll.mit.edu>
  7. Lines: 111
  8. Sender: usenet@xn.ll.mit.edu
  9. Reply-To: haydens@juliet.ll.mit.edu
  10. Organization: M.I.T. Lincoln Lab - Group 42
  11. References: <TMB.92Sep8141523@arolla.idiap.ch> <4947@holden.lulea.trab.se>
  12.     <HAYDENS.92Sep9215705@bullwinkle.juliet.ll.mit.edu>
  13.     <TMB.92Sep10120206@arolla.idiap.ch>
  14. Distribution: comp
  15. Date: 10 Sep 92 10:32:08
  16.  
  17.  
  18. In article <TMB.92Sep10120206@arolla.idiap.ch> tmb@arolla.idiap.ch (Thomas M. Breuel) writes:
  19.  
  20.    In article <HAYDENS.92Sep9215705@bullwinkle.juliet.ll.mit.edu> haydens@bullwinkle.juliet.ll.mit.edu (Hayden Schultz x3685 g42) writes:
  21.  
  22.      : Under the current rules,
  23.      : 
  24.      :       struct nothing {};
  25.      :       HashTable<int,nothing> table(1000000);
  26.      : 
  27.      : table takes up 8Mbytes (on most machines). If you could write
  28.      : 
  29.      :       HashTable<int,void> table(1000000);
  30.      : 
  31.      : table takes up 4Mbytes.
  32.  
  33.      On common implementations, 1 million such objects take up
  34.      24 MB (since a-e take up 4 bytes each), whereas Thomas's
  35.      proposed 'void' type means only 4 MB would be needed.
  36.      Quite a difference!
  37.  
  38.  
  39.       You should be able use abstraction to avoid this problem:
  40.  
  41.       template<class KeyNode>
  42.       class HashTable {
  43.     public:
  44.       KeyNode    lookup(const KeyNode &) const;
  45.       void    add(const KeyNode &);
  46.       int        in_table(KeyNode &);
  47.       };
  48.  
  49.       This class assumes that KeyNode::Value() and KeyNode::Key() functions
  50.       are used to access the key and value.  When you want to only use the
  51.       Value(), then you can write your KeyNode class: [...]
  52.  
  53.    You can do this. However, there are two problems with it:
  54.  
  55.     (1) It's counterintuitive. HashTable depends on two types, the
  56.     Key type and the Value type, and this should be made explicit
  57.     in the definition. Also, I don't want to have to name
  58.     and define a structure just to make a simple "HashTable<int,int>".
  59.  
  60.     (2) It may waste lots of memory because KeyNodes can not be packed
  61.     as tightly as Keys and Values. Consider the following two
  62.     implementation fragments:
  63.  
  64.        template <class Key,class Value>
  65.        struct HashTable1 {
  66.            Array<Key> keys;
  67.            Array<Value> values;
  68.            BitArray used;
  69.            ...
  70.        };
  71.  
  72.        template <class KeyNode>
  73.        struct HashTable2 {
  74.            Array<KeyNode> kvpairs;
  75.            BitArray used;
  76.            ...
  77.        };
  78.  
  79.        struct MyKeyNode { int key; char value; };
  80.  
  81.     Now, HashTable1<int,char> requires 5 bytes plus 1 bit per
  82.     slot, whereas HashTable2<MyKeyNode> requires 8 bytes plus
  83.     1 bit per slot.
  84.  
  85.                    Thomas.
  86.  
  87. I'm still not convinced that you can't use existing language features
  88. to solve (or maybe just avoid) this problem. If a legitimate subset of
  89. the hash table problem is hash tables with just keys, then this sounds
  90. like a basis for a class heirarchy. Again please forgive and stupid
  91. template errors I make, since I can't test this code myself.
  92.  
  93. Something like:
  94.  
  95. template <class Key>
  96. class KeyHash {
  97.   protected:
  98.     Array<Key>    keys;
  99.     BitArray    used;
  100.   public:
  101.     void    Add(Key &);
  102.     int        InTable(Key &);
  103. };
  104.  
  105. template <class Key, class Value>
  106. class HashTable : public KeyHash<Key> {
  107.   protected:
  108.     Array<Value>    values;
  109.   public:
  110.     Value        Lookup(Key &);
  111. };
  112.  
  113. I think that this meets your intuitive criterion. Whenever you don't
  114. care what the values are, you use the KeyHash class. You don't have to
  115. make a special class to make a simple HashTable<int,int>. The Key and
  116. Value types are as explicit as your original example. You don't even
  117. have to modify any existing code which uses the HashTable class, since
  118. the public interface hasn't changed.
  119.  
  120. And best of all, you don't have to modify the language to get your
  121. memory efficiency. You also know exactly what will happen if you
  122. inadvertently try to use the value returned by HashTable::Lookup() for
  123. a KeyHash object-- you'll get a compiler error.
  124.  
  125.     Hayden Schultz
  126.     MIT Lincoln Lab
  127.     haydens@juliet.ll.mit.edu
  128.