[ https://issues.apache.org/jira/browse/GOSSIP-75?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16110151#comment-16110151 ]
ASF GitHub Bot commented on GOSSIP-75: -------------------------------------- Github user edwardcapriolo commented on a diff in the pull request: https://github.com/apache/incubator-gossip/pull/62#discussion_r130772757 --- Diff: gossip-base/src/main/java/org/apache/gossip/lock/vote/MajorityVote.java --- @@ -0,0 +1,161 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.gossip.lock.vote; + +import org.apache.gossip.crdt.Crdt; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +public class MajorityVote implements Crdt<Map<String, VoteCandidate>, MajorityVote> { + + private final Map<String, VoteCandidate> voteCandidates = new ConcurrentHashMap<>(); + + public MajorityVote(Map<String, VoteCandidate> voteCandidateMap){ + voteCandidates.putAll(voteCandidateMap); + } + + @Override + public MajorityVote merge(MajorityVote other) { + Map<String, VoteCandidate> mergedCandidates = new ConcurrentHashMap<>(); + Set<String> firstKeySet = this.voteCandidates.keySet(); + Set<String> secondKeySet = other.voteCandidates.keySet(); + Set<String> sameCandidatesSet = getIntersection(firstKeySet,secondKeySet); + Set<String> differentCandidatesSet = getIntersectionCompliment(firstKeySet,secondKeySet); + + for (String differentCandidateId:differentCandidatesSet) { + if (this.voteCandidates.containsKey(differentCandidateId)) { + mergedCandidates.put(differentCandidateId, this.voteCandidates.get(differentCandidateId)); + } else if (other.voteCandidates.containsKey(differentCandidateId)) { + mergedCandidates.put(differentCandidateId, other.voteCandidates.get(differentCandidateId)); + } + } + + for (String sameCandidateId:sameCandidatesSet) { + if (this.voteCandidates.containsKey(sameCandidateId) + && other.voteCandidates.containsKey(sameCandidateId)) { + mergedCandidates.put(sameCandidateId, mergeCandidate( + this.voteCandidates.get(sameCandidateId), other.voteCandidates.get(sameCandidateId))); + } + } + + return new MajorityVote(mergedCandidates); + } + + private VoteCandidate mergeCandidate(VoteCandidate firstCandidate,VoteCandidate secondCandidate){ + VoteCandidate mergeResult = new VoteCandidate(firstCandidate.getCandidateNodeId(), + firstCandidate.getVotingKey(),new ConcurrentHashMap<>()); + Set<String> firstKeySet = firstCandidate.getVotes().keySet(); + Set<String> secondKeySet = secondCandidate.getVotes().keySet(); + Set<String> sameVoteNodeSet = getIntersection(firstKeySet,secondKeySet); + Set<String> differentVoteNodeSet = getIntersectionCompliment(firstKeySet,secondKeySet); + + for (String differentCandidateId:differentVoteNodeSet) { + if (firstCandidate.getVotes().containsKey(differentCandidateId)) { + mergeResult.getVotes().put(differentCandidateId, firstCandidate.getVotes().get(differentCandidateId)); + } else if (secondCandidate.getVotes().containsKey(differentCandidateId)) { + mergeResult.getVotes().put(differentCandidateId, secondCandidate.getVotes().get(differentCandidateId)); + } + } + + for (String sameVoteNodeId:sameVoteNodeSet) { + if (firstCandidate.getVotes().containsKey(sameVoteNodeId) + && secondCandidate.getVotes().containsKey(sameVoteNodeId)) { + mergeResult.getVotes().put(sameVoteNodeId, mergeVote( + firstCandidate.getVotes().get(sameVoteNodeId), secondCandidate.getVotes().get(sameVoteNodeId))); + } + } + + return mergeResult; + } + + private Vote mergeVote(Vote firstVote,Vote secondVote){ --- End diff -- Formatting > Voting interface > ---------------- > > Key: GOSSIP-75 > URL: https://issues.apache.org/jira/browse/GOSSIP-75 > Project: Gossip > Issue Type: New Feature > Reporter: Edward Capriolo > > Gossip has CRDT support. This is an important building block to doing higher > level things. The next piece is being able to act on an object when we > receive it. For example lets take the most simple case. I want the cluster to > vote on something such as "who asked for this lock first". Currently we > replicate objects lazily through a thread, what we want to do is on reception > of an object apply some function such that we can modify the object being > received. > The way I want to go about this is voting objects can be injected with a type > like VoteContext > http://stackoverflow.com/questions/27133161/how-to-pass-constructors-parameters-with-jackson > > Users can register Voter implementations. On receiving an object the > interface allows logic to be run. In the case of a Voting each node appends > its vote as the object moves around over time you can poll your local copy > and determine the result of the vote. -- This message was sent by Atlassian JIRA (v6.4.14#64029)