forked from Restream/reindexer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sphinx.go
110 lines (86 loc) · 2.09 KB
/
sphinx.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
package repo
import (
"sync"
"github.com/yunge/sphinx"
)
const maxSphinxClients = 8
type sphinxClient struct {
conn *sphinx.Client
busy bool
}
type SphinxRepo struct {
// sphinx.Client is not thread safe, so we have to implement our client pool
pool []*sphinxClient
lock sync.Mutex
cond *sync.Cond
// sphinx does not have storage, so we have to implement fake storage
fakeItems []*Item
}
func (repo *SphinxRepo) Init() bool {
repo.cond = sync.NewCond(&repo.lock)
for i := 0; i < maxSphinxClients; i++ {
conn := sphinx.NewClient().SetServer("127.0.0.1", 0).SetConnectTimeout(5000)
conn.Open()
if err := conn.Error(); err != nil {
panic(err)
}
repo.pool = append(repo.pool, &sphinxClient{conn: conn})
}
for i := 0; i < 100; i++ {
repo.fakeItems = append(repo.fakeItems, newItem(i))
}
return true
}
func (repo *SphinxRepo) Seed(itemsInDataSet int) bool {
return true
}
func (repo *SphinxRepo) QueryFullText(textQuery func() string, N int, limit int) (ret []*Item) {
client := repo.getClient()
client.conn.Limit = limit
ret = make([]*Item, 0, N*limit)
for i := 0; i < N; i++ {
res, err := client.conn.Query(textQuery(), "test1", "Some comment...")
if err != nil {
continue
// panic(err)
}
for _, r := range res.Matches {
ret = append(ret, repo.fakeItems[int(r.DocId)%len(repo.fakeItems)])
}
}
repo.freeClient(client)
return ret
}
func (repo *SphinxRepo) QueryByID(N int, onlyQuery bool) *Item {
return nil
}
func (repo *SphinxRepo) Query2Cond(N int, onlyQuery bool, limit int) []*Item {
return nil
}
func (repo *SphinxRepo) Query1Cond(N int, onlyQuery bool, limit int) []*Item {
return nil
}
func (repo *SphinxRepo) Update(N int) {
}
func (repo *SphinxRepo) getClient() *sphinxClient {
repo.lock.Lock()
for {
for _, client := range repo.pool {
if !client.busy {
client.busy = true
repo.lock.Unlock()
return client
}
}
repo.cond.Wait()
}
}
func (repo *SphinxRepo) freeClient(client *sphinxClient) {
repo.lock.Lock()
client.busy = false
repo.cond.Signal()
repo.lock.Unlock()
}
func init() {
registerRepo("sphinx", &SphinxRepo{})
}