/** * <summary> * Creates a sub-projection for current projection.</summary> * * <param name="nodes">Collection of nodes that sub-projection will be restricted to. If <c>null</c>,</param> * created projection is dynamic and will take nodes from topology. * <param name="filter">Filter to be applied to nodes in projection.</param> * <param name="balancer">Balancer to use in projection.</param> * <returns>Created projection.</returns> * <exception cref="GridClientException"> * If resulting projection is empty. Note that this exception may only be thrown on * case of static projections, i.e. where collection of nodes is not null.</exception> */ protected T CreateProjection(ICollection <N> nodes, Predicate <N> filter, IGridClientLoadBalancer balancer) { if (nodes != null && nodes.Count == 0) { throw new GridClientException("Failed to create projection: given nodes collection is empty."); } if (filter != null && this._filter != null) { filter = U.And <N>(this._filter, filter); } else if (filter == null) { filter = this._filter; } ICollection <N> subset = Intersection(this._nodes, nodes); if (subset != null && subset.Count == 0) { throw new GridClientException("Failed to create projection (given node set does not overlap with " + "existing node set) [prjNodes=" + this._nodes + ", nodes=" + nodes); } if (filter != null && subset != null) { subset = U.ApplyFilter(subset, filter); if (subset != null && subset.Count == 0) { throw new GridClientException("Failed to create projection (none of the nodes in projection node " + "set passed the filter) [prjNodes=" + subset + ", filter=" + filter + ']'); } } if (balancer == null) { balancer = this._balancer; } return(CreateProjectionImpl(nodes, filter, balancer)); }