-
Notifications
You must be signed in to change notification settings - Fork 1
/
colmgr.go
240 lines (193 loc) · 4.29 KB
/
colmgr.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
package colmgr
import (
"github.com/anlhord/generic"
"github.com/anlhord/generic/low"
genref "github.com/anlhord/generic/reflect"
"reflect"
// "fmt"
)
// this is the map that stores the roots of the collections
var collections map[uintptr]Collector
func init() {
collections = make(map[uintptr]Collector)
}
func Init(handle interface{}, rooter Rooter) {
p := uintptr(reflect.ValueOf(handle).Pointer())
// fmt.Printf("Calling Root to %d.\n", p)
if colmgr_debug && collections[p] != nil {
panic("Reinitialized collection")
}
collections[p] = rooter.Root()
}
func Destroy(handle interface{}) {
p := uintptr(reflect.ValueOf(handle).Pointer())
collections[p].Destroy()
delete(collections, p)
// fmt.Printf("Destroyed %d.\n", p)
// FIXME: refcounting?
}
////////////////////////////////////////////////////////////////////////////////
func Puts(slice interface{}, u UpdMapper) {
if colmgr_debug && !low.S(slice) {
panic("Put slice is not a slice")
}
u.Upd(*low.T(slice))
}
func Gets(slice interface{}, u UpdMapper) {
if colmgr_debug && !low.S(slice) {
panic("Get slice is not a slice")
}
*low.T(slice) = u.Map()
}
func Puti(iface interface{}, u UpdMapper) {
if colmgr_debug && low.S(iface) {
panic("Get iface is not an iface")
}
u.Upd(low.Y(iface))
}
func Geti(iface interface{}, u UpdMapper) {
if colmgr_debug && low.S(iface) {
panic("Get iface is not an iface")
}
*low.I(iface) = u.Map()
}
func Put(gvalue interface{}, u UpdMapper) {
if low.S(gvalue) {
Puts(gvalue, u)
} else {
Puti(gvalue, u)
}
}
func Get(gvalue interface{}, u UpdMapper) {
if low.S(gvalue) {
Gets(gvalue, u)
} else {
Geti(gvalue, u)
}
}
////////////////////////////////////////////////////////////////////////////////
func Inserts(gkey uintptr, slice interface{}, u MkNoder) {
if colmgr_debug && !low.S(slice) {
panic("Insert slice is not a slice")
}
sll := genref.Stuff(slice) // FIXME: use low.T here
if colmgr_gen_debug { // FIXME: make low.T work
sl := *low.T(slice)
if &(sll[0]) != &((*sl)[0]) {
panic("low.T bug")
}
if len(sll) != len((*sl)) {
panic("low.T len bug")
}
if cap(sll) != cap((*sl)) {
panic("low.T cap bug")
}
}
// fmt.Printf("Inserts %v.\n", &((sll)[0]))
u.MkNode(gkey, &sll)
}
func Inserti(gkey uintptr, iface interface{}, u MkNoder) {
u.MkNode(gkey, low.Y(iface))
}
func Insert(gkey uintptr, gvalue interface{}, u MkNoder) {
if low.S(gvalue) {
Inserts(gkey, gvalue, u)
} else {
Inserti(gkey, gvalue, u)
}
}
////////////////////////////////////////////////////////////////////////////////
func Append(gvalue interface{}, p Pusher) {
if low.S(gvalue) {
Appends(gvalue, p)
} else {
Appendi(gvalue, p)
}
}
func Appendi(iface interface{}, p Pusher) {
p.Push(low.Y(iface))
}
func Appends(slice interface{}, p Pusher) {
p.Push(*low.T(slice))
}
////////////////////////////////////////////////////////////////////////////////
type Rooter interface {
Root() Collector
}
type Collector interface {
Atterer
MkNoder
Dumper
Destroyer
}
type Destroyer interface {
Destroy()
}
// Cursor operators:////////////////////////////////////////////////
type Ender interface {
End() bool
}
type UpdMapper interface {
Map() *generic.Value
Upd(*generic.Value)
}
const Begin = uintptr(0)
const Root = ^Begin
const End = ^uintptr(1)
type Nexter interface {
Atterer
Ender
Next()
}
type Atter interface {
Atterer
UpdMapper
Nuker
Ender
Nexterer
MkNoder
Pusher
Fixer
}
type Atterer interface {
At(uintptr) Atter
}
type Nexterer interface {
Next() Nexter
}
func At(handle interface{}, key uintptr) Atter {
p := uintptr(reflect.ValueOf(handle).Pointer())
return collections[p].At(key)
}
type Pusher interface {
Push(*generic.Value)
}
type Fixer interface {
Fix()
}
type Nuker interface {
Nuke(uintptr, uintptr)
}
type MkNoder interface {
MkNode(uintptr, *generic.Value)
}
/*
// scaffolding operation, a high level replacement for a MkNode
func Insert(handle interface{}, key uintptr, val *generic.Value) {
if key >= End {
panic("Key -1 is end. Use smaller")
}
p := uintptr(reflect.ValueOf(handle).Pointer())
collections[p].MkNode(key, val)
}
*/
type Dumper interface {
Dump(byte)
}
func Dump(handle interface{}, format byte) {
if format > 1 {
panic("Unsupported format")
}
p := uintptr(reflect.ValueOf(handle).Pointer())
collections[p].Dump(format)
}