0

I have conversion tables I need to contain in memory for fast access. Until now I used a simple Hashtable were the Key was the internal code, and the Value was an object holding the external code and other meta-data.

Now we need to have a reverse look-up, meaning to get the internal code based on the external code. I could only come up with the following options:

  1. Have another container for this look-up, Hashtable containing only the internal code as Value to prevent more redundancy.
  2. Use the same container I use now, and store those objects again now using the the external code as the Key (have a prefix to prevent collisions).
  3. Don't pull data using Keys, but iterate through the Values contained under the same container to find the requested object ( O(n), same memory usage ).

The container is being lazy-loaded, so options 1&2 usually won't perform under the worst-case scenario.

Thoughts anyone? Please tell me there's some efficient container I could use for that, which I missed!

* EDIT *

Being a GC'd framework, and accepting the fact I'd have to have two conversion arrays (Dictionaries), would the following lines of code actually mean I stored only one object on memory, and then two pointers for it, under two different hashed-cells?

Dictionary<K1,V> forward;
Dictionary<K2,V> reverse;
//...    
void Add(V myObject)
{
    // myObject being the BLL object
    forward.Add(myObject.InternalCode, myObject);
    reverse.Add(myObject.ExternalCode, myObject);
}

Itamar.

synhershko
  • 4,472
  • 1
  • 30
  • 37
  • Why can't you lazy-load the reverse-lookup hash? – Ken Nov 30 '09 at 18:39
  • I am, even on an item basis (and not the whole list at once). This is my starting point - am trying to find the best option in terms of both performance and memory usage. – synhershko Nov 30 '09 at 18:54

2 Answers2

1

Build a custom collection class that has two internal hashtables (Dictionarys), one in each direction.

  public BiHashTable<K, V>
  {
     private Dictionary<K, V> vals = new Dictionary<K, V>();
     private Dictionary<V, K> keys = new Dictionary<V, K>();
     public void Add(K key, V val)
     {
        vals.Add(key, val);
        keys.Add(val, key);
     }
     public K this[v val] { get { return keys[val]; } }
     public V this[K key] { get { return vals[key]; } }
     // etc... 
  }

NOTE: This will be problematic is both K and V are the same type, you need a different formulation then...

Charles Bretana
  • 143,358
  • 22
  • 150
  • 216
  • Only problem with this, as explained in the question, is that V is not of a native type. I wouldn't want to use it as a key... Also, this is actually the implementation of the worst case scenario - the 2 Hashtables stored twice as a whole - exactly what I want to avoid... – synhershko Nov 30 '09 at 18:57
  • @synhershko, Why do you want to avoid this? Remember, all you are storing twice is a reference variable, a pointer. You are not storing the objects twice. And I see no way around storing something twice. If you don't, you're stuck with iterating through the single collection to find the key for a given value. And you are not storing, or "actually using" the object as a key, remember, you are actually using the hash created from the object as the key. – Charles Bretana Nov 30 '09 at 21:41
  • Yes, I figured as such - see my edit. I was asking to see if there's a way around holding two Hashtables -- apparently the answer is no. With regards to computing a hash of a non-native type, I know its a computed hash of it which is being used as a key. However, my gut tells me it won't be ideal when the object grows larger (e.g. has another array/hashtable in it) - just computing the hash would be an expensive task, at least more expensive than you'd want for live systems. – synhershko Dec 01 '09 at 11:50
  • That's why, for custom classes, you are advised to override the GetHashCode() method, to make sure that the process is efficient. Write your own that is fast, efficient. and unique. – Charles Bretana Dec 01 '09 at 14:20
0

I rather use two instances of Dictionary<TKey, TValue>

It favors code readability

Are you sure this dictionary is a performance bottleneck?

Jader Dias
  • 88,211
  • 155
  • 421
  • 625