Cleanup
This commit is contained in:
parent
65e9036a63
commit
2eb6d0e431
106
server.go
106
server.go
@ -44,22 +44,22 @@ import (
|
|||||||
|
|
||||||
var db *sql.DB
|
var db *sql.DB
|
||||||
|
|
||||||
func prepareColumn(request jsonQueryRequest, entries, foundEntries records, features featureMap, modes modeMap, name string, column *jsonColumn, wg *sync.WaitGroup) {
|
func prepareColumn(steps int, minScore float64, allEntries, matchedEntries records, features featureMap, modes modeMap, name string, column *jsonColumn, wg *sync.WaitGroup) {
|
||||||
mode := modes[name]
|
defer wg.Done()
|
||||||
|
|
||||||
*column = jsonColumn{
|
*column = jsonColumn{
|
||||||
Bracket: jsonBracket{Max: -1.0, Min: 1.0},
|
Bracket: jsonBracket{Max: -1.0, Min: 1.0},
|
||||||
Mode: mode.String(),
|
Mode: modes[name].String(),
|
||||||
Steps: request.Resolution,
|
Steps: steps,
|
||||||
Value: features[name]}
|
Value: features[name]}
|
||||||
|
|
||||||
hints := project(
|
hints := project(
|
||||||
entries,
|
allEntries,
|
||||||
features,
|
features,
|
||||||
modes,
|
modes,
|
||||||
name,
|
name,
|
||||||
request.MinScore,
|
minScore,
|
||||||
request.Resolution)
|
steps)
|
||||||
|
|
||||||
for _, hint := range hints {
|
for _, hint := range hints {
|
||||||
jsonHint := jsonProjection{hint.compatibility, hint.count, hint.sample}
|
jsonHint := jsonProjection{hint.compatibility, hint.count, hint.sample}
|
||||||
@ -67,7 +67,7 @@ func prepareColumn(request jsonQueryRequest, entries, foundEntries records, feat
|
|||||||
}
|
}
|
||||||
|
|
||||||
var d stats.Stats
|
var d stats.Stats
|
||||||
for _, record := range foundEntries {
|
for _, record := range matchedEntries {
|
||||||
if feature, ok := record.features[name]; ok {
|
if feature, ok := record.features[name]; ok {
|
||||||
d.Update(feature)
|
d.Update(feature)
|
||||||
}
|
}
|
||||||
@ -84,14 +84,34 @@ func prepareColumn(request jsonQueryRequest, entries, foundEntries records, feat
|
|||||||
column.Bracket.Max = math.Min(mean+dev, d.Max())
|
column.Bracket.Max = math.Min(mean+dev, d.Max())
|
||||||
column.Bracket.Min = math.Max(mean-dev, d.Min())
|
column.Bracket.Min = math.Max(mean-dev, d.Min())
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Done()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func executeQuery(rw http.ResponseWriter, req *http.Request) {
|
func executeQuery(rw http.ResponseWriter, req *http.Request) {
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
|
|
||||||
var request jsonQueryRequest
|
var (
|
||||||
|
request struct {
|
||||||
|
Features featureMap `json:"features"`
|
||||||
|
Geo *jsonGeoData `json:"geo"`
|
||||||
|
MaxResults int `json:"maxResults"`
|
||||||
|
MinScore float64 `json:"minScore"`
|
||||||
|
Modes map[string]string `json:"modes"`
|
||||||
|
Profile featureMap `json:"profile"`
|
||||||
|
Resolution int `json:"resolution"`
|
||||||
|
SortAsc bool `json:"sortAsc"`
|
||||||
|
SortKey string `json:"sortKey"`
|
||||||
|
WalkingDist float64 `json:"walkingDist"`
|
||||||
|
}
|
||||||
|
|
||||||
|
response struct {
|
||||||
|
Columns map[string]*jsonColumn `json:"columns"`
|
||||||
|
Count int `json:"count"`
|
||||||
|
MinScore float64 `json:"minScore"`
|
||||||
|
Records []jsonRecord `json:"records"`
|
||||||
|
ElapsedTime int64 `json:"elapsedTime"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
@ -102,44 +122,53 @@ func executeQuery(rw http.ResponseWriter, req *http.Request) {
|
|||||||
geo = &geoData{request.Geo.Latitude, request.Geo.Longitude}
|
geo = &geoData{request.Geo.Latitude, request.Geo.Longitude}
|
||||||
}
|
}
|
||||||
|
|
||||||
entries := getRecords(queryContext{geo, request.Profile, request.WalkingDist})
|
allEntries := getRecords(queryContext{geo, request.Profile, request.WalkingDist})
|
||||||
features := fixFeatures(request.Features)
|
features := fixFeatures(request.Features)
|
||||||
modes := fixModes(request.Modes)
|
modes := fixModes(request.Modes)
|
||||||
|
|
||||||
foundEntries := findRecords(entries, features, modes, request.MinScore)
|
matchedEntries := findRecords(allEntries, features, modes, request.MinScore)
|
||||||
sorter := recordSorter{entries: foundEntries, key: request.SortKey, ascending: request.SortAsc}
|
sorter := recordSorter{entries: matchedEntries, key: request.SortKey, ascending: request.SortAsc}
|
||||||
sorter.sort()
|
sorter.sort()
|
||||||
|
|
||||||
response := jsonQueryResponse{
|
response.Columns = make(map[string]*jsonColumn)
|
||||||
Columns: make(map[string]*jsonColumn),
|
response.Count = len(matchedEntries)
|
||||||
Count: len(foundEntries),
|
response.MinScore = request.MinScore
|
||||||
MinScore: request.MinScore,
|
response.Records = make([]jsonRecord, 0)
|
||||||
Records: make([]jsonRecord, 0)}
|
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
wg.Add(len(features))
|
wg.Add(len(features))
|
||||||
|
|
||||||
for name := range features {
|
for name := range features {
|
||||||
column := &jsonColumn{}
|
response.Columns[name] = new(jsonColumn)
|
||||||
prepareColumn(request, entries, foundEntries, features, modes, name, column, &wg)
|
go prepareColumn(
|
||||||
response.Columns[name] = column
|
request.Resolution,
|
||||||
|
request.MinScore,
|
||||||
|
allEntries,
|
||||||
|
matchedEntries,
|
||||||
|
features,
|
||||||
|
modes,
|
||||||
|
name,
|
||||||
|
response.Columns[name],
|
||||||
|
&wg)
|
||||||
}
|
}
|
||||||
|
|
||||||
for index, record := range foundEntries {
|
wg.Wait()
|
||||||
|
|
||||||
|
for index, entry := range matchedEntries {
|
||||||
if index >= request.MaxResults {
|
if index >= request.MaxResults {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
item := jsonRecord{
|
item := jsonRecord{
|
||||||
Name: record.name,
|
Name: entry.name,
|
||||||
Url: record.url,
|
Url: entry.url,
|
||||||
Score: record.score,
|
Score: entry.score,
|
||||||
Compatibility: record.compatibility,
|
Compatibility: entry.compatibility,
|
||||||
DistanceToUser: record.distanceToUser,
|
DistanceToUser: entry.distanceToUser,
|
||||||
DistanceToStn: record.distanceToStn,
|
DistanceToStn: entry.distanceToStn,
|
||||||
ClosestStn: record.closestStn,
|
ClosestStn: entry.closestStn,
|
||||||
AccessCount: record.accessCount,
|
AccessCount: entry.accessCount,
|
||||||
Id: record.id}
|
Id: entry.id}
|
||||||
|
|
||||||
response.Records = append(response.Records, item)
|
response.Records = append(response.Records, item)
|
||||||
}
|
}
|
||||||
@ -195,15 +224,17 @@ func getCategories(rw http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func addCategory(rw http.ResponseWriter, req *http.Request) {
|
func addCategory(rw http.ResponseWriter, req *http.Request) {
|
||||||
var request struct {
|
var (
|
||||||
|
request struct {
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var response struct {
|
response struct {
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Id int `json:"id"`
|
Id int `json:"id"`
|
||||||
Success bool `json:"success"`
|
Success bool `json:"success"`
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
@ -242,13 +273,15 @@ func addCategory(rw http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func removeCategory(rw http.ResponseWriter, req *http.Request) {
|
func removeCategory(rw http.ResponseWriter, req *http.Request) {
|
||||||
var request struct {
|
var (
|
||||||
|
request struct {
|
||||||
Id int `json:"id"`
|
Id int `json:"id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var response struct {
|
response struct {
|
||||||
Success bool `json:"success"`
|
Success bool `json:"success"`
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
@ -360,7 +393,6 @@ func main() {
|
|||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
<-c
|
<-c
|
||||||
log.Print("interrupted")
|
|
||||||
pprof.StopCPUProfile()
|
pprof.StopCPUProfile()
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}()
|
}()
|
||||||
|
21
types.go
21
types.go
@ -42,19 +42,6 @@ type jsonGeoData struct {
|
|||||||
Longitude float64 `json:"longitude"`
|
Longitude float64 `json:"longitude"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type jsonQueryRequest struct {
|
|
||||||
Features featureMap `json:"features"`
|
|
||||||
Geo *jsonGeoData `json:"geo"`
|
|
||||||
MaxResults int `json:"maxResults"`
|
|
||||||
MinScore float64 `json:"minScore"`
|
|
||||||
Modes map[string]string `json:"modes"`
|
|
||||||
Profile featureMap `json:"profile"`
|
|
||||||
Resolution int `json:"resolution"`
|
|
||||||
SortAsc bool `json:"sortAsc"`
|
|
||||||
SortKey string `json:"sortKey"`
|
|
||||||
WalkingDist float64 `json:"walkingDist"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type jsonColumn struct {
|
type jsonColumn struct {
|
||||||
Bracket jsonBracket `json:"bracket"`
|
Bracket jsonBracket `json:"bracket"`
|
||||||
Hints []jsonProjection `json:"hints"`
|
Hints []jsonProjection `json:"hints"`
|
||||||
@ -86,14 +73,6 @@ type jsonBracket struct {
|
|||||||
Max float64 `json:"max"`
|
Max float64 `json:"max"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type jsonQueryResponse struct {
|
|
||||||
Columns map[string]*jsonColumn `json:"columns"`
|
|
||||||
Count int `json:"count"`
|
|
||||||
MinScore float64 `json:"minScore"`
|
|
||||||
Records []jsonRecord `json:"records"`
|
|
||||||
ElapsedTime int64 `json:"elapsedTime"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type queryContext struct {
|
type queryContext struct {
|
||||||
geo *geoData
|
geo *geoData
|
||||||
profile featureMap
|
profile featureMap
|
||||||
|
2
util.go
2
util.go
@ -298,7 +298,7 @@ func getRecords(context queryContext) records {
|
|||||||
|
|
||||||
entry := record{
|
entry := record{
|
||||||
name: name,
|
name: name,
|
||||||
url: "http://www.tripadvisor.com" + url,
|
url: url,
|
||||||
distanceToStn: distanceToStn,
|
distanceToStn: distanceToStn,
|
||||||
closestStn: closestStn,
|
closestStn: closestStn,
|
||||||
accessCount: accessCount,
|
accessCount: accessCount,
|
||||||
|
Loading…
Reference in New Issue
Block a user