-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathhandler.go
111 lines (96 loc) · 2.56 KB
/
handler.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
package godnf
import (
"sync"
"sync/atomic"
"unsafe"
)
type rwLockWrapper struct {
RLock func()
RUnlock func()
Lock func()
Unlock func()
rwlock sync.RWMutex
}
func newRwLockWrapper(useLock bool) *rwLockWrapper {
locker := &rwLockWrapper{}
if useLock {
locker.RLock = func() { locker.rwlock.RLock() }
locker.RUnlock = func() { locker.rwlock.RUnlock() }
locker.Lock = func() { locker.rwlock.Lock() }
locker.Unlock = func() { locker.rwlock.Unlock() }
} else {
nop := func() {}
locker.RLock, locker.RUnlock = nop, nop
locker.Lock, locker.Unlock = nop, nop
}
return locker
}
// Handler is used to save docs and search docs
type Handler struct {
docs *docList
conjs *conjList
amts *amtList
terms *termList
termMap map[string]int
termMapLock *rwLockWrapper
conjRvs [][]int
conjRvsLock *rwLockWrapper
conjSzRvs [][]termRvs
conjSzRvsLock *rwLockWrapper
}
var currentHandler unsafe.Pointer = nil
// NewHandler creates a dnf handler which is safe for concurrent use by multiple goroutines
func NewHandler() *Handler {
return newHandler(true)
}
// NewHandlerWithoutLock creates a dnf handler
// which is unsafe for concurrent use by multiple goroutines
func NewHandlerWithoutLock() *Handler {
return newHandler(false)
}
func newHandler(useLock bool) *Handler {
terms := make([]Term, 0, 16)
terms = append(terms, Term{id: 0, key: "", val: ""})
termrvslist := make([]termRvs, 0, 1)
termrvslist = append(termrvslist, termRvs{termId: 0, cList: make([]cPair, 0)})
conjSzRvs := make([][]termRvs, 16)
conjSzRvs[0] = termrvslist
h := &Handler{
docs: &docList{
docs: make([]Doc, 0, 16),
docMap: make(map[string]bool, 16),
locker: newRwLockWrapper(useLock),
},
conjs: &conjList{
conjs: make([]Conj, 0, 16),
locker: newRwLockWrapper(useLock),
},
amts: &amtList{
amts: make([]Amt, 0, 16),
locker: newRwLockWrapper(useLock),
},
terms: &termList{
terms: terms,
locker: newRwLockWrapper(useLock),
},
termMap: make(map[string]int),
termMapLock: newRwLockWrapper(useLock),
conjRvs: make([][]int, 0),
conjRvsLock: newRwLockWrapper(useLock),
conjSzRvs: conjSzRvs,
conjSzRvsLock: newRwLockWrapper(useLock),
}
h.docs.h = h
h.conjs.h = h
h.amts.h = h
h.terms.h = h
return h
}
// GetHandler returns current global handler
func GetHandler() *Handler {
return (*Handler)(atomic.LoadPointer(¤tHandler))
}
// SetHandler set parameter handler to global handler
func SetHandler(handler *Handler) {
atomic.StorePointer(¤tHandler, unsafe.Pointer(handler))
}