Skip to content

Instantly share code, notes, and snippets.

@madflojo
Created September 3, 2022 18:15
Show Gist options
  • Save madflojo/7fd095c0a18af09bbe73c15b8d3bf8f2 to your computer and use it in GitHub Desktop.
Save madflojo/7fd095c0a18af09bbe73c15b8d3bf8f2 to your computer and use it in GitHub Desktop.
Threadsafe Packages - final
/*
Package directory is an example package that creates an internal directory for People.
This package is an example used for a Blog article and is not for anything else.
*/
package directory
import (
"fmt"
"sync"
)
// Person represents a person and their attributes.
type Person struct {
// Age represents the persons Age
Age int
// Name represents the persons Name
Name string
}
// Directory provides the ability to store and lookup people.
type Directory struct {
sync.RWMutex
// directory stores known People
directory map[string]Person
// name is used to identify the Directory instance
name string
}
// New is used to create a new instance of Directory.
func New(name string) (*Directory, error) {
d := &Directory{}
// Validate Name
if name == "" {
return d, fmt.Errorf("cannot have an empty name")
}
d.name = name
// Create new map
d.directory = make(map[string]Person)
return d, nil
}
// Name will return the current Directory name.
func (d *Directory) Name() string {
d.RLock()
defer d.RUnlock()
return d.name
}
// SetName will change the name of the current Directory.
func (d *Directory) SetName(n string) error {
if n == "" {
return fmt.Errorf("cannot have an empty name")
}
d.Lock()
defer d.Unlock()
d.name = n
return nil
}
// Add will add a person to the internal directory.
func (d *Directory) Add(p Person) error {
if p.Name == "" {
return fmt.Errorf("name cannot be empty")
}
d.Lock()
defer d.Unlock()
// Guess we can't have two people with the same name...
d.directory[p.Name] = p
return nil
}
// Lookup will find and return a person. If the provided person does not exist, Lookup will return
// an error.
func (d *Directory) Lookup(name string) (Person, error) {
d.RLock()
defer d.RUnlock()
p, ok := d.directory[name]
if ok {
return p, nil
}
return Person{}, fmt.Errorf("could not find person")
}
// Directory will return a map of all people stored within the Directory.
func (d *Directory) Directory() map[string]Person {
d.RLock()
defer d.RUnlock()
m := make(map[string]Person)
for k, v := range d.directory {
m[k] = v
}
return m
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment