89 lines
1.6 KiB
Go
89 lines
1.6 KiB
Go
package index
|
|
|
|
import (
|
|
"sort"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type Entry struct {
|
|
Hash string `json:"hash"`
|
|
Bytes int64 `json:"bytes"`
|
|
StoredAt string `json:"stored_at"`
|
|
Private bool `json:"private"`
|
|
CreatorTZ string `json:"creator_tz,omitempty"`
|
|
}
|
|
|
|
type rec struct {
|
|
Hash string
|
|
Bytes int64
|
|
StoredAt time.Time
|
|
Private bool
|
|
CreatorTZ string
|
|
}
|
|
|
|
type Index struct {
|
|
mu sync.RWMutex
|
|
hash map[string]rec
|
|
}
|
|
|
|
func New() *Index { return &Index{hash: make(map[string]rec)} }
|
|
|
|
func (ix *Index) Put(e Entry) error {
|
|
ix.mu.Lock()
|
|
defer ix.mu.Unlock()
|
|
t := parseWhen(e.StoredAt)
|
|
if t.IsZero() {
|
|
t = time.Now().UTC()
|
|
}
|
|
ix.hash[e.Hash] = rec{
|
|
Hash: e.Hash,
|
|
Bytes: e.Bytes,
|
|
StoredAt: t,
|
|
Private: e.Private,
|
|
CreatorTZ: e.CreatorTZ,
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (ix *Index) Delete(hash string) error {
|
|
ix.mu.Lock()
|
|
defer ix.mu.Unlock()
|
|
delete(ix.hash, hash)
|
|
return nil
|
|
}
|
|
|
|
func (ix *Index) List() ([]Entry, error) {
|
|
ix.mu.RLock()
|
|
defer ix.mu.RUnlock()
|
|
tmp := make([]rec, 0, len(ix.hash))
|
|
for _, r := range ix.hash {
|
|
tmp = append(tmp, r)
|
|
}
|
|
sort.Slice(tmp, func(i, j int) bool { return tmp[i].StoredAt.After(tmp[j].StoredAt) })
|
|
out := make([]Entry, len(tmp))
|
|
for i, r := range tmp {
|
|
out[i] = Entry{
|
|
Hash: r.Hash,
|
|
Bytes: r.Bytes,
|
|
StoredAt: r.StoredAt.UTC().Format(time.RFC3339Nano),
|
|
Private: r.Private,
|
|
CreatorTZ: r.CreatorTZ,
|
|
}
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
func parseWhen(s string) time.Time {
|
|
if s == "" {
|
|
return time.Time{}
|
|
}
|
|
if t, err := time.Parse(time.RFC3339Nano, s); err == nil {
|
|
return t
|
|
}
|
|
if t, err := time.Parse(time.RFC3339, s); err == nil {
|
|
return t
|
|
}
|
|
return time.Time{}
|
|
}
|