I have some configuration data that I’d like to model in code as so:
Key1, Key2, Key3, Value null, null, null, 1 1, null, null, 2 9, null, null, 21 1, null, 3, 3 null, 2, 3, 4 1, 2, 3, 5
With this configuration set, I then need to do lookups on bazillion (give or take) {Key1, Key2, Key3} tuples to get the ‘effective’ value. The effective value to use is based on a Key/Priority sum whereby in this example:
Key1 - Priority 10 Key2 - Priority 7 Key3 - Priority 5
So a specifc query which has a config entry on Key1=null, Key2=match, and Key3=match beats out one that has Key1=match, Key2=null, and Key3=null since Key2+Key3 priority > Key1 priority… That make sense?!
given a key of {1, 2, 3} the value should be 5. given a key of {3, 2, 3} the value should be 4. given a key of {8, 10, 11} the value should be 1. given a key of {1, 10, 11} the value should be 2. given a key of {9, 2, 3} the value should be 4. given a key of {8, 2, 3} the value should be 4. given a key of {9, 3, 3} the value should be 21.
Is there an easy way to model this data structure and lookup algorithm that is generic in that the # and types of keys is variable, and the ‘truth table’ (the ordering of the lookups) can be defined dynamically? The types being generics instead of ints would be perfect (floats, doubles, ushorts, etc), and making it easy to expand to n number of keys is important too!
Estimated ‘config’ table size: 1,000 rows, Estimated ‘data’ being looked up: 1e14
That gives an idea about the type of performance that would be expected.
I’m looking for ideas in C# or something that can translate to C# easily.
I’m assuming that there are few rules, and a large number of items that you’re going to check against the rules. In this case, it might be worth the expense of memory and up-front time to pre-compute a structure that would help you find the object faster.
The basic idea for this structure would be a tree such that at depth i, you would follow the ith element of the rule, or the null branch if it’s not found in the dictionary.
To build the tree, I would build it recursively. Start with the root node containing all possible rules in its pool. The process:
As a final optimization check, I would check if all children of a node are leaves, and if they all contain the same rule, then make the node a leaf with that value.
given the following rules:
an example tree:
If you build the tree up in this fashion, starting from the highest value key first, then you can possibly prune out a lot of checks against later keys.
Edit to add code: