@@ -21,6 +21,9 @@ def __init__(self, model: Model, model_json_filepath: str):
2121
2222 self .model_filepath = model_json_filepath
2323 self .model_json = None
24+
25+ self ._assigned_uids : Set [int ] = set ()
26+
2427 self ._load_model_json ()
2528
2629 def _load_model_json (self ):
@@ -35,6 +38,16 @@ def _load_model_json(self):
3538 self .model_json = json .load (model_file )
3639 logger .debug (f"Syncing model with model file: { self .model_filepath } " )
3740
41+ self ._load_assigned_uids ()
42+
43+ def _load_assigned_uids (self ):
44+ for entity_json in self .model_json ["entities" ]:
45+ self ._assigned_uids .add (IdUid .from_str (entity_json ["id" ]).uid )
46+ for prop_json in entity_json ["properties" ]:
47+ self ._assigned_uids .add (IdUid .from_str (prop_json ["id" ]).uid )
48+ if "indexId" in prop_json :
49+ self ._assigned_uids .add (IdUid .from_str (prop_json ["indexId" ]).uid )
50+
3851 def _save_model_json (self ):
3952 """ Replaces model JSON with the serialized model whose ID/UIDs are assigned. """
4053
@@ -119,31 +132,20 @@ def _find_property_json_by_name(self, entity_json: Dict[str, Any], prop_name: st
119132 return prop_json
120133 return None
121134
122- @staticmethod
123- def _generate_uid () -> int :
124- return random .getrandbits (63 ) + 1 # 0 would be invalid
135+ def _generate_uid (self ) -> int :
136+ while True :
137+ generated_uid = random .getrandbits (63 ) + 1 # 0 would be invalid
138+ if generated_uid not in self ._assigned_uids :
139+ break
140+ self ._assigned_uids .add (generated_uid )
141+ return generated_uid
125142
126143 def _validate_uid_unassigned (self , uid : int ):
127- # TODO use a dict/set for all assigned UIDs (for all entities/properties/indexes) for faster lookup
128144 """ Validates that a user supplied UID is not assigned for any other entity/property/index.
129145 Raises a ValueError if the UID is already assigned elsewhere.
130146 """
131-
132- try :
133- entity_json = self ._find_entity_json_by_uid (uid )
134- if entity_json is not None :
135- raise ValueError (f"in Entity \" { entity_json ['name' ]} \" ({ entity_json ['id' ]} )" )
136-
137- for entity_json in self .model_json ["entities" ]:
138- prop_json = self ._find_property_json_by_uid (entity_json , uid )
139- if prop_json is not None :
140- raise ValueError (f"in Property \" { entity_json ['name' ]} .{ prop_json ['name' ]} \" ({ prop_json ['id' ]} )" )
141- for prop_json in entity_json ["properties" ]:
142- if "indexId" in prop_json and IdUid .from_str (prop_json ["indexId" ]).uid == uid :
143- raise ValueError (
144- f"in Property index \" { entity_json ['name' ]} .{ prop_json ['name' ]} \" ({ prop_json ['id' ]} )" )
145- except ValueError as error :
146- raise ValueError (f"User supplied UID \" { uid } \" found { error } " )
147+ if uid in self ._assigned_uids :
148+ raise ValueError (f"User supplied UID { uid } is already assigned elsewhere" )
147149
148150 def _validate_matching_prop (self , entity : _Entity , prop : Property , prop_json : Dict [str , Any ]):
149151 """ Validates that the given property matches the JSON property. """
0 commit comments