1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2024-10-30 11:46:16 +00:00
mycorrhiza/hyphae/hyphae.go

120 lines
2.6 KiB
Go
Raw Normal View History

2021-05-11 10:14:00 +00:00
// Package hyphae is for the Hypha type, hypha storage and stuff like that. It shall not depend on mycorrhiza modules other than util.
package hyphae
import (
2021-07-30 14:16:58 +00:00
"github.com/bouncepaw/mycorrhiza/files"
2021-02-17 18:41:35 +00:00
"log"
2021-07-30 14:16:58 +00:00
"path/filepath"
2021-02-17 18:41:35 +00:00
"regexp"
"sync"
)
2021-02-17 18:41:35 +00:00
// HyphaPattern is a pattern which all hyphae must match.
2021-05-11 10:14:00 +00:00
var HyphaPattern = regexp.MustCompile(`[^?!:#@><*|"'&%{}]+`)
2021-02-17 18:41:35 +00:00
type Hypha struct {
sync.RWMutex
2021-03-14 13:16:30 +00:00
Name string // Canonical name
Exists bool
2021-03-14 13:16:30 +00:00
TextPath string // == "" => no text part
BinaryPath string // == "" => no attachment
2021-02-17 18:41:35 +00:00
}
2021-07-30 14:16:58 +00:00
// TextPartPath returns rooted path to the file where the text part should be.
func (h *Hypha) TextPartPath() string {
if h.TextPath == "" {
return filepath.Join(files.HyphaeDir(), h.Name+".myco")
}
return h.TextPath
}
2021-02-17 18:41:35 +00:00
var byNames = make(map[string]*Hypha)
var byNamesMutex = sync.Mutex{}
// EmptyHypha returns an empty hypha struct with given name.
func EmptyHypha(hyphaName string) *Hypha {
return &Hypha{
Name: hyphaName,
Exists: false,
TextPath: "",
BinaryPath: "",
}
}
2021-03-14 13:16:30 +00:00
// ByName returns a hypha by name. It may have been recorded to the storage.
2021-02-17 18:41:35 +00:00
func ByName(hyphaName string) (h *Hypha) {
2021-03-14 13:16:30 +00:00
h, recorded := byNames[hyphaName]
if recorded {
2021-02-17 18:41:35 +00:00
return h
}
return EmptyHypha(hyphaName)
}
2021-03-14 13:16:30 +00:00
func storeHypha(h *Hypha) {
2021-02-17 18:41:35 +00:00
byNamesMutex.Lock()
2021-03-14 13:16:30 +00:00
byNames[h.Name] = h
byNamesMutex.Unlock()
2021-03-14 15:20:02 +00:00
h.Lock()
h.Exists = true
h.Unlock()
2021-03-14 13:16:30 +00:00
}
// Insert inserts the hypha into the storage. A previous record is used if possible. Count incrementation is done if needed.
func (h *Hypha) Insert() (justRecorded bool) {
hp, recorded := byNames[h.Name]
if recorded {
hp.MergeIn(h)
2021-02-17 18:41:35 +00:00
} else {
2021-03-14 13:16:30 +00:00
storeHypha(h)
IncrementCount()
}
2021-03-14 13:16:30 +00:00
return !recorded
2021-02-17 18:41:35 +00:00
}
2021-03-14 13:16:30 +00:00
func (h *Hypha) InsertIfNew() (justRecorded bool) {
if !h.Exists {
2021-02-17 18:41:35 +00:00
return h.Insert()
}
return false
}
2021-02-20 14:03:54 +00:00
func (h *Hypha) Delete() {
2021-02-17 18:41:35 +00:00
byNamesMutex.Lock()
h.Lock()
delete(byNames, h.Name)
DecrementCount()
byNamesMutex.Unlock()
h.Unlock()
}
2021-02-20 14:03:54 +00:00
func (h *Hypha) RenameTo(newName string) {
2021-02-17 18:41:35 +00:00
byNamesMutex.Lock()
h.Lock()
2021-02-17 18:41:35 +00:00
delete(byNames, h.Name)
h.Name = newName
byNames[h.Name] = h
byNamesMutex.Unlock()
h.Unlock()
}
2021-02-17 18:41:35 +00:00
// MergeIn merges in content file paths from a different hypha object. Prints warnings sometimes.
func (h *Hypha) MergeIn(oh *Hypha) {
2021-03-14 13:16:30 +00:00
if h == oh {
return
}
h.Lock()
2021-02-17 18:41:35 +00:00
if h.TextPath == "" && oh.TextPath != "" {
h.TextPath = oh.TextPath
}
if oh.BinaryPath != "" {
if h.BinaryPath != "" {
log.Println("There is a file collision for attachment of a hypha:", h.BinaryPath, "and", oh.BinaryPath, "-- going on with the latter")
2021-02-17 18:41:35 +00:00
}
h.BinaryPath = oh.BinaryPath
}
2021-03-14 13:16:30 +00:00
h.Unlock()
2021-03-02 16:36:57 +00:00
}