-
Notifications
You must be signed in to change notification settings - Fork 0
/
ConcurrentPermanentMap.go
138 lines (111 loc) · 3.08 KB
/
ConcurrentPermanentMap.go
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package util
import (
"fmt"
"sync"
)
// keys are strings
type ConcurrentPermanentMap struct {
mut sync.Mutex
m MapWithPastesCount[*PermanentMapItem]
}
type PermanentMapItem struct {
value string
itemValueType MapItemValueType // URL or paste
}
type CPMNonExistentKeyError struct{}
func (e CPMNonExistentKeyError) Error() string {
return "ConcurrentPermanentMap: nonexistent key"
}
func (pmi *PermanentMapItem) MapItemToString() string {
return fmt.Sprintf("PermanentMapItem{value:%#v}", pmi.value)
}
func (pmi *PermanentMapItem) GetValue() string {
return pmi.value
}
func (pmi *PermanentMapItem) GetType() MapItemType {
return MapItemType{
IsTemporary: false,
ValueType: pmi.itemValueType,
}
}
func (emi *PermanentMapItem) GetExpiryTime() int64 {
return -1
}
func (cpm *ConcurrentPermanentMap) NumItems() int {
cpm.mut.Lock()
defer cpm.mut.Unlock()
return cpm.m.NumItems()
}
func (cpm *ConcurrentPermanentMap) NumPastes() int {
cpm.mut.Lock()
defer cpm.mut.Unlock()
return cpm.m.NumPastes()
}
// You can call this on nil receiver
func (*ConcurrentPermanentMap) BeginConstruction(stored_map_length int64, expiry_callback ExpiryCallback) ConcurrentMap {
m := NewMapWithPastesCount[*PermanentMapItem](stored_map_length)
return &ConcurrentPermanentMap{
mut: sync.Mutex{},
m: m,
}
}
// Caller must check that the key_str is not already in the map.
func (cpm *ConcurrentPermanentMap) ContinueConstruction(key_str string, value_str string, expiry_time int64, item_value_type MapItemValueType) {
// just add it to the map
err := cpm.m.InsertNew(string(key_str), &PermanentMapItem{
value: value_str,
itemValueType: item_value_type,
})
Check_err(err)
}
func (cpm *ConcurrentPermanentMap) FinishConstruction() {} // Does nothing.
// Returns an error if the entry already exists, otherwise returns nil.
func (cpm *ConcurrentPermanentMap) Put_New_Entry(key string, value string, _ int64, item_value_type MapItemValueType) error {
cpm.mut.Lock()
defer cpm.mut.Unlock()
// if entry already exists, return an error
err := cpm.m.InsertNew(key, &PermanentMapItem{
value: value,
itemValueType: item_value_type,
})
return err
}
func (cpm *ConcurrentPermanentMap) Get_Entry(key string) (MapItem, error) {
// 1. acquire read lock
cpm.mut.Lock()
defer cpm.mut.Unlock()
// 2. check if it's in the map
item, err := cpm.m.GetKey(key)
// If the key doesn't exist
if err != nil {
// return error saying key doesn't exist
return nil, CPMNonExistentKeyError{}
}
return item, nil
}
func NewEmptyConcurrentPermanentMap() *ConcurrentPermanentMap {
return &ConcurrentPermanentMap{
mut: sync.Mutex{},
m: NewMapWithPastesCount[*PermanentMapItem](0),
}
}
/*
type CPMItem struct {
Key string
Value string
}
func NewConcurrentPermanentMapFromSlice(kv_pairs []CPMItem) *ConcurrentPermanentMap {
m := make(map[string]string, len(kv_pairs))
for _, cpm_item := range kv_pairs {
m[cpm_item.Key] = cpm_item.Value
}
return &ConcurrentPermanentMap{
mut: sync.Mutex{},
m: m,
}
}
type TTLMap [K any, V any] struct {
Data []T
queue chan[K]
Map map[K]V
}*/