docs: def __update(self, sym, item, metadata=None, combine_method=None, chunk_range=None, audit=None):
          '''
          helper method used by update and append since they very closely
          resemble eachother. Really differ only by the combine method.
          append will combine existing date with new data (within a chunk),
          whereas update will replace existing data with new data (within a
          chunk).
          '''
          if not isinstance(item, (DataFrame, Series)):
              raise Exception("Can only chunk DataFrames and Series")
  
          self._arctic_lib.check_quota()
  
          symbol = sym[SYMBOL]
  
          if chunk_range is not None:
              self.delete(symbol, chunk_range)
              sym = self._get_symbol_info(symbol)
  
          ops = []
          meta_ops = []
          chunker = CHUNKER_MAP[sym[CHUNKER]]
  
          appended = 0
          new_chunks = 0
          for start, end, _, record in chunker.to_chunks(item, chunk_size=sym[CHUNK_SIZE]):
              # read out matching chunks
              df = self.read(symbol, chunk_range=chunker.to_range(start, end), filter_data=False)
              # assuming they exist, update them and store the original chunk
              # range for later use
              if len(df) > 0:
                  record = combine_method(df, record)
                  if record is None or record.equals(df):
                      continue
  
                  sym[APPEND_COUNT] += len(record) - len(df)
                  appended += len(record) - len(df)
                  sym[LEN] += len(record) - len(df)
              else:
                  sym[CHUNK_COUNT] += 1
                  new_chunks += 1
                  sym[LEN] += len(record)
  
              data = SER_MAP[sym[SERIALIZER]].serialize(record)
              meta = data[METADATA]
  
              chunk_count = int(len(data[DATA]) / MAX_CHUNK_SIZE + 1)
              seg_count = mongo_count(self._collection, filter={SYMBOL: symbol, START: start, END: end})
              # remove old segments for this chunk in case we now have less
              # segments than we did before
              if seg_count > chunk_count:
                  self._collection.delete_many({SYMBOL: symbol,
                                                START: start,
                                                END: end,
                                                SEGMENT: {'$gte': chunk_count}})
  
              for i in xrange(chunk_count):
                  chunk = {DATA: Binary(data[DATA][i * MAX_CHUNK_SIZE: (i + 1) * MAX_CHUNK_SIZE])}
                  chunk[SEGMENT] = i
                  chunk[START] = start
                  chunk[END] = end
                  chunk[SYMBOL] = symbol
                  dates = [chunker.chunk_to_str(start), chunker.chunk_to_str(end), str(chunk[SEGMENT]).encode('ascii')]
                  sha = self._checksum(dates, data[DATA])
                  chunk[SHA] = sha
                  ops.append(pymongo.UpdateOne({SYMBOL: symbol,
                                                START: start,
                                                END: end,
                                                SEGMENT: chunk[SEGMENT]},
                                               {'$set': chunk}, upsert=True))
                  meta_ops.append(pymongo.UpdateOne({SYMBOL: symbol,
                                                     START: start,
                                                     END: end},
                                                    {'$set': meta}, upsert=True))
          if ops:
              self._collection.bulk_write(ops, ordered=False)
              self._mdata.bulk_write(meta_ops, ordered=False)
  
          sym[USERMETA] = metadata
          self._symbols.replace_one({SYMBOL: symbol}, sym)
          if audit is not None:
              if new_chunks > 0:
                  audit['new_chunks'] = new_chunks
              if appended > 0:
                  audit['appended_rows'] = appended
              self._audit.insert_one(audit)