lock around read operations in graph

Writes and reads will fail with ErrBusy if there's
concurrent reads or writes, respectively. It is
not sufficient to only lock around writes.
This commit is contained in:
Daniel Norberg 2013-11-05 18:26:07 -05:00
parent 980eda4c25
commit 1dc34e2b96
1 changed files with 23 additions and 1 deletions

View File

@ -138,7 +138,14 @@ func (db *Database) Set(fullPath, id string) (*Entity, error) {
// Return true if a name already exists in the database // Return true if a name already exists in the database
func (db *Database) Exists(name string) bool { func (db *Database) Exists(name string) bool {
return db.Get(name) != nil db.mux.Lock()
defer db.mux.Unlock()
e, err := db.get(name)
if err != nil {
return false
}
return e != nil
} }
func (db *Database) setEdge(parentPath, name string, e *Entity) error { func (db *Database) setEdge(parentPath, name string, e *Entity) error {
@ -165,6 +172,9 @@ func (db *Database) RootEntity() *Entity {
// Return the entity for a given path // Return the entity for a given path
func (db *Database) Get(name string) *Entity { func (db *Database) Get(name string) *Entity {
db.mux.Lock()
defer db.mux.Unlock()
e, err := db.get(name) e, err := db.get(name)
if err != nil { if err != nil {
return nil return nil
@ -200,6 +210,9 @@ func (db *Database) get(name string) (*Entity, error) {
// List all entities by from the name // List all entities by from the name
// The key will be the full path of the entity // The key will be the full path of the entity
func (db *Database) List(name string, depth int) Entities { func (db *Database) List(name string, depth int) Entities {
db.mux.Lock()
defer db.mux.Unlock()
out := Entities{} out := Entities{}
e, err := db.get(name) e, err := db.get(name)
if err != nil { if err != nil {
@ -212,6 +225,9 @@ func (db *Database) List(name string, depth int) Entities {
} }
func (db *Database) Walk(name string, walkFunc WalkFunc, depth int) error { func (db *Database) Walk(name string, walkFunc WalkFunc, depth int) error {
db.mux.Lock()
defer db.mux.Unlock()
e, err := db.get(name) e, err := db.get(name)
if err != nil { if err != nil {
return err return err
@ -226,6 +242,9 @@ func (db *Database) Walk(name string, walkFunc WalkFunc, depth int) error {
// Return the refrence count for a specified id // Return the refrence count for a specified id
func (db *Database) Refs(id string) int { func (db *Database) Refs(id string) int {
db.mux.Lock()
defer db.mux.Unlock()
var count int var count int
if err := db.conn.QueryRow("SELECT COUNT(*) FROM edge WHERE entity_id = ?;", id).Scan(&count); err != nil { if err := db.conn.QueryRow("SELECT COUNT(*) FROM edge WHERE entity_id = ?;", id).Scan(&count); err != nil {
return 0 return 0
@ -235,6 +254,9 @@ func (db *Database) Refs(id string) int {
// Return all the id's path references // Return all the id's path references
func (db *Database) RefPaths(id string) Edges { func (db *Database) RefPaths(id string) Edges {
db.mux.Lock()
defer db.mux.Unlock()
refs := Edges{} refs := Edges{}
rows, err := db.conn.Query("SELECT name, parent_id FROM edge WHERE entity_id = ?;", id) rows, err := db.conn.Query("SELECT name, parent_id FROM edge WHERE entity_id = ?;", id)