package com.ldbc.driver.workloads.ldbc.snb.interactive; import com.ldbc.driver.Operation; import com.ldbc.driver.Workload.DbValidationParametersFilter; import com.ldbc.driver.Workload.DbValidationParametersFilterAcceptance; import com.ldbc.driver.Workload.DbValidationParametersFilterResult; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; class LdbcSnbInteractiveDbValidationParametersFilter implements DbValidationParametersFilter { private final Set<Class> multiResultOperations; private final Map<Class, Long> remainingRequiredResultsPerWriteType; private final Map<Class, Long> remainingRequiredResultsPerLongReadType; private final Set<Class> enabledShortReadOperationTypes; private long writeAddPersonOperationCount; private int uncompletedShortReads; LdbcSnbInteractiveDbValidationParametersFilter(Set<Class> multiResultOperations, long writeAddPersonOperationCount, Map<Class, Long> remainingRequiredResultsPerWriteType, Map<Class, Long> remainingRequiredResultsPerLongReadType, Set<Class> enabledShortReadOperationTypes) { this.multiResultOperations = multiResultOperations; this.writeAddPersonOperationCount = writeAddPersonOperationCount; this.remainingRequiredResultsPerWriteType = remainingRequiredResultsPerWriteType; this.remainingRequiredResultsPerLongReadType = remainingRequiredResultsPerLongReadType; this.enabledShortReadOperationTypes = enabledShortReadOperationTypes; this.uncompletedShortReads = 0; } @Override public boolean useOperation(Operation operation) { Class operationType = operation.getClass(); if (enabledShortReadOperationTypes.contains(operationType)) { return true; } else if (operationType.equals(LdbcUpdate1AddPerson.class)) { return writeAddPersonOperationCount > 0; } else if (remainingRequiredResultsPerWriteType.containsKey(operationType)) { return false == haveCompletedAllRequiredResultsPerOperationType(remainingRequiredResultsPerWriteType); } else if (remainingRequiredResultsPerLongReadType.containsKey(operationType)) { return remainingRequiredResultsPerLongReadType.get(operationType) > 0; } else { // disabled operation return false; } } @Override public DbValidationParametersFilterResult useOperationAndResultForValidation(Operation operation, Object operationResult) { Class operationType = operation.getClass(); List<Operation> injectedOperations = new ArrayList<>(); // do not use empty results for validation if (multiResultOperations.contains(operationType) && ((List) operationResult).isEmpty()) { return new DbValidationParametersFilterResult(DbValidationParametersFilterAcceptance.REJECT_AND_CONTINUE, injectedOperations); } injectedOperations.addAll(generateOperationsToInject(operation)); uncompletedShortReads += injectedOperations.size(); if (operationType.equals(LdbcUpdate1AddPerson.class)) { // writes do not return anything, but they should be executed and some default result needs to be stored in the validation parameters writeAddPersonOperationCount--; } else if (enabledShortReadOperationTypes.contains(operationType)) { // keep track of how many injected operations have completed (only short reads are injected) uncompletedShortReads--; } else if (remainingRequiredResultsPerWriteType.containsKey(operationType)) { // decrement count for write operation type remainingRequiredResultsPerWriteType.put(operationType, Math.max(0, remainingRequiredResultsPerWriteType.get(operationType) - 1)); } else if (remainingRequiredResultsPerLongReadType.containsKey(operationType)) { // decrement count for long read operation type remainingRequiredResultsPerLongReadType.put(operationType, remainingRequiredResultsPerLongReadType.get(operationType) - 1); } else { throw new RuntimeException("Unexpected operation type: " + operationType.getSimpleName()); } if (validationParameterGenerationFinished()) { return new DbValidationParametersFilterResult(DbValidationParametersFilterAcceptance.ACCEPT_AND_FINISH, injectedOperations); } else { return new DbValidationParametersFilterResult(DbValidationParametersFilterAcceptance.ACCEPT_AND_CONTINUE, injectedOperations); } } private boolean validationParameterGenerationFinished() { // check that all writes have completed if (false == haveCompletedAllRequiredResultsPerOperationType(remainingRequiredResultsPerWriteType)) { return false; } // check that all long reads have completed if (false == haveCompletedAllRequiredResultsPerOperationType(remainingRequiredResultsPerLongReadType)) { return false; } // check that all Add Person writes have completed if (writeAddPersonOperationCount > 0) { return false; } // check that all short reads have completed if (uncompletedShortReads > 0) { return false; } // we're done return true; } private boolean haveCompletedAllRequiredResultsPerOperationType(Map<Class, Long> requiredResultsPerOperationType) { for (Long value : requiredResultsPerOperationType.values()) { if (value > 0) return false; } return true; } private List<Operation> generateOperationsToInject(Operation operation) { List<Operation> operationsToInject = new ArrayList<>(); switch (operation.type()) { case LdbcUpdate1AddPerson.TYPE: { injectShort1(operationsToInject, ((LdbcUpdate1AddPerson) operation).personId()); injectShort2(operationsToInject, ((LdbcUpdate1AddPerson) operation).personId()); injectShort3(operationsToInject, ((LdbcUpdate1AddPerson) operation).personId()); break; } case LdbcUpdate2AddPostLike.TYPE: { injectShort1(operationsToInject, ((LdbcUpdate2AddPostLike) operation).personId()); injectShort2(operationsToInject, ((LdbcUpdate2AddPostLike) operation).personId()); injectShort3(operationsToInject, ((LdbcUpdate2AddPostLike) operation).personId()); injectShort4(operationsToInject, ((LdbcUpdate2AddPostLike) operation).postId()); injectShort5(operationsToInject, ((LdbcUpdate2AddPostLike) operation).postId()); injectShort6(operationsToInject, ((LdbcUpdate2AddPostLike) operation).postId()); injectShort7(operationsToInject, ((LdbcUpdate2AddPostLike) operation).postId()); break; } case LdbcUpdate3AddCommentLike.TYPE: { injectShort1(operationsToInject, ((LdbcUpdate3AddCommentLike) operation).personId()); injectShort2(operationsToInject, ((LdbcUpdate3AddCommentLike) operation).personId()); injectShort3(operationsToInject, ((LdbcUpdate3AddCommentLike) operation).personId()); injectShort4(operationsToInject, ((LdbcUpdate3AddCommentLike) operation).commentId()); injectShort5(operationsToInject, ((LdbcUpdate3AddCommentLike) operation).commentId()); injectShort6(operationsToInject, ((LdbcUpdate3AddCommentLike) operation).commentId()); injectShort7(operationsToInject, ((LdbcUpdate3AddCommentLike) operation).commentId()); break; } case LdbcUpdate4AddForum.TYPE: { injectShort1(operationsToInject, ((LdbcUpdate4AddForum) operation).moderatorPersonId()); injectShort2(operationsToInject, ((LdbcUpdate4AddForum) operation).moderatorPersonId()); injectShort3(operationsToInject, ((LdbcUpdate4AddForum) operation).moderatorPersonId()); break; } case LdbcUpdate5AddForumMembership.TYPE: { injectShort1(operationsToInject, ((LdbcUpdate5AddForumMembership) operation).personId()); injectShort2(operationsToInject, ((LdbcUpdate5AddForumMembership) operation).personId()); injectShort3(operationsToInject, ((LdbcUpdate5AddForumMembership) operation).personId()); break; } case LdbcUpdate6AddPost.TYPE: { injectShort1(operationsToInject, ((LdbcUpdate6AddPost) operation).authorPersonId()); injectShort2(operationsToInject, ((LdbcUpdate6AddPost) operation).authorPersonId()); injectShort3(operationsToInject, ((LdbcUpdate6AddPost) operation).authorPersonId()); injectShort4(operationsToInject, ((LdbcUpdate6AddPost) operation).postId()); injectShort5(operationsToInject, ((LdbcUpdate6AddPost) operation).postId()); injectShort6(operationsToInject, ((LdbcUpdate6AddPost) operation).postId()); injectShort7(operationsToInject, ((LdbcUpdate6AddPost) operation).postId()); break; } case LdbcUpdate7AddComment.TYPE: { injectShort1(operationsToInject, ((LdbcUpdate7AddComment) operation).authorPersonId()); injectShort2(operationsToInject, ((LdbcUpdate7AddComment) operation).authorPersonId()); injectShort3(operationsToInject, ((LdbcUpdate7AddComment) operation).authorPersonId()); injectShort4(operationsToInject, ((LdbcUpdate7AddComment) operation).commentId()); injectShort5(operationsToInject, ((LdbcUpdate7AddComment) operation).commentId()); injectShort6(operationsToInject, ((LdbcUpdate7AddComment) operation).commentId()); injectShort7(operationsToInject, ((LdbcUpdate7AddComment) operation).commentId()); break; } case LdbcUpdate8AddFriendship.TYPE: { injectShort1(operationsToInject, ((LdbcUpdate8AddFriendship) operation).person1Id()); injectShort2(operationsToInject, ((LdbcUpdate8AddFriendship) operation).person1Id()); injectShort3(operationsToInject, ((LdbcUpdate8AddFriendship) operation).person1Id()); injectShort1(operationsToInject, ((LdbcUpdate8AddFriendship) operation).person2Id()); injectShort2(operationsToInject, ((LdbcUpdate8AddFriendship) operation).person2Id()); injectShort3(operationsToInject, ((LdbcUpdate8AddFriendship) operation).person2Id()); break; } } return operationsToInject; } private void injectShort1(List<Operation> operationsToInject, long personId) { if (enabledShortReadOperationTypes.contains(LdbcShortQuery1PersonProfile.class)) { operationsToInject.add( new LdbcShortQuery1PersonProfile(personId) ); } } private void injectShort2(List<Operation> operationsToInject, long personId) { if (enabledShortReadOperationTypes.contains(LdbcShortQuery2PersonPosts.class)) { operationsToInject.add( new LdbcShortQuery2PersonPosts(personId, LdbcShortQuery2PersonPosts.DEFAULT_LIMIT) ); } } private void injectShort3(List<Operation> operationsToInject, long personId) { if (enabledShortReadOperationTypes.contains(LdbcShortQuery3PersonFriends.class)) { operationsToInject.add( new LdbcShortQuery3PersonFriends(personId) ); } } private void injectShort4(List<Operation> operationsToInject, long messageId) { if (enabledShortReadOperationTypes.contains(LdbcShortQuery4MessageContent.class)) { operationsToInject.add( new LdbcShortQuery4MessageContent(messageId) ); } } private void injectShort5(List<Operation> operationsToInject, long messageId) { if (enabledShortReadOperationTypes.contains(LdbcShortQuery5MessageCreator.class)) { operationsToInject.add( new LdbcShortQuery5MessageCreator(messageId) ); } } private void injectShort6(List<Operation> operationsToInject, long messageId) { if (enabledShortReadOperationTypes.contains(LdbcShortQuery6MessageForum.class)) { operationsToInject.add( new LdbcShortQuery6MessageForum(messageId) ); } } private void injectShort7(List<Operation> operationsToInject, long messageId) { if (enabledShortReadOperationTypes.contains(LdbcShortQuery7MessageReplies.class)) { operationsToInject.add( new LdbcShortQuery7MessageReplies(messageId) ); } } }