Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // +build !solution
- package singlepaxos
- // Learner represents a learner as defined by the single-decree Paxos
- // algorithm.
- type Learner struct {
- //TODO(student): Task 2 and 3 - algorithm and distributed implementation
- // Add needed fields
- id int
- nrOfNodes int
- greatestRound Round
- mv map[int]bool
- // Count frequency of words
- freq map[Value]int
- }
- // NewLearner returns a new single-decree Paxos learner. It takes the
- // following arguments:
- //
- // id: The id of the node running this instance of a Paxos learner.
- //
- // nrOfNodes: The total number of Paxos nodes.
- //
- // valueOut: A send only channel used to send values that has been learned,
- // i.e. decided by the Paxos nodes.
- func NewLearner(id int, nrOfNodes int, valueOut chan<- Value) *Learner {
- //TODO(student): Task 2 and 3 - algorithm and distributed implementation
- return &Learner{id: id, nrOfNodes: nrOfNodes, greatestRound: Round(-1)}
- }
- // Start starts l's main run loop as a separate goroutine. The main run loop
- // handles incoming learn messages.
- func (l *Learner) Start() {
- go func() {
- for {
- //TODO(student): Task 3 - distributed implementation
- }
- }()
- }
- // Stop stops l's main run loop.
- func (l *Learner) Stop() {
- //TODO(student): Task 3 - distributed implementation
- }
- // DeliverLearn delivers learn lrn to learner l.
- func (l *Learner) DeliverLearn(lrn Learn) {
- //TODO(student): Task 3 - distributed implementation
- }
- // Internal: handleLearn processes learn lrn according to the single-decree
- // Paxos algorithm. If handling the learn results in learner l emitting a
- // corresponding decided value, then output will be true and val contain the
- // decided value. If handleLearn returns false as output, then val will have
- // its zero value.
- func (l *Learner) handleLearn(learn Learn) (val Value, output bool) {
- //TODO(student): Task 2 - algorithm implementation
- // Ignores smaller rounds
- if learn.Rnd < l.greatestRound {
- return ZeroValue, false
- }
- if _, ok := l.mv[learn.From]; ok {
- return ZeroValue, false
- }
- // Clears map and increases greates round if a
- // higher round arrives
- if learn.Rnd > l.greatestRound {
- l.greatestRound = learn.Rnd
- l.mv = make(map[int]bool)
- l.freq = make(map[Value]int)
- }
- // Add valid node
- l.mv[learn.From] = true
- if _, ok := l.freq[learn.Val]; ok {
- l.freq[learn.Val] = l.freq[learn.Val] + 1
- } else {
- l.freq[learn.Val] = 1
- }
- if len(l.mv) > (l.nrOfNodes / 2) {
- val := l.findVal()
- if val == "" {
- return "", false
- }
- return val, true
- }
- return ZeroValue, false
- }
- //TODO(student): Add any other unexported methods needed.
- func (l *Learner) findVal() Value {
- for val, freq := range l.freq {
- if freq > l.nrOfNodes/2 {
- return val
- }
- }
- return ""
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement