summaryrefslogtreecommitdiff
path: root/storage/storage.go
blob: 06434e28b51661b7c66d957c718c4c5ef037d73c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package storage

import (
	"crypto/rand"
	"errors"
	"log"
	"math/big"
	"strings"
)

var ErrNoSuchFile = errors.New("no such file")

type Storage struct {
	files map[string]File
}

func NewStorage() *Storage {
	return &Storage{
		files: make(map[string]File),
	}
}

func generateKey(length uint) (string, error) {
	key := make([]string, 0, 0)
	alphabet := "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789abcdefghkmnpqrstuvwxyz"

	for i := uint(0); i < length; i++ {
		n, err := rand.Int(rand.Reader, big.NewInt(int64(len(alphabet))))

		if err != nil {
			return "", err
		}

		key = append(key, string(alphabet[n.Int64()]))
	}

	return strings.Join(key, ""), nil
}

func (s *Storage) Get(key string) (*File, error) {
	if file, ok := s.files[key]; ok {
		return &file, nil
	} else {
		return nil, ErrNoSuchFile
	}
}

func (s *Storage) Put(file File) (string, error) {
	key, err := generateKey(8)

	if err != nil {
		return "", err
	}

	s.files[key] = file

	return key, nil
}

func (s *Storage) GarbageCollect() {
	log.Println("running garbage collection on stored files")

	deletedKeys := make([]string, 0)

	for key, file := range s.files {
		if !file.IsAvailable() {
			deletedKeys = append(deletedKeys, key)
		}
	}

	for _, key := range deletedKeys {
		log.Println("cleaned up stale file:", key)
		delete(s.files, key)
	}
}