code: func (it *HasA) Stats() graph.IteratorStats {
  	subitStats := it.primaryIt.Stats()
  	// TODO(barakmich): These should really come from the quadstore itself
  	// and be optimized.
  	faninFactor := int64(1)
  	fanoutFactor := int64(30)
  	nextConstant := int64(2)
  	quadConstant := int64(1)
  	return graph.IteratorStats{
  		NextCost:     quadConstant + subitStats.NextCost,
  		ContainsCost: (fanoutFactor * nextConstant) * subitStats.ContainsCost,
  		Size:         faninFactor * subitStats.Size,
  		ExactSize:    false,
  		Next:         it.runstats.Next,
  		Contains:     it.runstats.Contains,
  		ContainsNext: it.runstats.ContainsNext,
  	}
  }
docs: // GetStats() returns the statistics on the HasA iterator. This is curious. Next
  // cost is easy, it's an extra call or so on top of the subiterator Next cost.
  // ContainsCost involves going to the graph.QuadStore, iterating out values, and hoping
  // one sticks -- potentially expensive, depending on fanout. Size, however, is
  // potentially smaller. we know at worst it's the size of the subiterator, but
  // if there are many repeated values, it could be much smaller in totality.