diff --git a/README.md b/README.md index 13a48c37..774db1cd 100644 --- a/README.md +++ b/README.md @@ -254,9 +254,9 @@ A bounding box consists of two points. The first being the southwestern most poi set fleet truck1 bounds 30 -110 40 -100 ``` #### Geohash -A [geohash](https://en.wikipedia.org/wiki/Geohash) is a string respresentation of a point. With the length of the string indicating the precision of the point. +A [geohash](https://en.wikipedia.org/wiki/Geohash) is a string representation of a point. With the length of the string indicating the precision of the point. ``` -set fleet truck1 hash 9tbnthxzr # this would be equivlent to 'point 33.5123 -112.2693' +set fleet truck1 hash 9tbnthxzr # this would be equivalent to 'point 33.5123 -112.2693' ``` #### GeoJSON @@ -272,7 +272,7 @@ set city tempe object {"type":"Polygon","coordinates":[[[0,0],[10,10],[10,0],[0, #### XYZ Tile An XYZ tile is rectangle bounding area on earth that is represented by an X, Y coordinate and a Z (zoom) level. -Check out [maptiler.org](https://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/) for an interactive example. +Check out [maptiler.org](http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/) for an interactive example. #### QuadKey A QuadKey used the same coordinate system as an XYZ tile except that the string representation is a string characters composed of 0, 1, 2, or 3. For a detailed explanation checkout [The Bing Maps Tile System](https://msdn.microsoft.com/en-us/library/bb259689.aspx). diff --git a/internal/collection/collection.go b/internal/collection/collection.go index 3f87fd8e..f9271579 100644 --- a/internal/collection/collection.go +++ b/internal/collection/collection.go @@ -1,6 +1,8 @@ package collection import ( + "runtime" + ifbtree "github.com/tidwall/btree" "github.com/tidwall/geojson" "github.com/tidwall/geojson/geo" @@ -10,6 +12,9 @@ import ( "github.com/tidwall/tile38/internal/collection/rtree" ) +// yieldStep forces the iterator to yield goroutine every N steps. +const yieldStep = 0xFF + // Cursor allows for quickly paging through Scan, Within, Intersects, and Nearby type Cursor interface { Offset() uint64 @@ -280,6 +285,9 @@ func (c *Collection) Scan(desc bool, cursor Cursor, if count <= offset { return true } + if count&yieldStep == yieldStep { + runtime.Gosched() + } if cursor != nil { cursor.Step(1) } @@ -310,6 +318,9 @@ func (c *Collection) ScanRange(start, end string, desc bool, cursor Cursor, if count <= offset { return true } + if count&yieldStep == yieldStep { + runtime.Gosched() + } if cursor != nil { cursor.Step(1) } @@ -350,6 +361,9 @@ func (c *Collection) SearchValues(desc bool, cursor Cursor, if count <= offset { return true } + if count&yieldStep == yieldStep { + runtime.Gosched() + } if cursor != nil { cursor.Step(1) } @@ -382,6 +396,9 @@ func (c *Collection) SearchValuesRange(start, end string, desc bool, if count <= offset { return true } + if count&yieldStep == yieldStep { + runtime.Gosched() + } if cursor != nil { cursor.Step(1) } @@ -422,6 +439,9 @@ func (c *Collection) ScanGreaterOrEqual(id string, desc bool, if count <= offset { return true } + if count&yieldStep == yieldStep { + runtime.Gosched() + } if cursor != nil { cursor.Step(1) } @@ -544,6 +564,9 @@ func (c *Collection) Within( if count <= offset { return false, true } + if count&yieldStep == yieldStep { + runtime.Gosched() + } if cursor != nil { cursor.Step(1) } @@ -560,6 +583,9 @@ func (c *Collection) Within( if count <= offset { return true } + if count&yieldStep == yieldStep { + runtime.Gosched() + } if cursor != nil { cursor.Step(1) } @@ -594,6 +620,9 @@ func (c *Collection) Intersects( if count <= offset { return false, true } + if count&yieldStep == yieldStep { + runtime.Gosched() + } if cursor != nil { cursor.Step(1) } @@ -610,6 +639,9 @@ func (c *Collection) Intersects( if count <= offset { return true } + if count&yieldStep == yieldStep { + runtime.Gosched() + } if cursor != nil { cursor.Step(1) } @@ -667,6 +699,9 @@ func (c *Collection) Nearby( if count <= offset { return true } + if count&yieldStep == yieldStep { + runtime.Gosched() + } if cursor != nil { cursor.Step(1) } diff --git a/internal/server/server.go b/internal/server/server.go index d04fbc1c..6e7310c8 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -785,6 +785,7 @@ func (server *Server) watchLuaStatePool() { } } +// backgroundSyncAOF ensures that the aof buffer is does not grow too big. func (server *Server) backgroundSyncAOF() { t := time.NewTicker(time.Second) defer t.Stop() @@ -792,12 +793,14 @@ func (server *Server) backgroundSyncAOF() { if server.stopServer.on() { return } - server.mu.Lock() - if len(server.aofbuf) > 0 { - server.flushAOF(true) - } - server.aofbuf = nil - server.mu.Unlock() + func() { + server.mu.Lock() + defer server.mu.Unlock() + if len(server.aofbuf) > 0 { + server.flushAOF(true) + } + server.aofbuf = nil + }() } }