@@ -13,7 +13,9 @@ use strum::EnumCount;
1313use crate :: block:: Block ;
1414use crate :: context:: ScopeContext ;
1515use crate :: everything:: Everything ;
16- use crate :: helpers:: { dup_error, exact_dup_advice, exact_dup_error, TigerHashMap , TigerHashSet } ;
16+ use crate :: helpers:: {
17+ dup_error, exact_dup_advice, exact_dup_error, DupReporter , TigerHashMap , TigerHashSet ,
18+ } ;
1719use crate :: item:: Item ;
1820use crate :: lowercase:: Lowercase ;
1921use crate :: token:: Token ;
@@ -50,17 +52,7 @@ impl Default for Db {
5052
5153impl Db {
5254 pub fn add ( & mut self , item : Item , key : Token , block : Block , kind : Box < dyn DbKind > ) {
53- if let Some ( other) = self . database [ item as usize ] . get ( key. as_str ( ) ) {
54- if other. key . loc . ptr . kind >= key. loc . ptr . kind {
55- if other. block . equivalent ( & block) {
56- exact_dup_error ( & key, & other. key , & item. to_string ( ) ) ;
57- } else {
58- dup_error ( & key, & other. key , & item. to_string ( ) ) ;
59- }
60- }
61- }
62- self . items_lc [ item as usize ] . insert ( Lowercase :: new ( key. as_str ( ) ) , key. as_str ( ) ) ;
63- self . database [ item as usize ] . insert ( key. as_str ( ) , DbEntry { key, block, kind } ) ;
55+ self . add_with_reporter ( item, key, block, kind, exact_dup_error) ;
6456 }
6557
6658 #[ allow( dead_code) ]
@@ -71,17 +63,49 @@ impl Db {
7163 block : Block ,
7264 kind : Box < dyn DbKind > ,
7365 ) {
74- if let Some ( other) = self . database [ item as usize ] . get ( key. as_str ( ) ) {
75- if other. key . loc . ptr . kind >= key. loc . ptr . kind {
76- if other. block . equivalent ( & block) {
77- exact_dup_advice ( & key, & other. key , & item. to_string ( ) ) ;
66+ self . add_with_reporter ( item, key, block, kind, exact_dup_advice) ;
67+ }
68+
69+ fn add_with_reporter (
70+ & mut self ,
71+ item : Item ,
72+ key : Token ,
73+ block : Block ,
74+ kind : Box < dyn DbKind > ,
75+ exact_dup_reporter : DupReporter ,
76+ ) {
77+ use std:: collections:: hash_map:: Entry ;
78+
79+ match self . database [ item as usize ] . entry ( key. as_str ( ) ) {
80+ Entry :: Occupied ( mut occupied_entry) => {
81+ let new = DbEntry { key, block, kind } ;
82+ let existing = occupied_entry. get ( ) ;
83+
84+ let ( keep, overwriten) = if new. key . loc . ptr > existing. key . loc . ptr {
85+ ( & new, existing)
7886 } else {
79- dup_error ( & key, & other. key , & item. to_string ( ) ) ;
87+ ( existing, & new)
88+ } ;
89+
90+ if overwriten. key . loc . ptr . kind >= keep. key . loc . ptr . kind {
91+ if overwriten. block . equivalent ( & keep. block ) {
92+ exact_dup_reporter ( & keep. key , & overwriten. key , & item. to_string ( ) ) ;
93+ } else {
94+ dup_error ( & keep. key , & overwriten. key , & item. to_string ( ) ) ;
95+ }
96+ }
97+ // Update the db if the new entry is the one we're keeping
98+ if & raw const new == & raw const * keep {
99+ self . items_lc [ item as usize ]
100+ . insert ( Lowercase :: new ( new. key . as_str ( ) ) , new. key . as_str ( ) ) ;
101+ occupied_entry. insert ( new) ;
80102 }
81103 }
104+ Entry :: Vacant ( vacant_entry) => {
105+ self . items_lc [ item as usize ] . insert ( Lowercase :: new ( key. as_str ( ) ) , key. as_str ( ) ) ;
106+ vacant_entry. insert ( DbEntry { key, block, kind } ) ;
107+ }
82108 }
83- self . items_lc [ item as usize ] . insert ( Lowercase :: new ( key. as_str ( ) ) , key. as_str ( ) ) ;
84- self . database [ item as usize ] . insert ( key. as_str ( ) , DbEntry { key, block, kind } ) ;
85109 }
86110
87111 #[ cfg( feature = "hoi4" ) ]
0 commit comments