code: func (ek *expKeeper) updateBookkeeping(toTrack []*expiryInfo, toClear []*expiryInfoKey) error {
  	updateBatch := leveldbhelper.NewUpdateBatch()
  	for _, expinfo := range toTrack {
  		k, v, err := encodeKV(expinfo)
  		if err != nil {
  			return err
  		}
  		updateBatch.Put(k, v)
  	}
  	for _, expinfokey := range toClear {
  		updateBatch.Delete(encodeExpiryInfoKey(expinfokey))
  	}
  	return ek.db.WriteBatch(updateBatch, true)
  }
docs: // updateBookkeeping updates the information stored in the bookkeeper
  // 'toTrack' parameter causes new entries in the bookkeeper and  'toClear' parameter contains the entries that
  // are to be removed from the bookkeeper. This function is invoked with the commit of every block. As an
  // example, the commit of the block with block number 50, 'toTrack' parameter may contain following two entries:
  // (1) &expiryInfo{&expiryInfoKey{committingBlk: 50, expiryBlk: 55}, pvtdataKeys....} and
  // (2) &expiryInfo{&expiryInfoKey{committingBlk: 50, expiryBlk: 60}, pvtdataKeys....}
  // The 'pvtdataKeys' in the first entry contains all the keys (and key-hashes) that are to be expired at block 55 (i.e., these collections have a BTL configured to 4)
  // and the 'pvtdataKeys' in second entry contains all the keys (and key-hashes) that are to be expired at block 60 (i.e., these collections have a BTL configured to 9).
  // Similarly, continuing with the above example, the parameter 'toClear' may contain following two entries
  // (1) &expiryInfoKey{committingBlk: 45, expiryBlk: 50} and (2) &expiryInfoKey{committingBlk: 40, expiryBlk: 50}. The first entry was created
  // at the time of the commit of the block number 45 and the second entry was created at the time of the commit of the block number 40, however
  // both are expiring with the commit of block number 50.