Always use compressed indexing

This commit is contained in:
tidwall 2018-10-23 11:23:55 -07:00
parent ccd6975f5f
commit b1370332e6
6 changed files with 17 additions and 62 deletions

4
Gopkg.lock generated
View File

@ -227,7 +227,7 @@
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:c0012e273a29ef7c490e8a4d28c23f2135b8aa9980121a65bdc032163d7cbfd5" digest = "1:6fc1b77dedecd24d417a38c4ffc580c0c4de1540b60453efee44f1a41b205d27"
name = "github.com/tidwall/geojson" name = "github.com/tidwall/geojson"
packages = [ packages = [
".", ".",
@ -235,7 +235,7 @@
"geometry", "geometry",
] ]
pruneopts = "" pruneopts = ""
revision = "a1db67ca0ab0c8e59a5fc9d03d0e1d88f87b6902" revision = "581e33d25c96a70d4006cbeca5fcd716caad7766"
[[projects]] [[projects]]
digest = "1:3ddca2bd5496c6922a2a9e636530e178a43c2a534ea6634211acdc7d10222794" digest = "1:3ddca2bd5496c6922a2a9e636530e178a43c2a534ea6634211acdc7d10222794"

View File

@ -184,12 +184,8 @@ func ListenAndServeEx(host string, port int, dir string, ln *net.Listener, http
c.geomParseOpts.IndexGeometryKind = geometry.None c.geomParseOpts.IndexGeometryKind = geometry.None
case "RTree": case "RTree":
c.geomParseOpts.IndexGeometryKind = geometry.RTree c.geomParseOpts.IndexGeometryKind = geometry.RTree
case "RTreeCompressed":
c.geomParseOpts.IndexGeometryKind = geometry.RTreeCompressed
case "QuadTree": case "QuadTree":
c.geomParseOpts.IndexGeometryKind = geometry.QuadTree c.geomParseOpts.IndexGeometryKind = geometry.QuadTree
case "QuadTreeCompressed":
c.geomParseOpts.IndexGeometryKind = geometry.QuadTreeCompressed
} }
if c.geomParseOpts.IndexGeometryKind == geometry.None { if c.geomParseOpts.IndexGeometryKind == geometry.None {
log.Debugf("Geom indexing: %s", log.Debugf("Geom indexing: %s",

View File

@ -24,12 +24,8 @@ func (kind IndexKind) shortString() string {
return "none" return "none"
case RTree: case RTree:
return "rtre" return "rtre"
case RTreeCompressed:
return "rtrc"
case QuadTree: case QuadTree:
return "quad" return "quad"
case QuadTreeCompressed:
return "quac"
} }
} }
@ -40,9 +36,7 @@ func testBig(
opts := []IndexOptions{ opts := []IndexOptions{
IndexOptions{Kind: None, MinPoints: 64}, IndexOptions{Kind: None, MinPoints: 64},
IndexOptions{Kind: QuadTreeCompressed, MinPoints: 64},
IndexOptions{Kind: QuadTree, MinPoints: 64}, IndexOptions{Kind: QuadTree, MinPoints: 64},
IndexOptions{Kind: RTreeCompressed, MinPoints: 64},
IndexOptions{Kind: RTree, MinPoints: 64}, IndexOptions{Kind: RTree, MinPoints: 64},
} }
for _, opts := range opts { for _, opts := range opts {
@ -79,8 +73,8 @@ func testBig(
if os.Getenv("PIPBENCH") == "1" { if os.Getenv("PIPBENCH") == "1" {
fmt.Printf("%s/%s ", label, opts.Kind.shortString()) fmt.Printf("%s/%s ", label, opts.Kind.shortString())
mem := ms2.Alloc - ms1.Alloc mem := ms2.Alloc - ms1.Alloc
fmt.Printf("created in %s using %d bytes\n", dur, mem) fmt.Printf("%d points created in %s using %d bytes\n",
ring.NumPoints(), dur, mem)
lotsa.Output = os.Stdout lotsa.Output = os.Stdout
fmt.Printf("%s/%s/in ", label, opts.Kind.shortString()) fmt.Printf("%s/%s/in ", label, opts.Kind.shortString())
lotsa.Ops(N, T, func(_, _ int) { lotsa.Ops(N, T, func(_, _ int) {
@ -99,9 +93,7 @@ func testBig(
ringContainsPoint(ring, randPoints[i], true) ringContainsPoint(ring, randPoints[i], true)
}) })
} }
} }
} }
func TestBigArizona(t *testing.T) { func TestBigArizona(t *testing.T) {

View File

@ -1,8 +1,10 @@
package geometry package geometry
import "encoding/binary" import (
"encoding/binary"
)
const qMaxItems = 16 const qMaxItems = 32
const qMaxDepth = 16 const qMaxDepth = 16
type qNode struct { type qNode struct {

View File

@ -17,9 +17,7 @@ type IndexKind byte
const ( const (
None IndexKind = iota None IndexKind = iota
RTree RTree
RTreeCompressed
QuadTree QuadTree
QuadTreeCompressed
) )
func (kind IndexKind) String() string { func (kind IndexKind) String() string {
@ -30,12 +28,8 @@ func (kind IndexKind) String() string {
return "None" return "None"
case RTree: case RTree:
return "RTree" return "RTree"
case RTreeCompressed:
return "RTreeCompressed"
case QuadTree: case QuadTree:
return "QuadTree" return "QuadTree"
case QuadTreeCompressed:
return "QuadTreeCompressed"
} }
} }
@ -182,27 +176,6 @@ func (series *baseSeries) Search(
} }
} }
} }
case *rTree:
v.Search(
[]float64{rect.Min.X, rect.Min.Y},
[]float64{rect.Max.X, rect.Max.Y},
func(_, _ []float64, value interface{}) bool {
index := value.(int)
var seg Segment
seg.A = series.points[index]
if series.closed && index == len(series.points)-1 {
seg.B = series.points[0]
} else {
seg.B = series.points[index+1]
}
if !iter(seg, index) {
return false
}
return true
},
)
case *qNode:
v.search(series, series.rect, rect, iter)
case *byte: case *byte:
// convert the byte pointer back to a valid slice // convert the byte pointer back to a valid slice
data := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{ data := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
@ -340,7 +313,7 @@ func (series *baseSeries) buildIndex() {
return return
} }
switch series.indexKind { switch series.indexKind {
case RTree, RTreeCompressed: case RTree:
tr := new(rTree) tr := new(rTree)
n := series.NumSegments() n := series.NumSegments()
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
@ -349,26 +322,18 @@ func (series *baseSeries) buildIndex() {
[]float64{rect.Min.X, rect.Min.Y}, []float64{rect.Min.X, rect.Min.Y},
[]float64{rect.Max.X, rect.Max.Y}, i) []float64{rect.Max.X, rect.Max.Y}, i)
} }
if series.indexKind == RTreeCompressed { series.setCompressed(
series.setCompressed( tr.compress([]byte{1, 0, 0, 0, 0}),
tr.compress([]byte{1, 0, 0, 0, 0}), )
) case QuadTree:
} else {
series.index = tr
}
case QuadTree, QuadTreeCompressed:
root := new(qNode) root := new(qNode)
n := series.NumSegments() n := series.NumSegments()
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
seg := series.SegmentAt(i) seg := series.SegmentAt(i)
root.insert(series, series.rect, seg.Rect(), i, 0) root.insert(series, series.rect, seg.Rect(), i, 0)
} }
if series.indexKind == QuadTreeCompressed { series.setCompressed(
series.setCompressed( root.compress([]byte{2, 0, 0, 0, 0}, series.rect),
root.compress([]byte{2, 0, 0, 0, 0}, series.rect), )
)
} else {
series.index = root
}
} }
} }

View File

@ -93,7 +93,7 @@ type ParseOptions struct {
var DefaultParseOptions = &ParseOptions{ var DefaultParseOptions = &ParseOptions{
IndexChildren: 64, IndexChildren: 64,
IndexGeometry: 64, IndexGeometry: 64,
IndexGeometryKind: geometry.QuadTreeCompressed, IndexGeometryKind: geometry.QuadTree,
} }
// Parse a GeoJSON object // Parse a GeoJSON object