gifs/api

Paddy 2014-12-17 Parent:eb450538f079

8:03e846421572 Go to Latest

gifs/api/usage.go

Update import path. Update our import path so it will work without aliasing.

History
1 package api
3 import (
4 "sort"
5 "sync"
7 "code.secondbit.org/uuid.hg"
8 )
10 type UsageTracker interface {
11 TrackUpload(id uuid.ID, bytes int64) error
12 TrackDownload(id uuid.ID, bytes int64) error
13 GetUsage(id uuid.ID) (Usage, error)
14 GetTopUsages(id uuid.ID, num, offset int64) ([]Usage, error)
15 }
17 type Usage struct {
18 UserID uuid.ID
19 UploadedBytes int64
20 DownloadedBytes int64
21 UploadRequests int64
22 DownloadRequests int64
23 }
25 func (u Usage) score() float64 {
26 storageCost := .026 * float64(u.UploadedBytes) / 1073741824
27 bandwidthCost := .012 * float64(u.DownloadedBytes) / 1073741824
28 uploadReqCost := .02 * float64(u.UploadRequests) / 1000
29 downloadReqCost := .01 * float64(u.DownloadRequests) / 10000
30 return storageCost + bandwidthCost + uploadReqCost + downloadReqCost
31 }
33 type topUsages []Usage
35 func (t topUsages) Less(i, j int) bool {
36 return t[i].score() > t[j].score()
37 }
39 func (t topUsages) Swap(i, j int) {
40 t[i], t[j] = t[j], t[i]
41 }
43 func (t topUsages) Len() int {
44 return len(t)
45 }
47 type MemTracker struct {
48 usages map[string]Usage
49 sync.RWMutex
50 }
52 func NewMemTracker() *MemTracker {
53 return &MemTracker{
54 usages: map[string]Usage{},
55 }
56 }
58 func (m *MemTracker) TrackUpload(id uuid.ID, bytes int64) error {
59 m.Lock()
60 defer m.Unlock()
62 use := m.usages[id.String()]
64 use.UploadedBytes = use.UploadedBytes + bytes
65 use.UploadRequests = use.UploadRequests + 1
66 m.usages[id.String()] = use
67 return nil
68 }
70 func (m *MemTracker) TrackDownload(id uuid.ID, bytes int64) error {
71 m.Lock()
72 defer m.Unlock()
74 use := m.usages[id.String()]
76 use.DownloadedBytes = use.DownloadedBytes + bytes
77 use.DownloadRequests = use.DownloadRequests + 1
78 m.usages[id.String()] = use
79 return nil
80 }
82 func (m *MemTracker) GetUsage(id uuid.ID) (Usage, error) {
83 m.RLock()
84 defer m.RUnlock()
86 return m.usages[id.String()], nil
87 }
89 func (m *MemTracker) GetTopUsages(id uuid.ID, num, offset int64) ([]Usage, error) {
90 m.RLock()
91 defer m.RUnlock()
93 usages := []Usage{}
94 for _, usage := range m.usages {
95 usages = append(usages, usage)
96 }
97 sortedUsages := topUsages(usages)
98 sort.Sort(sortedUsages)
99 usages = []Usage(sortedUsages)
101 if int64(len(usages)) <= offset {
102 return []Usage{}, nil
103 }
104 if int64(len(usages)) > offset+num {
105 return usages[offset : offset+num], nil
106 } else {
107 return usages[offset:], nil
108 }
109 }