docs: def _process(self, data):
          "Process a single packet and update the internal tables."
          parts = data.split(':')
          if self._debug:
              self.error('packet: %r' % data)
          if not parts:
              return
  
          # interpret the packet and update stats
          stats = self._stats
          key = parts[0].translate(KEY_TABLE, KEY_DELETIONS)
          if self._key_prefix:
              key = '.'.join([self._key_prefix, key])
          for part in parts[1:]:
              srate = 1.0
              fields = part.split('|')
              length = len(fields)
              if length < 2:
                  continue
              value = fields[0]
              stype = fields[1].strip()
  
              with stats_lock:
                  # timer (milliseconds)
                  if stype == 'ms':
                      stats.timers[key].append(float(value if value else 0))
  
                  # counter with optional sample rate
                  elif stype == 'c':
                      if length == 3 and fields[2].startswith('@'):
                          srate = float(fields[2][1:])
                      value = float(value if value else 1) * (1 / srate)
                      stats.counts[key] += value
                  elif stype == 'g':
                      value = float(value if value else 1)
                      stats.gauges[key] = value