/// <summary> /// Performs a <em>shallow</em> copy of properties from /// <paramref name="fromNode"/> to <paramref name="toNode"/>. /// </summary> /// <param name="fromNode">The node to copy from.</param> /// <param name="toNode">The node to copy to.</param> /// <returns><paramref name="toNode"/>, with its properties updated.</returns> /// <remarks>Does <em>not</em> change the parent node of /// <paramref name="toNode"/>.</remarks> public static ProductPartitionNode CopyProperties(ProductPartitionNode fromNode, ProductPartitionNode toNode) { switch (fromNode.nodeState.NodeType) { case NodeType.BIDDABLE_UNIT: toNode = toNode.AsBiddableUnit(); if (fromNode.CpcBidSpecified) { toNode.CpcBid = fromNode.CpcBid; } break; case NodeType.EXCLUDED_UNIT: toNode = toNode.AsExcludedUnit(); break; case NodeType.SUBDIVISION: toNode = toNode.AsSubdivision(); break; default: throw new InvalidOperationException( "Unrecognized node state: " + fromNode.nodeState.NodeType); } toNode.ProductPartitionId = fromNode.ProductPartitionId; return(toNode); }
/// <summary> /// Returns a new tree based on a non-empty collection of ad group criteria. /// </summary> /// <param name="adGroupId">The ad group ID.</param> /// <param name="parentIdMap">The multimap from parent product partition ID /// to child criteria.</param> /// <returns>a new product partition tree.</returns> private static ProductPartitionTree CreateAdGroupTree(long adGroupId, Dictionary <long, List <AdGroupCriterion> > parentIdMap) { ProductPartitionNode rootNode = null; if (parentIdMap.Count == 0) { rootNode = new ProductPartitionNode(null, null, NEW_ROOT_ID); } else { List <AdGroupCriterion> root = CollectionUtilities.TryGetValue(parentIdMap, ROOT_PARENT_ID); PreconditionUtilities.CheckState(root != null, string.Format(ShoppingMessages.RootCriteriaNotFoundInCriteriaList, adGroupId)); PreconditionUtilities.CheckState(root.Count == 1, string.Format(ShoppingMessages.MoreThanOneRootFound, adGroupId)); AdGroupCriterion rootCriterion = root[0]; PreconditionUtilities.CheckState(rootCriterion is BiddableAdGroupCriterion, string.Format(ShoppingMessages.RootCriterionIsNotBiddable, adGroupId)); BiddableAdGroupCriterion biddableRootCriterion = (BiddableAdGroupCriterion)rootCriterion; rootNode = new ProductPartitionNode(null, null, rootCriterion.criterion.id, new ProductDimensionEqualityComparer()); // Set the root's bid if a bid exists on the BiddableAdGroupCriterion. Money rootNodeBid = GetBid(biddableRootCriterion); if (rootNodeBid != null) { rootNode.AsBiddableUnit().CpcBid = rootNodeBid.microAmount; } AddChildNodes(rootNode, parentIdMap); } return(new ProductPartitionTree(adGroupId, rootNode)); }
/// <summary> /// Using the criteria in <paramref name="parentIdMap"/>, recursively adds /// all children under the partition ID of <paramref name="parentNode"/> to /// <paramref name="parentNode"/>. /// </summary> /// <param name="parentNode">The parent node.</param> /// <param name="parentIdMap">The multimap from parent partition ID to list /// of child criteria</param> private static void AddChildNodes(ProductPartitionNode parentNode, Dictionary <long, List <AdGroupCriterion> > parentIdMap) { List <AdGroupCriterion> childCriteria = CollectionUtilities.TryGetValue(parentIdMap, parentNode.ProductPartitionId); // no children, return. if (childCriteria == null || childCriteria.Count == 0) { return; } // Ensure that the parent is a subdivision. parentNode.AsSubdivision(); foreach (AdGroupCriterion childCriterion in childCriteria) { ProductPartition partition = (ProductPartition)childCriterion.criterion; ProductPartitionNode childNode = parentNode.AddChild(partition.caseValue); childNode.ProductPartitionId = partition.id; if (childCriterion is BiddableAdGroupCriterion) { childNode = childNode.AsBiddableUnit(); Money cpcBidAmount = GetBid((BiddableAdGroupCriterion)childCriterion); if (cpcBidAmount != null) { childNode.CpcBid = cpcBidAmount.microAmount; } } else { childNode = childNode.AsExcludedUnit(); } AddChildNodes(childNode, parentIdMap); } }