Uploaded image for project: 'Couchbase Server'
  1. Couchbase Server
  2. MB-46535

[BP MB-43037 to 6.6.3] Scrub code for value receivers where pointer receivers should be used

    XMLWordPrintable

Details

    • Untriaged
    • 1
    • Unknown

    Description

      I have run across a couple places in code that are problematically using value receivers instead of pointer receivers for methods. Usually this is not what we want, because it will make a (shallow) copy of the entire calling object and then invoke the method on it, instead of just invoking the method on the existing object. I assume there are probably more of these scattered around our code as I have not been seeking them out specifically, so we should do a scrub.

      There are at least two problems with value receivers:

      1. Performance: memory/CPU/garbage collection hit of making the unwanted copy of the calling object. For example, in indexer.go the following method creates a copy of the entire indexer object before invoking the method on that copy:

       This example was fixed by MB-36746:

      indexer.go
       
      func (idx indexer) newIndexInstMsg(m common.IndexInstMap) *MsgUpdateInstMap {
         return &MsgUpdateInstMap{indexInstMap: m, stats: idx.stats.Clone(),
            rollbackTimes: idx.keyspaceIdRollbackTimes}
      }
      

       

      2. Correctness: for cases of atomic pointer loads and stores inside Holder objects, if the Get method uses a value receiver, then a non-atomic copy of the Holder object is made upon which the Get method is invoked. The non-atomic copy may catch the pointer mid-update, resulting in a garbage pointer in the copied object, and then the Get method will atomically load that already-garbage pointer:

        This example was fixed by MB-36746:

      indexer/stats_manager.go
       
      func (h IndexerStatsHolder) Get() *IndexerStats {
         return (*IndexerStats)(atomic.LoadPointer(&h.ptr))
      }
      

       

      These should instead use pointer receivers (idx *indexer) and (h *IndexerStatsHolder), respectively.

      I will fix the above two examples as part of MB-36746, but we need to do a more thorough scrub.

      Attachments

        Issue Links

          For Gerrit Dashboard: MB-46535
          # Subject Branch Project Status CR V

          Activity

            People

              kevin.cherkauer Kevin Cherkauer (Inactive)
              kevin.cherkauer Kevin Cherkauer (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes

                  PagerDuty