code: func CleanupGarbage(c context.Context, cleanup ...Garbage) error {
  	if datastore.CurrentTransaction(c) != nil {
  		panic("dsset.CleanupGarbage must be called outside of a transaction")
  	}
  
  	keys := []*datastore.Key{}
  	for _, tombs := range cleanup {
  		for _, tomb := range tombs {
  			keys = append(keys, tomb.storage...)
  		}
  	}
  
  	err := batchOp(len(keys), func(start, end int) error {
  		return datastore.Delete(c, keys[start:end])
  	})
  	if err != nil {
  		return transient.Tag.Apply(err)
  	}
  
  	for _, tombs := range cleanup {
  		for _, tomb := range tombs {
  			tomb.cleanedUp = true
  			tomb.storage = nil
  		}
  	}
  	return nil
  }
docs: // CleanupGarbage deletes entities used to store items under given tombstones.
  //
  // This is datastore's MultiDelete RPC in disguise. Touches many entity groups.
  // Must be called outside of transactions. Idempotent.
  //
  // Can handle tombstones from multiple different sets at once. This is preferred
  // over calling 'CleanupGarbage' multiple times (once per set), since it
  // collapses multiple datastore RPCs into one.
  //
  // This MUST be called before tombstones returned by 'List' are removed in
  // 'Pop'. Failure to do so will make items reappear in the set.
  //
  // Returns only transient errors. There's no way to know which items were
  // removed and which weren't in case of an error.