mirror of https://github.com/tidwall/tile38.git
parent
0ce2dab945
commit
248ccfbe8a
|
@ -59,11 +59,12 @@ type scanWriter struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ScanWriterParams struct {
|
type ScanWriterParams struct {
|
||||||
id string
|
id string
|
||||||
o geojson.Object
|
o geojson.Object
|
||||||
fields []float64
|
fields []float64
|
||||||
distance float64
|
distance float64
|
||||||
noLock bool
|
noLock bool
|
||||||
|
ignoreGlobMatch bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) newScanWriter(
|
func (c *Controller) newScanWriter(
|
||||||
|
@ -294,6 +295,28 @@ func (sw *scanWriter) fieldMatch(fields []float64, o geojson.Object) (fvals []fl
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sw *scanWriter) globMatch(id string, o geojson.Object) (ok, keepGoing bool) {
|
||||||
|
if !sw.globEverything {
|
||||||
|
if sw.globSingle {
|
||||||
|
if sw.globPattern != id {
|
||||||
|
return false, true
|
||||||
|
}
|
||||||
|
return true, false
|
||||||
|
}
|
||||||
|
var val string
|
||||||
|
if sw.matchValues {
|
||||||
|
val = o.String()
|
||||||
|
} else {
|
||||||
|
val = id
|
||||||
|
}
|
||||||
|
ok, _ := glob.Match(sw.globPattern, val)
|
||||||
|
if !ok {
|
||||||
|
return false, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true, true
|
||||||
|
}
|
||||||
|
|
||||||
//id string, o geojson.Object, fields []float64, noLock bool
|
//id string, o geojson.Object, fields []float64, noLock bool
|
||||||
func (sw *scanWriter) writeObject(opts ScanWriterParams) bool {
|
func (sw *scanWriter) writeObject(opts ScanWriterParams) bool {
|
||||||
if !opts.noLock {
|
if !opts.noLock {
|
||||||
|
@ -301,23 +324,11 @@ func (sw *scanWriter) writeObject(opts ScanWriterParams) bool {
|
||||||
defer sw.mu.Unlock()
|
defer sw.mu.Unlock()
|
||||||
}
|
}
|
||||||
keepGoing := true
|
keepGoing := true
|
||||||
if !sw.globEverything {
|
if !opts.ignoreGlobMatch {
|
||||||
if sw.globSingle {
|
var match bool
|
||||||
if sw.globPattern != opts.id {
|
match, keepGoing = sw.globMatch(opts.id, opts.o)
|
||||||
return true
|
if !match {
|
||||||
}
|
return true
|
||||||
keepGoing = false // return current object and stop iterating
|
|
||||||
} else {
|
|
||||||
var val string
|
|
||||||
if sw.matchValues {
|
|
||||||
val = opts.o.String()
|
|
||||||
} else {
|
|
||||||
val = opts.id
|
|
||||||
}
|
|
||||||
ok, _ := glob.Match(sw.globPattern, val)
|
|
||||||
if !ok {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nfields, ok := sw.fieldMatch(opts.fields, opts.o)
|
nfields, ok := sw.fieldMatch(opts.fields, opts.o)
|
||||||
|
|
|
@ -328,6 +328,7 @@ func (c *Controller) cmdNearby(msg *server.Message) (res resp.Value, err error)
|
||||||
}
|
}
|
||||||
sw.writeHead()
|
sw.writeHead()
|
||||||
if sw.col != nil {
|
if sw.col != nil {
|
||||||
|
var matched uint32
|
||||||
iter := func(id string, o geojson.Object, fields []float64, dist *float64) bool {
|
iter := func(id string, o geojson.Object, fields []float64, dist *float64) bool {
|
||||||
if c.hasExpired(s.key, id) {
|
if c.hasExpired(s.key, id) {
|
||||||
return true
|
return true
|
||||||
|
@ -342,15 +343,16 @@ func (c *Controller) cmdNearby(msg *server.Message) (res resp.Value, err error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sw.writeObject(ScanWriterParams{
|
return sw.writeObject(ScanWriterParams{
|
||||||
id: id,
|
id: id,
|
||||||
o: o,
|
o: o,
|
||||||
fields: fields,
|
fields: fields,
|
||||||
distance: distance,
|
distance: distance,
|
||||||
noLock: true,
|
noLock: true,
|
||||||
|
ignoreGlobMatch: s.knn,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if s.knn {
|
if s.knn {
|
||||||
nearestNeighbors(sw, s.lat, s.lon, iter)
|
nearestNeighbors(sw, s.lat, s.lon, &matched, iter)
|
||||||
} else {
|
} else {
|
||||||
sw.col.Nearby(s.sparse, s.lat, s.lon, s.meters, minZ, maxZ,
|
sw.col.Nearby(s.sparse, s.lat, s.lon, s.meters, minZ, maxZ,
|
||||||
func(id string, o geojson.Object, fields []float64) bool {
|
func(id string, o geojson.Object, fields []float64) bool {
|
||||||
|
@ -374,13 +376,22 @@ type iterItem struct {
|
||||||
dist float64
|
dist float64
|
||||||
}
|
}
|
||||||
|
|
||||||
func nearestNeighbors(sw *scanWriter, lat, lon float64, iter func(id string, o geojson.Object, fields []float64, dist *float64) bool) {
|
func nearestNeighbors(sw *scanWriter, lat, lon float64, matched *uint32,
|
||||||
|
iter func(id string, o geojson.Object, fields []float64, dist *float64) bool) {
|
||||||
limit := int(sw.cursor + sw.limit)
|
limit := int(sw.cursor + sw.limit)
|
||||||
var items []iterItem
|
var items []iterItem
|
||||||
sw.col.NearestNeighbors(lat, lon, func(id string, o geojson.Object, fields []float64) bool {
|
sw.col.NearestNeighbors(lat, lon, func(id string, o geojson.Object, fields []float64) bool {
|
||||||
if _, ok := sw.fieldMatch(fields, o); ok {
|
if _, ok := sw.fieldMatch(fields, o); !ok {
|
||||||
dist := o.CalculatedPoint().DistanceTo(geojson.Position{X: lon, Y: lat, Z: 0})
|
return true
|
||||||
items = append(items, iterItem{id: id, o: o, fields: fields, dist: dist})
|
}
|
||||||
|
match, keepGoing := sw.globMatch(id, o)
|
||||||
|
if !match {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
dist := o.CalculatedPoint().DistanceTo(geojson.Position{X: lon, Y: lat, Z: 0})
|
||||||
|
items = append(items, iterItem{id: id, o: o, fields: fields, dist: dist})
|
||||||
|
if !keepGoing {
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
return len(items) < limit
|
return len(items) < limit
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue