@@ -192,24 +192,30 @@ def find(self) -> list[Tag]:
192192 all_tags = self ._ctx .client .tags .find ()
193193
194194 # O(n^2) algorithm to find all child tags
195+ #
195196 # This could be optimized by using a dictionary to store the tags by their parent_id and
196197 # then recursively traverse the dictionary to find all child tags. O(2 * n) = O(n) but the
197198 # code is more complex
198199 #
199- # If the tags are always ordered, it could be performed in a single pass (O(n)) as parents
200- # always appear before any children
200+ # If the tags are always ordered (which they seem to be ordered by creation date - parents are first),
201+ # this algo be performed in a two passes (one to add all tags, one to confirm no more additions)
201202 child_tags = []
202203 parent_ids = {self ._parent_tag ["id" ]}
203- child_tag_found : bool = True
204- while child_tag_found :
205- child_tag_found = False
206-
204+ tag_found : bool = True
205+ while tag_found :
206+ tag_found = False
207207 for tag in [* all_tags ]:
208- if tag .get ("parent_id" ) in parent_ids :
208+ parent_id = tag .get ("parent_id" )
209+ if not parent_id :
210+ # Skip top-level tags
211+ all_tags .remove (tag )
212+ continue
213+ if parent_id in parent_ids :
209214 child_tags .append (tag )
210215 parent_ids .add (tag ["id" ])
216+ # Child found, remove from search list
211217 all_tags .remove (tag )
212- child_tag_found = True
218+ tag_found = True
213219
214220 return child_tags
215221
@@ -236,7 +242,6 @@ def get(self, tag_id: str) -> Tag:
236242 Tag
237243 The tag object.
238244 """
239- # TODO-barret-future: Replace with `self._ctx.client.tags.find(id=tag_id)`
240245 if not isinstance (tag_id , str ):
241246 raise TypeError ("`tag_id` must be a string" )
242247 if tag_id == "" :
0 commit comments