Commits

Kirill Simonov committed 0e874d5

Reduce stack growth when encoding the binding graph.

  • Participants
  • Parent commits af0fec6

Comments (0)

Files changed (3)

src/htsql/core/adapter.py

         return None
 
     @classmethod
+    def __prepare__(interface, *args, **kwds):
+        """
+        Instantiates the interface to the given arguments.
+        """
+        # Extract polymorphic parameters.
+        dispatch_key = interface.__dispatch__(*args, **kwds)
+        # Realize the interface.
+        realization = interface.__realize__(dispatch_key)
+        # Instantiate and return the realization.
+        return realization(*args, **kwds)
+
+    @classmethod
     def __invoke__(interface, *args, **kwds):
         """
         Realizes and applies the interface to the given arguments.
+
+        Use ``__prepare__()()`` instead when traversing a deeply nested tree.
         """
         # Extract polymorphic parameters.
         dispatch_key = interface.__dispatch__(*args, **kwds)

src/htsql/core/classify.py

         if len(alternatives) == 1:
             return alternatives[0]
         else:
-            return AmbiguousArc(alternatives)
+            return AmbiguousArc(None, alternatives)
 
 
 class Call(Adapter):

src/htsql/core/tr/encode.py

         # result.
         if self.with_cache:
             if binding not in self.binding_to_code:
-                code = encode(binding, self)
+                #FIXME: reduce recursion depth
+                #code = encode(binding, self)
+                code = Encode.__prepare__(binding, self)()
                 self.binding_to_code[binding] = code
             return self.binding_to_code[binding]
         # Caching is disabled; return a new instance every time.
         # result.
         if self.with_cache:
             if binding not in self.binding_to_flow:
-                flow = relate(binding, self)
+                #FIXME: reduce recursion depth
+                #flow = relate(binding, self)
+                flow = Relate.__prepare__(binding, self)()
                 self.binding_to_flow[binding] = flow
             return self.binding_to_flow[binding]
         # Caching is disabled; return a new instance every time.
 
     def __call__(self):
         # Delegate it to the `Convert` adapter.
-        return Convert.__invoke__(self.binding, self.state)
+        return Convert.__prepare__(self.binding, self.state)()
 
 
 class Convert(Adapter):
 
     def __call__(self):
         # Delegate the translation to the `EncodeBySignature` adapter.
-        return EncodeBySignature.__invoke__(self.binding, self.state)
+        return EncodeBySignature.__prepare__(self.binding, self.state)()
 
 
 class RelateFormula(Relate):
 
     def __call__(self):
         # Delegate the translation to the `RelateBySignature` adapter.
-        return RelateBySignature.__invoke__(self.binding, self.state)
+        return RelateBySignature.__prepare__(self.binding, self.state)()
 
 
 class EncodeBySignatureBase(Adapter):