From c580e44f1a478836a1978818e486599295ae6d82 Mon Sep 17 00:00:00 2001 From: Alex Yatskov Date: Sun, 23 Aug 2015 20:03:26 +0900 Subject: [PATCH] WIP --- server.go | 40 ++++++++++++++++++++++------------------ types.go | 18 ++++++++---------- util.go | 26 +++++++++++++------------- 3 files changed, 43 insertions(+), 41 deletions(-) diff --git a/server.go b/server.go index 481a75b..53cee41 100644 --- a/server.go +++ b/server.go @@ -44,7 +44,7 @@ import ( var db *sql.DB -func prepareColumn(steps int, minScore float64, allEntries, matchedEntries []record, features featureMap, modes modeMap, name string, col *column, wg *sync.WaitGroup) { +func prepareColumn(steps int, minScore float64, allEntries, matchedEntries []record, features map[string]float64, modes map[string]modeType, name string, col *column, wg *sync.WaitGroup) { defer wg.Done() *col = column{ @@ -86,16 +86,16 @@ func executeQuery(rw http.ResponseWriter, req *http.Request) { var ( request struct { - Features featureMap `json:"features"` - Geo *geoData `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"` + Features map[string]float64 `json:"features"` + Geo *geoData `json:"geo"` + MaxResults int `json:"maxResults"` + MinScore float64 `json:"minScore"` + Modes map[string]string `json:"modes"` + Profile map[string]float64 `json:"profile"` + Resolution int `json:"resolution"` + SortAsc bool `json:"sortAsc"` + SortKey string `json:"sortKey"` + WalkingDist float64 `json:"walkingDist"` } response struct { @@ -125,14 +125,10 @@ func executeQuery(rw http.ResponseWriter, req *http.Request) { sorter := recordSorter{entries: matchedEntries, key: request.SortKey, ascending: request.SortAsc} sorter.sort() - response.Columns = make(map[string]*column) - response.Count = len(matchedEntries) - response.MinScore = request.MinScore - response.Records = matchedEntries //[:request.MaxResults] - var wg sync.WaitGroup wg.Add(len(features)) + response.Columns = make(map[string]*column) for name := range features { response.Columns[name] = new(column) go prepareColumn( @@ -149,8 +145,16 @@ func executeQuery(rw http.ResponseWriter, req *http.Request) { wg.Wait() + response.Count = len(matchedEntries) + response.MinScore = request.MinScore response.ElapsedTime = time.Since(startTime).Nanoseconds() + if len(matchedEntries) > request.MaxResults { + response.Records = matchedEntries[:request.MaxResults] + } else { + response.Records = matchedEntries + } + js, err := json.Marshal(response) if err != nil { log.Fatal(err) @@ -279,8 +283,8 @@ func removeCategory(rw http.ResponseWriter, req *http.Request) { func accessReview(rw http.ResponseWriter, req *http.Request) { var request struct { - Id int `json:"id"` - Profile featureMap `json:"profile"` + Id int `json:"id"` + Profile map[string]float64 `json:"profile"` } if err := json.NewDecoder(req.Body).Decode(&request); err != nil { diff --git a/types.go b/types.go index 537f38c..8e9def0 100644 --- a/types.go +++ b/types.go @@ -27,15 +27,18 @@ import ( "sort" ) -type featureMap map[string]float64 -type modeMap map[string]modeType type modeType int const ( - modeTypeProd = iota + 1 + modeTypeProd modeType = iota + 1 modeTypeDist ) +type bracket struct { + Min float64 `json:"min"` + Max float64 `json:"max"` +} + type column struct { Bracket bracket `json:"bracket"` Hints []projection `json:"hints"` @@ -60,18 +63,13 @@ type record struct { Name string `json:"name"` Score float64 `json:"score"` Url string `json:"url"` - features featureMap + features map[string]float64 geo geoData } -type bracket struct { - Min float64 `json:"min"` - Max float64 `json:"max"` -} - type queryContext struct { geo *geoData - profile featureMap + profile map[string]float64 walkingDist float64 } diff --git a/util.go b/util.go index 91f96f2..3105adb 100644 --- a/util.go +++ b/util.go @@ -31,8 +31,8 @@ import ( "github.com/kellydunn/golang-geo" ) -func fixFeatures(features featureMap) featureMap { - fixedFeatures := featureMap{ +func fixFeatures(features map[string]float64) map[string]float64 { + fixedFeatures := map[string]float64{ "nearby": 0.0, "accessible": 0.0, "delicious": 0.0, @@ -49,8 +49,8 @@ func fixFeatures(features featureMap) featureMap { return fixedFeatures } -func fixModes(modes map[string]string) modeMap { - fixedModes := modeMap{ +func fixModes(modes map[string]string) map[string]modeType { + fixedModes := map[string]modeType{ "nearby": modeTypeProd, "accessible": modeTypeProd, "delicious": modeTypeProd, @@ -69,7 +69,7 @@ func fixModes(modes map[string]string) modeMap { return fixedModes } -func similarity(features1 featureMap, features2 featureMap) float64 { +func similarity(features1 map[string]float64, features2 map[string]float64) float64 { var result float64 for key, value1 := range features1 { @@ -81,7 +81,7 @@ func similarity(features1 featureMap, features2 featureMap) float64 { return result } -func compare(features1 featureMap, features2 featureMap, modes modeMap) float64 { +func compare(features1 map[string]float64, features2 map[string]float64, modes map[string]modeType) float64 { var result float64 for key, value1 := range features1 { @@ -100,7 +100,7 @@ func compare(features1 featureMap, features2 featureMap, modes modeMap) float64 return result } -func walkMatches(entries []record, features featureMap, modes modeMap, minScore float64, callback func(record, float64)) { +func walkMatches(entries []record, features map[string]float64, modes map[string]modeType, minScore float64, callback func(record, float64)) { for _, entry := range entries { if score := compare(features, entry.features, modes); score >= minScore { callback(entry, score) @@ -108,7 +108,7 @@ func walkMatches(entries []record, features featureMap, modes modeMap, minScore } } -func statRecords(entries []record, features featureMap, modes modeMap, minScore float64) (float64, int) { +func statRecords(entries []record, features map[string]float64, modes map[string]modeType, minScore float64) (float64, int) { var compatibility float64 var count int @@ -132,7 +132,7 @@ func stepRange(min, max float64, steps int, callback func(float64)) { } } -func findRecords(entries []record, features featureMap, modes modeMap, minScore float64) []record { +func findRecords(entries []record, features map[string]float64, modes map[string]modeType, minScore float64) []record { var matchedEntries []record walkMatches(entries, features, modes, minScore, func(entry record, score float64) { @@ -143,8 +143,8 @@ func findRecords(entries []record, features featureMap, modes modeMap, minScore return matchedEntries } -func project(entries []record, features featureMap, modes modeMap, featureName string, minScore float64, steps int) []projection { - sampleFeatures := make(featureMap) +func project(entries []record, features map[string]float64, modes map[string]modeType, featureName string, minScore float64, steps int) []projection { + sampleFeatures := make(map[string]float64) for key, value := range features { sampleFeatures[key] = value } @@ -219,7 +219,7 @@ func computeRecordCompat(entry *record, context queryContext, wg *sync.WaitGroup } defer groupRows.Close() - recordProfile := make(featureMap) + recordProfile := make(map[string]float64) for groupRows.Next() { var categoryId int var categoryValue float64 @@ -305,7 +305,7 @@ func getRecords(context queryContext) []record { geo: geoData{latitude, longitude}, Id: id} - entry.features = featureMap{ + entry.features = map[string]float64{ "delicious": delicious, "accommodating": accommodating, "affordable": affordable,