Refactoring
This commit is contained in:
parent
5b158c27b2
commit
59accf2e53
@ -37,9 +37,9 @@ var db *sql.DB
|
|||||||
|
|
||||||
func executeQuery(rw http.ResponseWriter, req *http.Request) {
|
func executeQuery(rw http.ResponseWriter, req *http.Request) {
|
||||||
type Request struct {
|
type Request struct {
|
||||||
features Features
|
features featureMap
|
||||||
bounds Bounds
|
bounds queryBounds
|
||||||
geo Geo
|
geo geoContext
|
||||||
walkingDist float64
|
walkingDist float64
|
||||||
minScore float64
|
minScore float64
|
||||||
hintSteps int
|
hintSteps int
|
||||||
|
32
types.go
32
types.go
@ -22,59 +22,59 @@
|
|||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
type Context struct {
|
type queryContext struct {
|
||||||
geo Geo
|
geo geoContext
|
||||||
latitude float64
|
latitude float64
|
||||||
longitude float64
|
longitude float64
|
||||||
profile Features
|
profile featureMap
|
||||||
walkingDist float64
|
walkingDist float64
|
||||||
}
|
}
|
||||||
|
|
||||||
type Projection struct {
|
type queryProjection struct {
|
||||||
sample float64
|
sample float64
|
||||||
stats RecordStats
|
stats recordStats
|
||||||
}
|
}
|
||||||
|
|
||||||
type Features map[interface{}]float64
|
type featureMap map[interface{}]float64
|
||||||
|
|
||||||
type RecordStats struct {
|
type recordStats struct {
|
||||||
compatibility float64
|
compatibility float64
|
||||||
count int
|
count int
|
||||||
}
|
}
|
||||||
|
|
||||||
type Bounds struct {
|
type queryBounds struct {
|
||||||
max float64
|
max float64
|
||||||
min float64
|
min float64
|
||||||
}
|
}
|
||||||
|
|
||||||
type Geo struct {
|
type geoContext struct {
|
||||||
latitude float64
|
latitude float64
|
||||||
longitude float64
|
longitude float64
|
||||||
valid bool
|
valid bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Record struct {
|
type record struct {
|
||||||
accessCount int
|
accessCount int
|
||||||
compatibility float64
|
compatibility float64
|
||||||
distanceToStn float64
|
distanceToStn float64
|
||||||
distanceToUser float64
|
distanceToUser float64
|
||||||
features Features
|
features featureMap
|
||||||
geo Geo
|
geo geoContext
|
||||||
id int
|
id int
|
||||||
name string
|
name string
|
||||||
score float64
|
score float64
|
||||||
}
|
}
|
||||||
|
|
||||||
type Records []Record
|
type records []record
|
||||||
|
|
||||||
func (slice Records) Len() int {
|
func (slice records) Len() int {
|
||||||
return len(slice)
|
return len(slice)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (slice Records) Less(i, j int) bool {
|
func (slice records) Less(i, j int) bool {
|
||||||
return slice[i].score > slice[j].score
|
return slice[i].score > slice[j].score
|
||||||
}
|
}
|
||||||
|
|
||||||
func (slice Records) Swap(i, j int) {
|
func (slice records) Swap(i, j int) {
|
||||||
slice[i], slice[j] = slice[j], slice[i]
|
slice[i], slice[j] = slice[j], slice[i]
|
||||||
}
|
}
|
||||||
|
42
util.go
42
util.go
@ -29,7 +29,7 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
func innerProduct(features1 Features, features2 Features) float64 {
|
func innerProduct(features1 featureMap, features2 featureMap) float64 {
|
||||||
var result float64
|
var result float64
|
||||||
for key, value1 := range features1 {
|
for key, value1 := range features1 {
|
||||||
value2, _ := features2[key]
|
value2, _ := features2[key]
|
||||||
@ -39,17 +39,17 @@ func innerProduct(features1 Features, features2 Features) float64 {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func walkMatches(records Records, features Features, minScore float64, callback func(Record, float64)) {
|
func walkMatches(entries records, features featureMap, minScore float64, callback func(record, float64)) {
|
||||||
for _, record := range records {
|
for _, record := range entries {
|
||||||
if score := innerProduct(features, record.features); score >= minScore {
|
if score := innerProduct(features, record.features); score >= minScore {
|
||||||
callback(record, score)
|
callback(record, score)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func statRecords(records Records, features Features, minScore float64) RecordStats {
|
func statRecords(entries records, features featureMap, minScore float64) recordStats {
|
||||||
var stats RecordStats
|
var stats recordStats
|
||||||
walkMatches(records, features, minScore, func(record Record, score float64) {
|
walkMatches(entries, features, minScore, func(record record, score float64) {
|
||||||
stats.compatibility += record.compatibility
|
stats.compatibility += record.compatibility
|
||||||
stats.count++
|
stats.count++
|
||||||
})
|
})
|
||||||
@ -57,7 +57,7 @@ func statRecords(records Records, features Features, minScore float64) RecordSta
|
|||||||
return stats
|
return stats
|
||||||
}
|
}
|
||||||
|
|
||||||
func stepRange(bounds Bounds, steps int, callback func(float64)) {
|
func stepRange(bounds queryBounds, steps int, callback func(float64)) {
|
||||||
stepSize := (bounds.max - bounds.min) / float64(steps)
|
stepSize := (bounds.max - bounds.min) / float64(steps)
|
||||||
|
|
||||||
for i := 0; i < steps; i++ {
|
for i := 0; i < steps; i++ {
|
||||||
@ -69,37 +69,37 @@ func stepRange(bounds Bounds, steps int, callback func(float64)) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func findRecords(records Records, features Features, minScore float64) {
|
func findRecords(entries records, features featureMap, minScore float64) {
|
||||||
var foundRecords Records
|
var foundRecords records
|
||||||
|
|
||||||
walkMatches(records, features, minScore, func(record Record, score float64) {
|
walkMatches(entries, features, minScore, func(record record, score float64) {
|
||||||
foundRecords = append(foundRecords, record)
|
foundRecords = append(foundRecords, record)
|
||||||
})
|
})
|
||||||
|
|
||||||
sort.Sort(foundRecords)
|
sort.Sort(foundRecords)
|
||||||
}
|
}
|
||||||
|
|
||||||
func project(records Records, features Features, featureName string, minScore float64, bounds Bounds, steps int) []Projection {
|
func project(entries records, features featureMap, featureName string, minScore float64, bounds queryBounds, steps int) []queryProjection {
|
||||||
sampleFeatures := make(Features)
|
sampleFeatures := make(featureMap)
|
||||||
for key, value := range features {
|
for key, value := range features {
|
||||||
sampleFeatures[key] = value
|
sampleFeatures[key] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
var projection []Projection
|
var projection []queryProjection
|
||||||
stepRange(bounds, steps, func(sample float64) {
|
stepRange(bounds, steps, func(sample float64) {
|
||||||
sampleFeatures[featureName] = sample
|
sampleFeatures[featureName] = sample
|
||||||
stats := statRecords(records, sampleFeatures, minScore)
|
stats := statRecords(entries, sampleFeatures, minScore)
|
||||||
projection = append(projection, Projection{sample: sample, stats: stats})
|
projection = append(projection, queryProjection{sample: sample, stats: stats})
|
||||||
})
|
})
|
||||||
|
|
||||||
return projection
|
return projection
|
||||||
}
|
}
|
||||||
|
|
||||||
func computeRecordGeo(records Records, context Context) {
|
func computeRecordGeo(entries records, context queryContext) {
|
||||||
distUserMin := math.MaxFloat64
|
distUserMin := math.MaxFloat64
|
||||||
distUserMax := 0.0
|
distUserMax := 0.0
|
||||||
|
|
||||||
for _, record := range records {
|
for _, record := range entries {
|
||||||
if context.geo.valid {
|
if context.geo.valid {
|
||||||
userPoint := geo.NewPoint(context.geo.latitude, context.geo.longitude)
|
userPoint := geo.NewPoint(context.geo.latitude, context.geo.longitude)
|
||||||
recordPoint := geo.NewPoint(record.geo.latitude, context.geo.longitude)
|
recordPoint := geo.NewPoint(record.geo.latitude, context.geo.longitude)
|
||||||
@ -116,7 +116,7 @@ func computeRecordGeo(records Records, context Context) {
|
|||||||
|
|
||||||
distUserRange := distUserMax - distUserMin
|
distUserRange := distUserMax - distUserMin
|
||||||
|
|
||||||
for _, record := range records {
|
for _, record := range entries {
|
||||||
nearby := -((record.distanceToUser-distUserMin)/distUserRange - 0.5) * 2.0
|
nearby := -((record.distanceToUser-distUserMin)/distUserRange - 0.5) * 2.0
|
||||||
|
|
||||||
accessible := 1.0 - (record.distanceToStn / context.walkingDist)
|
accessible := 1.0 - (record.distanceToStn / context.walkingDist)
|
||||||
@ -131,8 +131,8 @@ func computeRecordGeo(records Records, context Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func computeRecordPopularity(records Records, context Context) {
|
func computeRecordPopularity(entries records, context queryContext) {
|
||||||
for _, record := range records {
|
for _, record := range entries {
|
||||||
historyRows, err := db.Query("SELECT id FROM history WHERE reviewId = (?)", record.id)
|
historyRows, err := db.Query("SELECT id FROM history WHERE reviewId = (?)", record.id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -152,7 +152,7 @@ func computeRecordPopularity(records Records, context Context) {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
recordProfile := make(Features)
|
recordProfile := make(featureMap)
|
||||||
for groupRows.Next() {
|
for groupRows.Next() {
|
||||||
var categoryId int
|
var categoryId int
|
||||||
var categoryValue float64
|
var categoryValue float64
|
||||||
|
Loading…
Reference in New Issue
Block a user