nuts-foundation/nuts-node

View on GitHub
network/transport/v2/gossip/set.go

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
/*
 * Nuts node
 * Copyright (C) 2022 Nuts community
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

package gossip

import (
    "container/list"

    "github.com/nuts-foundation/nuts-node/crypto/hash"
)

// uniqueList represents an ordered list where each element is unique
// it is not thread safe and only works for hash.SHA256Hash structs
type uniqueList struct {
    // list that holds the list items
    list *list.List
    // set contains the items from the list but as indexed set
    set map[string]*list.Element
}

// newUniqueList returns a new uniqueList with initialized list and set
func newUniqueList() *uniqueList {
    return &uniqueList{
        list: list.New(),
        set:  map[string]*list.Element{},
    }
}

// Len returns the size of the list
func (u *uniqueList) Len() int {
    return len(u.set)
}

// Add a value, it'll only be added if all conditions return true.
// A value is only added if new.
// condition checking is done within transactional context.
func (u *uniqueList) Add(ref hash.SHA256Hash) {
    if _, ok := u.set[ref.String()]; !ok {
        u.set[ref.String()] = u.list.PushBack(ref)
    }
}

// Remove a value
func (u *uniqueList) Remove(ref hash.SHA256Hash) {
    if element, ok := u.set[ref.String()]; ok {
        u.list.Remove(element)
        delete(u.set, ref.String())
    }
}

// RemoveFront the first value from the list.
func (u *uniqueList) RemoveFront() {
    if element := u.list.Front(); element != nil {
        data := element.Value.(hash.SHA256Hash)
        delete(u.set, data.String())
        u.list.Remove(element)
    }
}

// Contains returns true if the given key exists in the set.
func (u *uniqueList) Contains(value hash.SHA256Hash) bool {
    _, ok := u.set[value.String()]
    return ok
}

// Values returns all values in the ordered list
func (u *uniqueList) Values() []hash.SHA256Hash {
    refs := make([]hash.SHA256Hash, u.list.Len())

    i := 0
    for element := u.list.Front(); element != nil; element = element.Next() {
        refs[i] = element.Value.(hash.SHA256Hash)
        i++
    }
    return refs
}