-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathusers_visits.go
124 lines (100 loc) · 2.99 KB
/
users_visits.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
package main
import (
"github.com/valyala/fasthttp"
"log"
)
var _ = log.Println
type usersVisits struct {
// key
Visit int // visit
Distance int // location
Country string // location
// data
Mark uint8 // visit
Place []byte // location
}
type UsersVisitsNode struct {
key int
val * usersVisits
nextNode *UsersVisitsNode
}
type UsersVisitsIndex struct {
head *UsersVisitsNode
}
func NewUsersVisitsIndex() UsersVisitsIndex {
return UsersVisitsIndex{head: &UsersVisitsNode{key: 0, val: nil, nextNode: nil}}
}
func (b UsersVisitsIndex) Insert(key int, value * usersVisits) {
currentNode := b.head
var previousNode *UsersVisitsNode
newNode := &UsersVisitsNode{key: key, val: value, nextNode: nil}
for {
if currentNode.key > key {
newNode.nextNode = previousNode.nextNode
previousNode.nextNode = newNode
return
}
if currentNode.nextNode == nil {
currentNode.nextNode = newNode
return
}
previousNode = currentNode
currentNode = currentNode.nextNode
}
}
func (b UsersVisitsIndex) RemoveByVisit(Visit int) (*usersVisits) {
currentNode := b.head
var previousNode *UsersVisitsNode
for {
if currentNode.val != nil {
val := currentNode.val
if val.Visit == Visit {
previousNode.nextNode = currentNode.nextNode
return currentNode.val
}
}
if currentNode.nextNode == nil {
return nil
}
previousNode = currentNode
currentNode = currentNode.nextNode
}
}
func (b UsersVisitsIndex) VisitsHandler(ctx *fasthttp.RequestCtx, skipCountry bool, fromDate int, toDate int, Country string, toDistance int) () {
ctx.Write([]byte("{\"visits\":["))
if b.head.nextNode == nil { // no visits of this user
ctx.Write([]byte("]}"))
return
}
currentNode := b.head.nextNode
first_entry := true
for {
val := currentNode.val
Visited_at := currentNode.key
//log.Println(val.Visit, Visited_at, val.Distance, val.Country, val.Mark, val.Place)
matched :=
(Visited_at > fromDate) &&
(Visited_at < toDate) &&
(skipCountry || val.Country == Country) &&
(val.Distance < toDistance)
if matched {
if first_entry {
first_entry = false
} else {
ctx.Write([]byte(","))
}
ctx.Write([]byte("{\"mark\":"))
ctx.Write([]byte{uint8(val.Mark) + '0'})
ctx.Write([]byte(",\"visited_at\":"))
WriteInt(ctx, Visited_at)
ctx.Write([]byte(",\"place\":\""))
ctx.Write(val.Place)
ctx.Write([]byte("\"}"))
}
if currentNode.nextNode == nil {
break
}
currentNode = currentNode.nextNode
}
ctx.Write([]byte("]}"))
}