/** * Creating a separate copy here to avoid ConcurrentModificationException as BucketList gets modified * during assignment business logic execution. * * @param bucketList * @return New object/deep copy of BucketList. */ private BucketList makeCopy(BucketList bucketList) { List<Bucket> iBucketList = new ArrayList<>(bucketList.getBuckets()); BucketList newBucketList = new BucketList(); newBucketList.setBuckets(iBucketList); return newBucketList; } }
/** * Queries the database to get additional information to the buckets for the provided * experiment, like the label and allocation percentage. For the analytics data per bucket * see {@link #getAnalyticData(List, Parameters)}. * * @param exp the experiment that should be enriched with bucket data * @return the same ExperimentDetail object but with additional information */ private ExperimentDetail getBucketData(ExperimentDetail exp) { List<Bucket> buckList = buckets.getBuckets(exp.getId(), false).getBuckets(); exp.addBuckets(buckList); return exp; }
/** * Get the bucket based on experiment id and bucket label * If metadata cache is enabled then fetch from cache else fetch from database. * * @param experimentID * @param bucketLabel * @return */ protected Optional<Bucket> getBucketByLabel(Experiment.ID experimentID, Bucket.Label bucketLabel) { Optional<Bucket> rBucket = Optional.empty(); BucketList bucketList = null; if (metadataCacheEnabled) { bucketList = metadataCache.getBucketList(experimentID); } else { bucketList = repository.getBucketList(experimentID); } if (isNull(bucketList)) return rBucket; for (Bucket bucket : bucketList.getBuckets()) { if (bucket.getLabel().equals(bucketLabel)) { return Optional.of(bucket); } } return rBucket; }
int bucketListSize = bucketList.getBuckets().size(); StringBuilder SQL = new StringBuilder("UPDATE bucket SET "); List<String> args = new ArrayList<>(bucketListSize); if (bucketList.getBuckets().get(i).getState() != null) { hasval = true; break; SQL.append("state = CASE label "); for (int i = 0; i < bucketListSize; i++) { Bucket b = bucketList.getBuckets().get(i); if (b.getState() != null) { SQL.append("WHEN ? then ? "); if (bucketList.getBuckets().get(i).getAllocationPercent() != null) { hasval = true; break; SQL.append("allocation_percent = CASE label "); for (int i = 0; i < bucketListSize; i++) { Bucket b = bucketList.getBuckets().get(i); if (b.getAllocationPercent() != null) { SQL.append("WHEN ? then ? "); if (bucketList.getBuckets().get(i).isControl() != null) { hasval = true; break; SQL.append("is_control = CASE label ");
/** * {@inheritDoc} */ @Override public BucketList combineOldAndNewBuckets(BucketList oldBuckets, BucketList newBuckets) { BucketList allBuckets = new BucketList(); for (Bucket b : oldBuckets.getBuckets()) { Boolean changed = false; for (Bucket bb : newBuckets.getBuckets()) { if (bb.getLabel().equals(b.getLabel())) { allBuckets.addBucket(bb); changed = true; break; } } if (!changed) { allBuckets.addBucket(b); } } return allBuckets; } }
for (int i = 0; i < bucketList.getBuckets().size(); i++) { Bucket b = bucketList.getBuckets().get(i); CQL += "UPDATE bucket SET "; if (b.getState() != null) {
if ((Objects.isNull(bucketList) || bucketList.getBuckets().isEmpty()) && !skipBucketRetrieval) { bucketList = getBucketList(experiment.getID());
for (Bucket bucket : bucketList.getBuckets()) { for (Bucket b : oldBuckets.getBuckets()) { if (b.getLabel().equals(bucket.getLabel())) { oldBucket = b; if (!changeBucketList.getBuckets().isEmpty()) { allBuckets = buckets.combineOldAndNewBuckets(oldBuckets, changeBucketList); validator.validateExperimentBuckets(allBuckets.getBuckets()); cassandraRepository.logBucketChanges(experimentID, changeBucketList.getBuckets().get(i).getLabel(), allChanges.get(i)); eventLog.postEvent(new BucketChangeEvent(user, experiment, changeBucketList.getBuckets().get(i), bucketAuditInfo.getAttributeName(), bucketAuditInfo.getOldValue(), bucketAuditInfo.getNewValue()));
experiment.setBuckets(bucketList.getBuckets()); experiment.setExclusionIdList(exclusionIdList);
/** * {@inheritDoc} */ @Override public void checkStateTransition(Experiment.ID experimentID, Experiment.State currentState, Experiment.State desiredState) { if (desiredState != null && !currentState.equals(desiredState)) { // Throw an exception if the StateTransition is invalid validator.validateStateTransition(currentState, desiredState); /* If moving from a DRAFT state to a RUNNING state a sanity-check is required on the experiment buckets. Fetch the bucket information if the experiment will be (or remain) in an active state (running, paused) because that info is used to create the KV-store entry. * */ if (currentState.equals(DRAFT) && desiredState.equals(RUNNING)) { // Throw an exception if the sanity-check fails BucketList bucketList = buckets.getBuckets(experimentID, false /* don't check experiment again */); validator.validateExperimentBuckets(bucketList.getBuckets()); } } }
boolean isBucketEmpty = false; String bucketLabel = userAssignments.row(experimentID).values().iterator().next(); for (Bucket b : bucketList.getBuckets()) { if (bucketLabel.equals(b.getLabel().toString())) { if (b.getState() == Bucket.State.EMPTY) {
if (Objects.isNull(bucketsExternal) || bucketsExternal.getBuckets().isEmpty()) { assignedBucket = selectBucket(bucketList.getBuckets()); } else { assignedBucket = selectBucket(bucketsExternal.getBuckets());
for (Bucket buck : bucketList.getBuckets()) { if (!buck.getLabel().equals(bucket.getLabel()) && buck.getState() == Bucket.State.OPEN) { for (int i = 0; i < bucketList.getBuckets().size(); i++) { Bucket buck = bucketList.getBuckets().get(i); List<Bucket.BucketAuditInfo> changeList = new ArrayList<>(); validator.validateExperimentBuckets(newBuckets.getBuckets()); for (int i = 0; i < bucketList.getBuckets().size(); i++) { cassandraRepository.logBucketChanges(experimentID, bucketList.getBuckets().get(i).getLabel(), allChanges.get(i)); for (Bucket.BucketAuditInfo bucketAuditInfo : allChanges.get(i)) { if (!Experiment.State.DRAFT.equals(experiment.getState()) && !(Objects.equals(bucketAuditInfo.getOldValue(), bucketAuditInfo.getNewValue()))) { EventLogEvent event = new BucketChangeEvent(user, experiment, bucketList.getBuckets().get(i), bucketAuditInfo.getAttributeName(), bucketAuditInfo.getOldValue(), bucketAuditInfo.getNewValue()); for (Bucket buck : updates.getBuckets()) { if (buck.getLabel().equals(bucket.getLabel())) { return buck;
/** * {@inheritDoc} */ @Override public BucketList adjustAllocationPercentages(Experiment experiment, Bucket newBucket) { double remainingAlloc = 1. - newBucket.getAllocationPercent(); BucketList bucketList = buckets.getBuckets(experiment.getID(), false /* don't check experiment again */); BucketList newBuckets = new BucketList(); for (Bucket bucket : bucketList.getBuckets()) { if (bucket.getLabel().equals(newBucket.getLabel())) { continue; } double newAlloc = roundToTwo(remainingAlloc * bucket.getAllocationPercent()); LOGGER.debug("Add Bucket: setting allocation percentage for bucket " + bucket.getLabel() + " in experiment " + experiment.getID() + " to: " + newAlloc); Bucket.Builder builder = Bucket.from(bucket).withAllocationPercent(newAlloc); Bucket updatedBucket = builder.build(); newBuckets.addBucket(updatedBucket); if (!Experiment.State.DRAFT.equals(experiment.getState()) && Double.compare(bucket.getAllocationPercent(), updatedBucket.getAllocationPercent()) != 0) { // this is a system event, so no user needed eventLog.postEvent(new BucketChangeEvent(experiment, updatedBucket, "allocation", String.valueOf(bucket.getAllocationPercent()), String.valueOf(updatedBucket.getAllocationPercent()))); } } return newBuckets; }
BucketList buckets = getBucketList(experimentID); Boolean bucketFound = false; for (Bucket bucket : buckets.getBuckets()) { if (bucket.getLabel().equals(desiredBucketLabel) && !bucket.getState().equals(Bucket.State.EMPTY)) { bucketFound = true;