/** * Returns a new instance of this class by retrieving the product partitions of the specified ad * group. All parameters are required. */ public static ProductPartitionTree createAdGroupTree( AdWordsServices services, AdWordsSession session, Long adGroupId) throws ApiException, RemoteException { // Get the AdGroupCriterionService. AdGroupCriterionServiceInterface criterionService = services.get(session, AdGroupCriterionServiceInterface.class); SelectorBuilder selectorBuilder = new SelectorBuilder() .fields( REQUIRED_SELECTOR_FIELD_ENUMS.toArray( new AdGroupCriterionField[REQUIRED_SELECTOR_FIELD_ENUMS.size()])) .equals(AdGroupCriterionField.AdGroupId, adGroupId.toString()) .equals(AdGroupCriterionField.CriteriaType, "PRODUCT_PARTITION") .in( AdGroupCriterionField.Status, UserStatus.ENABLED.getValue(), UserStatus.PAUSED.getValue()) .limit(PAGE_SIZE); AdGroupCriterionPage adGroupCriterionPage; // A multimap from each product partition ID to its direct children. ListMultimap<Long, AdGroupCriterion> parentIdMap = LinkedListMultimap.create(); int offset = 0; do { // Get the next page of results. adGroupCriterionPage = criterionService.get(selectorBuilder.build()); if (adGroupCriterionPage != null && adGroupCriterionPage.getEntries() != null) { for (AdGroupCriterion adGroupCriterion : adGroupCriterionPage.getEntries()) { ProductPartition partition = (ProductPartition) adGroupCriterion.getCriterion(); parentIdMap.put(partition.getParentCriterionId(), adGroupCriterion); } offset += adGroupCriterionPage.getEntries().length; selectorBuilder.increaseOffsetBy(PAGE_SIZE); } } while (offset < adGroupCriterionPage.getTotalNumEntries()); // Construct the ProductPartitionTree from the parentIdMap. if (!parentIdMap.containsKey(null)) { Preconditions.checkState( parentIdMap.isEmpty(), "No root criterion found in the tree but the tree is not empty"); return createEmptyAdGroupTree( adGroupId, getAdGroupBiddingStrategyConfiguration(services, session, adGroupId)); } return createNonEmptyAdGroupTree(adGroupId, parentIdMap); }
private <N extends InternalTitanVertex> void persist( ListMultimap<N, InternalRelation> mutatedEdges, Map<TitanType, TypeSignature> signatures, InternalTitanTransaction tx, StoreMutator mutator) throws StorageException { assert mutatedEdges != null && !mutatedEdges.isEmpty(); Collection<N> vertices = mutatedEdges.keySet(); // if (sortNodes) { // List<N> sortedvertices = new ArrayList<N>(vertices); // Collections.sort(sortedvertices, new Comparator<N>(){ // // @Override // public int compare(N o1, N o2) { // assert o1.getID()!=o2.getID(); // if (o1.getID()<o2.getID()) return -1; // else return 1; // } // // }); // vertices=sortedvertices; // } for (N node : vertices) { List<InternalRelation> edges = mutatedEdges.get(node); List<Entry> additions = new ArrayList<Entry>(edges.size()); List<ByteBuffer> deletions = new ArrayList<ByteBuffer>(Math.max(10, edges.size() / 10)); List<TitanProperty> properties = new ArrayList<TitanProperty>(); for (InternalRelation edge : edges) { if (edge.isRemoved()) { if (edge.isProperty()) { deleteIndexEntry((TitanProperty) edge, mutator); } deletions.add(getEntry(tx, edge, node, signatures, true).getColumn()); } else { assert edge.isNew(); if (edge.isProperty()) properties.add((TitanProperty) edge); additions.add(getEntry(tx, edge, node, signatures)); } } mutator.mutateEdges(IDHandler.getKey(node.getID()), additions, deletions); // Persist property index for retrieval for (TitanProperty prop : properties) { addIndexEntry(prop, mutator); } } }
/** * Returns a new tree based on a non-empty collection of ad group criteria. All parameters * required. * * @param adGroupId the ID of the ad group * @param parentIdMap the multimap from parent product partition ID to child criteria * @return a new ProductPartitionTree */ private static ProductPartitionTree createNonEmptyAdGroupTree( Long adGroupId, ListMultimap<Long, AdGroupCriterion> parentIdMap) { Preconditions.checkNotNull(adGroupId, "Null ad group ID"); Preconditions.checkArgument( !parentIdMap.isEmpty(), "parentIdMap passed for ad group ID %s is empty", adGroupId); Preconditions.checkArgument( parentIdMap.containsKey(null), "No root criterion found in the list of ad group criteria for ad group ID %s", adGroupId); AdGroupCriterion rootCriterion = Iterables.getOnlyElement(parentIdMap.get(null)); Preconditions.checkState( rootCriterion instanceof BiddableAdGroupCriterion, "Root criterion for ad group ID %s is not a BiddableAdGroupCriterion", adGroupId); BiddableAdGroupCriterion biddableRootCriterion = (BiddableAdGroupCriterion) rootCriterion; BiddingStrategyConfiguration biddingStrategyConfig = biddableRootCriterion.getBiddingStrategyConfiguration(); Preconditions.checkState( biddingStrategyConfig != null, "Null bidding strategy config on the root node of ad group ID %s", adGroupId); ProductPartitionNode rootNode = new ProductPartitionNode( null, (ProductDimension) null, rootCriterion.getCriterion().getId(), new ProductDimensionComparator()); // Set the root's bid if a bid exists on the BiddableAdGroupCriterion. Money rootNodeBid = getBid(biddableRootCriterion); if (rootNodeBid != null) { rootNode = rootNode.asBiddableUnit().setBid(rootNodeBid.getMicroAmount()); } addChildNodes(rootNode, parentIdMap); return new ProductPartitionTree(adGroupId, biddingStrategyConfig, rootNode); }
/** * Is this report a success? * * @return true if the message map is empty */ public boolean isSuccess() { return msgMap.isEmpty(); }
@Override public boolean isEmpty() { return cells.isEmpty() && isConcreteCollection(); }
@Override public boolean isEmpty() { return backingMap.isEmpty(); }
@Override public void save( final Collection<InternalRelation> addedRelations, final Collection<InternalRelation> deletedRelations, final InternalTitanTransaction tx) throws StorageException { // Setup log.debug( "Saving transaction. Added {}, removed {}", addedRelations.size(), deletedRelations.size()); final Map<TitanType, TypeSignature> signatures = new HashMap<TitanType, TypeSignature>(); final TransactionHandle txh = tx.getTxHandle(); final StoreMutator mutator = getStoreMutator(txh); final boolean acquireLocks = tx.getTxConfiguration().hasAcquireLocks(); // 1. Assign TitanVertex IDs assignIDs(addedRelations, tx); for (int saveAttempt = 0; saveAttempt < maxWriteRetryAttempts; saveAttempt++) { // while (true) { //Indefinite loop, broken if no exception occurs, otherwise retried // or failed immediately try { // 2. Collect deleted edges ListMultimap<InternalTitanVertex, InternalRelation> mutations = ArrayListMultimap.create(); if (deletedRelations != null && !deletedRelations.isEmpty()) { for (InternalRelation del : deletedRelations) { assert del.isRemoved(); for (int pos = 0; pos < del.getArity(); pos++) { InternalTitanVertex node = del.getVertex(pos); if (pos == 0 || !del.isUnidirected()) { mutations.put(node, del); } if (pos == 0 && acquireLocks && del.getType().isFunctional() && ((InternalTitanType) del.getType()).isFunctionalLocking()) { Entry entry = getEntry(tx, del, node, signatures); mutator.acquireEdgeLock( IDHandler.getKey(node.getID()), entry.getColumn(), entry.getValue()); } } if (acquireLocks && del.isProperty()) { lockKeyedProperty((TitanProperty) del, mutator); } } } ListMultimap<InternalTitanType, InternalRelation> simpleEdgeTypes = null; ListMultimap<InternalTitanType, InternalRelation> otherEdgeTypes = null; // 3. Sort Added Edges for (InternalRelation edge : addedRelations) { if (edge.isRemoved()) continue; assert edge.isNew(); TitanType et = edge.getType(); // Give special treatment to edge type definitions if (SystemTypeManager.prepersistedSystemTypes.contains(et)) { assert edge.getVertex(0) instanceof InternalTitanType; InternalTitanType node = (InternalTitanType) edge.getVertex(0); assert node.hasID(); if (node.isSimple()) { if (simpleEdgeTypes == null) simpleEdgeTypes = ArrayListMultimap.create(); simpleEdgeTypes.put(node, edge); } else { if (otherEdgeTypes == null) otherEdgeTypes = ArrayListMultimap.create(); otherEdgeTypes.put(node, edge); } } else { // STANDARD TitanRelation assert (edge.getArity() == 1 && edge.isProperty()) || (edge.getArity() == 2 && edge.isEdge()); for (int pos = 0; pos < edge.getArity(); pos++) { InternalTitanVertex node = edge.getVertex(pos); assert node.hasID(); if (pos == 0 || !edge.isUnidirected()) { mutations.put(node, edge); } if (pos == 0 && acquireLocks && edge.getType().isFunctional() && !node.isNew() && ((InternalTitanType) edge.getType()).isFunctionalLocking()) { Entry entry = getEntry(tx, edge, node, signatures, true); mutator.acquireEdgeLock(IDHandler.getKey(node.getID()), entry.getColumn(), null); } } } if (acquireLocks && edge.isProperty()) { lockKeyedProperty((TitanProperty) edge, mutator); } } // 3. Persist if (simpleEdgeTypes != null) persist(simpleEdgeTypes, signatures, tx, mutator); if (otherEdgeTypes != null) persist(otherEdgeTypes, signatures, tx, mutator); mutator.flush(); // Commit saved EdgeTypes to TypeManager if (simpleEdgeTypes != null) commitEdgeTypes(simpleEdgeTypes.keySet()); if (otherEdgeTypes != null) commitEdgeTypes(otherEdgeTypes.keySet()); if (!mutations.isEmpty()) persist(mutations, signatures, tx, mutator); mutator.flush(); // Successfully completed - return to break out of loop break; } catch (Throwable e) { if (e instanceof TemporaryStorageException) { if (saveAttempt < maxWriteRetryAttempts - 1) temporaryStorageException(e); else throw new PermanentStorageException( "Tried committing " + maxWriteRetryAttempts + " times on temporary exception without success", e); } else if (e instanceof StorageException) { throw (StorageException) e; } else { throw new PermanentStorageException( "Unidentified exception occurred during persistence", e); } } } }