Add rule caching to improve performance
codetaylor opened this issue ยท 2 comments
When a rule is successfully matched, place it into Map<IBlockState, List<Rule>>
. For each block harvest event, check this map first before iterating the rule set. When rules are reloaded, clear the map.
This rule caching strategy is broken. Let me explain why.
Let's say you have two rules A and B listed in a rule file in the following order:
- Rule A says match stone blocks mined with a stone pickaxe
- Rule B says match stone blocks mined with any pickaxe
When a stone block is mined with an iron pickaxe, Rule A is not matched and Rule B is matched and placed in the cache. Next, when a stone block is mined with a stone pickaxe, the cache is tested first, and Rule B is incorrectly matched first, disregarding the explicit sequence defined by the user. When a stone block is mined with a stone pickaxe, Rule A should match before Rule B and, if Rule B is already cached from a previous match, Rule B will be selected over Rule A.
A better rule caching strategy is as follows:
- Check if the map has the
IBlockState
key - If the map has the key,
- retrieve the rule list,
- and test rules in iteration order
- If not,
- iterate all rules
- place any rule that matches block only in the cache list in the same order they are defined
- if no rules match block only, place empty list in the cache
- re-enter the method
- Return the matched rule or null