105 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			105 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package storage
 | |
| 
 | |
| import (
 | |
| 	"errors"
 | |
| 	"io/ioutil"
 | |
| 	"os"
 | |
| 	"path/filepath"
 | |
| 	"strings"
 | |
| 	"sync"
 | |
| 
 | |
| 	"git.eeqj.de/sneak/feta/toot"
 | |
| )
 | |
| 
 | |
| // TootFSStorage is a TootStorageBackend that writes to the local
 | |
| // filesystem.
 | |
| type TootFSStorage struct {
 | |
| 	root string
 | |
| }
 | |
| 
 | |
| // NewTootFSStorage returns a *TootFSStorage for writing toots to the
 | |
| // local filesystem
 | |
| func NewTootFSStorage(root string) *TootFSStorage {
 | |
| 	ts := new(TootFSStorage)
 | |
| 	ts.root = root
 | |
| 	return ts
 | |
| }
 | |
| 
 | |
| // StoreToots writes a slice of pointers to toots to disk
 | |
| func (ts *TootFSStorage) StoreToots(tc []*toot.Toot) error {
 | |
| 	var returnErrors []string
 | |
| 	for _, item := range tc {
 | |
| 		err := ts.StoreToot(item)
 | |
| 		if err != nil {
 | |
| 			returnErrors = append(returnErrors, err.Error())
 | |
| 			continue
 | |
| 		}
 | |
| 	}
 | |
| 	if len(returnErrors) == 0 {
 | |
| 		return nil
 | |
| 	}
 | |
| 	return errors.New(strings.Join(returnErrors, "; "))
 | |
| }
 | |
| 
 | |
| // TootExists checks to see if we have already written a toot to disk or
 | |
| // not.  Note that the ingester de-dupes with a table in memory so that this
 | |
| // will only really get used on app restarts
 | |
| func (ts *TootFSStorage) TootExists(t *toot.Toot) bool {
 | |
| 	path := t.DiskStoragePath()
 | |
| 	full := ts.root + "/" + path
 | |
| 	_, err := os.Stat(full)
 | |
| 	if os.IsNotExist(err) {
 | |
| 		return false
 | |
| 	}
 | |
| 	return true
 | |
| }
 | |
| 
 | |
| // StoreToot writes a single toot to disk
 | |
| func (ts *TootFSStorage) StoreToot(t *toot.Toot) error {
 | |
| 	path := t.DiskStoragePath()
 | |
| 	full := ts.root + "/" + path
 | |
| 	dir := filepath.Dir(full)
 | |
| 	err := os.MkdirAll(dir, 0755)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	return ioutil.WriteFile(full, t.Original, 0644)
 | |
| }
 | |
| 
 | |
| // TootMemoryStorage is a TootStorageBackend that just stores all ingested
 | |
| // toots in ram forever until the computer fills up and catches fire and explodes
 | |
| type TootMemoryStorage struct {
 | |
| 	sync.Mutex
 | |
| 	toots map[string]*toot.Toot
 | |
| 	//maxSize uint   // FIXME support eviction
 | |
| }
 | |
| 
 | |
| // NewTootMemoryStorage returns a *TootMemoryStorage for storing toots in
 | |
| // ram forever
 | |
| func NewTootMemoryStorage() *TootMemoryStorage {
 | |
| 	ts := new(TootMemoryStorage)
 | |
| 	ts.toots = make(map[string]*toot.Toot)
 | |
| 	return ts
 | |
| }
 | |
| 
 | |
| // StoreToot saves a single toot into an in-memory hashtable
 | |
| func (ts *TootMemoryStorage) StoreToot(t *toot.Toot) {
 | |
| 	if ts.TootExists(t) {
 | |
| 		return
 | |
| 	}
 | |
| 	ts.Lock()
 | |
| 	defer ts.Unlock()
 | |
| 	ts.toots[t.Hash] = t
 | |
| 	return
 | |
| }
 | |
| 
 | |
| // TootExists checks to see if we have a toot in memory already
 | |
| func (ts *TootMemoryStorage) TootExists(t *toot.Toot) bool {
 | |
| 	ts.Lock()
 | |
| 	defer ts.Unlock()
 | |
| 	if _, ok := ts.toots[t.Hash]; ok { //this syntax is so gross
 | |
| 		return true
 | |
| 	}
 | |
| 	return false
 | |
| }
 |