1
This commit is contained in:
Alex Yatskov 2015-08-23 20:03:26 +09:00
parent fabde8de5f
commit c580e44f1a
3 changed files with 43 additions and 41 deletions

View File

@ -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 {

View File

@ -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
}

26
util.go
View File

@ -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,