blob: 69b2747536a3733ed7a86f5405729c61c048680c [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package pkg
import (
"fmt"
"sync"
)
// PackageSet is a concurrency-safe set collection of Packages
type PackageSet struct {
mu sync.Mutex
pkgs []*Package
}
// NewPackageSet initializes a PackageSet struct
func NewPackageSet() *PackageSet {
return &PackageSet{
pkgs: []*Package{},
mu: sync.Mutex{},
}
}
// Add adds a package to our list of packages.
func (r *PackageSet) Add(pkg *Package) {
r.mu.Lock()
defer r.mu.Unlock()
r.pkgs = append(r.pkgs, pkg)
}
// Remove removes a package from our list of packages.
func (r *PackageSet) Remove(pkg *Package) error {
r.mu.Lock()
defer r.mu.Unlock()
return r.remove(pkg)
}
func (r *PackageSet) remove(pkg *Package) error {
for i := range r.pkgs {
if *r.pkgs[i] == *pkg {
r.pkgs = append(r.pkgs[:i], r.pkgs[i+1:]...)
return nil
}
}
return fmt.Errorf("Requested package not found")
}
// Replace does an atomic swap. If insertNew is set to true the 'new' Package
// will be added to the PackageSet even if 'old' is not currently in the set.
func (r *PackageSet) Replace(old *Package, new *Package, insertNew bool) error {
r.mu.Lock()
defer r.mu.Unlock()
err := r.remove(old)
if err == nil || insertNew {
r.pkgs = append(r.pkgs, new)
}
if insertNew {
return nil
}
return err
}
// Packages returns copy of the list of Packages
func (r *PackageSet) Packages() []*Package {
r.mu.Lock()
c := make([]*Package, len(r.pkgs))
copy(c, r.pkgs)
r.mu.Unlock()
return c
}