Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-89205

Use CRTP to avoid virtual calls in PrepareExecutionHelper

    • Type: Icon: Improvement Improvement
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • Labels:
    • Query Optimization

      The way PrepareExecutionHelper and its subclasses are organized is already close to CRTP, but involves more virtual calls than a CRTP implementation would involve.

      The base class defines some virtual functions to be overridden (for example buildPlanCacheKey()). A derived class inherits from the base while templating on types specific to its execution method.

      class SlotBasedPrepareExecutionHelper final
          : public PrepareExecutionHelper<sbe::PlanCacheKey, SlotBasedPrepareExecutionResult> {
      

      During the top-level prepare() call, the base class calls the overridden buildPlanCacheKey() virtual function (and others).

       

      Since the base class is already templated differently by each derived class, we don't care about having a common base class. The inheritance is for code sharing only. This makes it eligible for CRTP, which would avoid all virtual calls. We add the Derived type to the base class template parameters.

      template <typename KeyType, typename ResultType, typename Derived>
      class PrepareExecutionHelper {
      
      class SlotBasedPrepareExecutionHelper final : public PrepareExecutionHelper<sbe::PlanCacheKey, SlotBasedPrepareExecutionResult, SlotBasedPrepareExecutionHelper> {
      

      Then the base class implementation of prepare() would call 

      static_cast<Derived*>(this)->buildPlanCacheKey()

      instead of 

      buildPlanCacheKey()

      instead of a virtual call, the function would be resolved at compile time.

       

      If this was not a hot code path, I would recommend simpler and more understandable code over confusing C++ patterns. But the execution helpers are used in every query and have a lot of virtual function calls.

       

            Assignee:
            Unassigned Unassigned
            Reporter:
            matt.boros@mongodb.com Matt Boros
            Votes:
            0 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated: