class_docstr: Base class for Hoeffding Decision Trees.
  
  This is an **abstract class**, so it cannot be used directly. It defines base operations
  and properties that all the Hoeffding decision trees must inherit or implement according to
  their own design.
  
  Parameters
  ----------
  max_depth
      The maximum depth a tree can reach. If `None`, the tree will grow indefinitely.
  binary_split
      If True, only allow binary splits.
  max_size
      The max size of the tree, in Megabytes (MB).
  memory_estimate_period
      Interval (number of processed instances) between memory consumption checks.
  stop_mem_management
      If True, stop growing as soon as memory limit is hit.
  remove_poor_attrs
      If True, disable poor attributes to reduce memory usage.
  merit_preprune
      If True, enable merit-based tree pre-pruning.
docstr: Calculate the size of the model and trigger tracker function
  if the actual model size exceeds the max size in the configuration.
  
  This memory-management routine shared by all the Hoeffding Trees is based on [^1].
  
  References
  ----------
  [^1]: Kirkby, R.B., 2007. Improving hoeffding trees (Doctoral dissertation,
  The University of Waikato).
code: def _estimate_model_size(self):
      """Calculate the size of the model and trigger tracker function
      if the actual model size exceeds the max size in the configuration.
  
      This memory-management routine shared by all the Hoeffding Trees is based on [^1].
  
      References
      ----------
      [^1]: Kirkby, R.B., 2007. Improving hoeffding trees (Doctoral dissertation,
      The University of Waikato).
      """
      leaves = self._find_leaves()
      total_active_size = 0
      total_inactive_size = 0
      for leaf in leaves:
          if leaf.is_active():
              total_active_size += calculate_object_size(leaf)
          else:
              total_inactive_size += calculate_object_size(leaf)
      if total_active_size > 0:
          self._active_leaf_size_estimate = (
              total_active_size / self._n_active_leaves
          )
      if total_inactive_size > 0:
          self._inactive_leaf_size_estimate = (
              total_inactive_size / self._n_inactive_leaves
          )
      actual_model_size = calculate_object_size(self)
      estimated_model_size = (
          self._n_active_leaves * self._active_leaf_size_estimate
          + self._n_inactive_leaves * self._inactive_leaf_size_estimate
      )
      self._size_estimate_overhead_fraction = (
          actual_model_size / estimated_model_size
      )
      if actual_model_size > self._max_byte_size:
          self._enforce_size_limit()
  
imports: from __future__ import annotations
  import collections
  import functools
  import io
  import math
  from abc import ABC, abstractmethod
  from river import base
  from river.utils.norm import normalize_values_in_dict
  from .nodes.branch import DTBranch, NominalBinaryBranch, NominalMultiwayBranch, NumericBinaryBranch, NumericMultiwayBranch
  from .nodes.leaf import HTLeaf
  from .utils import calculate_object_size
label_desc: Use image node_id 20 for calling the HoeffdingTree obj's underlying member method code with example usage: obj._estimate_model_size() without return types