hashtable.h

Go to the documentation of this file.
00001 /*  
00002  *      HashTable.h - HashTable class for MAXScript
00003  *
00004  *          Copyright (c) John Wainwright 1996
00005  *
00006  */
00007 
00008 #pragma once
00009 
00010 #include "..\kernel\value.h"
00011 
00012 struct binding 
00013 {
00014     void*   key;
00015     void*   value;
00016 };
00017 
00018 struct secondary                        /* secondary extent struct          */
00019 {
00020     UINT    size;                     /* size of secondary extent   */  // SR NOTE64: was size_t
00021     binding*    bindings;           /* table of bindings                */
00022 };
00023     
00024 #define KEY_IS_OBJECT   0x0001      /* init flags that indicate whether keys & values are full MXS collectable objects */
00025 #define VALUE_IS_OBJECT 0x0002
00026 
00027 ScripterExport int  default_eq_fn(const void* key1, const void* key2);  /* default comparator & hash fns */
00028 ScripterExport DWORD_PTR default_hash_fn(const void* key);
00029 
00030 class HashTabMapper;
00031 
00032 visible_class_debug_ok (HashTable)
00033 
00034 class HashTable : public Value
00035 {
00036 public:
00037    // SR NOTE64: hash functions returned "INT_PTR" (and previously I suppose they
00038    // used to return 'int'; in Win64, the hash values can get pretty huge, and negative,
00039    // and then hash_value % size will give a negative value -- not good.  I'd change it
00040    // to a DWORD, but then the default hash function, which just returns the pointer
00041    // casted to an INT_PTR, would have to do more computations and this might slow
00042    // things down too much.  So I'll just change it to an unsigned value instead and
00043    // introduce a typedef for it.
00044    typedef DWORD_PTR (*hash_fn_type)(const void*);
00045    typedef int       (*eq_fn_type)(const void*, const void*);
00046 
00047 private:
00048     secondary   **table;            /* primary extent: tbl of second's  */
00049     UINT        size;               /* table size                       */  // SR NOTE64: Was size_t
00050     int         n_entries;          /* no. entries in primary extent    */
00051     eq_fn_type  eq_fn;            /* key equivalence function       */
00052     hash_fn_type hash_fn;         /* key hgashing function          */
00053     int         cursor;             /* cursors used for sequencing...   */
00054     int         secondCursor;           
00055     short       flags;
00056     HashTable*  inner;              /* links to next & prev tables when */
00057     HashTable*  outer;              /* used as a lexical scope table    */
00058     int         level;              // scope nesting level
00059 
00060 public:
00061     ScripterExport HashTable(UINT primary_size, eq_fn_type key_eq_fn, hash_fn_type key_hash_fn, int flags);
00062                 HashTable() { init(17, default_eq_fn, default_hash_fn, KEY_IS_OBJECT + VALUE_IS_OBJECT); }
00063                 HashTable(UINT primary_size) { init(primary_size, default_eq_fn, default_hash_fn, KEY_IS_OBJECT + VALUE_IS_OBJECT); }
00064     ScripterExport ~HashTable();
00065     ScripterExport void     init(UINT primary_size, eq_fn_type key_eq_fn, hash_fn_type key_hash_fn, int flags);
00066 #   define      is_hashtable(v) ((DbgVerify(!is_sourcepositionwrapper(v)), (v))->tag == class_tag(HashTable))
00067 
00068     ScripterExport static CRITICAL_SECTION hash_update; // for syncing allocation hashtable updates
00069 
00070     static void setup();
00071 
00072                 classof_methods (HashTable, Value);
00073     void        collect() { delete this;}
00074     ScripterExport void     gc_trace();
00075 
00076     ScripterExport Value*   get(const void* key);
00077     ScripterExport Value*   put(const void* key, const void* val);
00078     ScripterExport Value*   put_new(const void* key, const void* val);
00079     ScripterExport Value*   find_key(const void *val);
00080     ScripterExport Value*   set(const void* key, const void* val);
00081     ScripterExport void     remove(const void* key);
00082     ScripterExport void     map_keys_and_vals(void (*fn)(const void* key, const void* val, void* arg), void* arg);
00083     ScripterExport void     map_keys_and_vals(HashTabMapper* mapper);
00084     ScripterExport int      num_entries() { return n_entries; }
00085 
00086 
00087     HashTable*  enter_scope();
00088     HashTable*  leave_scope();
00089     HashTable*  next_scope();
00090     int         scope_level() { return level; }
00091 };
00092 
00093 class HashTabMapper 
00094 {
00095 public:
00096     virtual void map(const void* key, const void* val)=0;
00097 };
00098 
00099 #define SECONDARY_BUCKET    5
00100