Added plain spatial query for LevelDB backend.

This commit is contained in:
Sascha L. Teichmann 2014-09-01 16:12:24 +02:00
parent f82216807e
commit bebe776e54
3 changed files with 91 additions and 8 deletions

View File

@ -223,7 +223,85 @@ func (ldbs *LevelDBSession) AllKeys(hash []byte, done chan struct{}) (keys chan
return
}
func (ldbs *LevelDBSession) SpatialQuery(hash, first, second []byte, done chan struct{}) (blocks chan Block, err error) {
func (ldbs *LevelDBSession) SpatialQuery(hash, first, second []byte, done chan struct{}) (chan Block, error) {
if ldbs.backend.interleaved {
return ldbs.interleavedSpatialQuery(first, second, done)
}
return ldbs.plainSpatialQuery(first, second, done)
}
func (ldbs *LevelDBSession) plainSpatialQuery(first, second []byte, done chan struct{}) (blocks chan Block, err error) {
var (
firstKey int64
secondKey int64
)
if firstKey, err = common.DecodeStringFromBytes(first); err != nil {
return
}
if secondKey, err = common.DecodeStringFromBytes(second); err != nil {
return
}
c1 := common.PlainToCoord(firstKey)
c2 := common.PlainToCoord(secondKey)
c1, c2 = common.MinCoord(c1, c2), common.MaxCoord(c1, c2)
blocks = make(chan Block)
go func() {
defer close(blocks)
ldbs.backend.mutex.RLock()
defer ldbs.backend.mutex.RUnlock()
ro := leveldb.NewReadOptions()
defer ro.Close()
ro.SetFillCache(false)
it := ldbs.backend.db.NewIterator(ro)
defer it.Close()
a, b := common.Coord{X: c1.X}, common.Coord{X: c2.X}
var err error
for a.Z = c1.Z; a.Z <= c2.Z; a.Z++ {
b.Z = a.Z
for a.Y = c1.Y; a.Y <= c2.Y; a.Y++ {
b.Y = a.Y
from, to := order(common.CoordToPlain(a), common.CoordToPlain(b))
var encodedFrom []byte
if encodedFrom, err = common.EncodeStringToBytes(from); err != nil {
log.Printf("encoding key failed: %s", err)
return
}
it.Seek(encodedFrom)
for it.Valid() {
key := it.Key()
var decodedKey int64
if decodedKey, err = common.DecodeStringFromBytes(key); err != nil {
log.Printf("decoding key failed: %s", err)
return
}
if decodedKey > to {
break
}
select {
case blocks <- Block{Key: key, Data: it.Value()}:
case <-done:
return
}
}
if err = it.GetError(); err != nil {
log.Printf("iterating failed: %s", err)
return
}
}
}
}()
return
}
func (ldbs *LevelDBSession) interleavedSpatialQuery(first, second []byte, done chan struct{}) (blocks chan Block, err error) {
err = ErrNotImplemented
return
}

12
misc.go Normal file
View File

@ -0,0 +1,12 @@
// Copyright 2014 by Sascha L. Teichmann
// Use of this source code is governed by the MIT license
// that can be found in the LICENSE file.
package main
func order(a, b int64) (int64, int64) {
if a < b {
return a, b
}
return b, a
}

View File

@ -292,13 +292,6 @@ func (ss *SqliteSession) SpatialQuery(hash, first, second []byte, done chan stru
return ss.plainSpatialQuery(first, second, done)
}
func order(a, b int64) (int64, int64) {
if a < b {
return a, b
}
return b, a
}
func (ss *SqliteSession) interleavedSpatialQuery(first, second []byte, done chan struct{}) (blocks chan Block, err error) {
var (
firstKey int64