code: func NewDeltaFIFO(keyFunc KeyFunc, knownObjects KeyListerGetter) *DeltaFIFO {
  	f := &DeltaFIFO{
  		items:        map[string]Deltas{},
  		queue:        []string{},
  		keyFunc:      keyFunc,
  		knownObjects: knownObjects,
  	}
  	f.cond.L = &f.lock
  	return f
  }
docs: // NewDeltaFIFO returns a Store which can be used process changes to items.
  //
  // keyFunc is used to figure out what key an object should have. (It's
  // exposed in the returned DeltaFIFO's KeyOf() method, with bonus features.)
  //
  // 'keyLister' is expected to return a list of keys that the consumer of
  // this queue "knows about". It is used to decide which items are missing
  // when Replace() is called; 'Deleted' deltas are produced for these items.
  // It may be nil if you don't need to detect all deletions.
  // TODO: consider merging keyLister with this object, tracking a list of
  //       "known" keys when Pop() is called. Have to think about how that
  //       affects error retrying.
  // NOTE: It is possible to misuse this and cause a race when using an
  //       external known object source.
  //       Whether there is a potential race depends on how the comsumer
  //       modifies knownObjects. In Pop(), process function is called under
  //       lock, so it is safe to update data structures in it that need to be
  //       in sync with the queue (e.g. knownObjects).
  //
  //       Example:
  //       In case of sharedIndexInformer being a consumer
  //       (https://github.com/kubernetes/kubernetes/blob/0cdd940f/staging/
  //       src/k8s.io/client-go/tools/cache/shared_informer.go#L192),
  //       there is no race as knownObjects (s.indexer) is modified safely
  //       under DeltaFIFO's lock. The only exceptions are GetStore() and
  //       GetIndexer() methods, which expose ways to modify the underlying
  //       storage. Currently these two methods are used for creating Lister
  //       and internal tests.
  //
  // Also see the comment on DeltaFIFO.