Introduced non standard HSPATIAL hash first second which performs a spatial query between coords first and second. TODO: Implement in backends. Write documentation.

This commit is contained in:
Sascha L. Teichmann 2014-09-01 00:19:47 +02:00
parent 3929ffc3b2
commit caf2cbbcfe
5 changed files with 67 additions and 6 deletions

View File

@ -4,12 +4,22 @@
package main
import "errors"
var ErrNotImplemented = errors.New("Not implemented")
type (
Block struct {
Key []byte
Data []byte
}
Session interface {
Fetch(hash, key []byte) ([]byte, error)
InTransaction() bool
Store(hash, key, value []byte) (bool, error)
AllKeys(hash []byte, done chan struct{}) (chan []byte, int, error)
SpatialQuery(hash, first, second []byte, done chan struct{}) (chan Block, error)
BeginTransaction() error
CommitTransaction() error
Close() error

View File

@ -112,10 +112,6 @@ func (c *Connection) Hkeys(hash []byte) bool {
return c.writeError(err)
}
if err != nil {
return c.writeError(err)
}
if n == 0 {
return c.writeEmptyArray()
}
@ -126,15 +122,44 @@ func (c *Connection) Hkeys(hash []byte) bool {
}
for key := range keys {
if err := c.writeBulkString(key); err != nil {
if err = c.writeBulkString(key); err != nil {
logError(err)
close(keys)
return false
}
}
return true
}
func (c *Connection) HSpatial(hash, first, second []byte) bool {
var (
err error
blocks chan Block
done = make(chan struct{})
)
defer close(done)
if blocks, err = c.session.SpatialQuery(hash, first, second, done); err != nil {
return c.writeError(err)
}
for block := range blocks {
if err = c.writeBulkString(block.Key); err != nil {
logError(err)
return false
}
if err = c.writeBulkString(block.Data); err != nil {
logError(err)
return false
}
}
if err = c.writeBulkString(nil); err != nil {
logError(err)
return false
}
return true
}
func (c *Connection) writeError(err error) bool {
logError(err)
if _, err = c.conn.Write(redisError); err != nil {

View File

@ -222,3 +222,8 @@ 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) {
err = ErrNotImplemented
return
}

View File

@ -127,6 +127,7 @@ type RedisCommands interface {
Multi() bool
Exec() bool
Hkeys(hash []byte) bool
HSpatial(hash, first, second []byte) bool
}
type RedisCommandExecutor struct {
@ -217,6 +218,21 @@ func (rce *RedisCommandExecutor) execute() bool {
return false
}
return rce.commands.Hkeys(hash)
case "HSPATIAL":
if l < 4 {
log.Println("WARN: Missing argments for HSPATIAL.")
return false
}
hash, ok1 := rce.args[1].([]byte)
first, ok2 := rce.args[2].([]byte)
second, ok3 := rce.args[3].([]byte)
if !ok1 || !ok2 || !ok3 {
log.Println("WARN: HSET data are not byte slices.")
return false
}
return rce.commands.HSpatial(hash, first, second)
}
log.Printf("WARN: unknown command: '%s'\n", cmd)
return false

View File

@ -274,3 +274,8 @@ func (ss *SqliteSession) AllKeys(hash []byte, done chan struct{}) (keys chan []b
return
}
func (ss *SqliteSession) SpatialQuery(hash, first, second []byte, done chan struct{}) (blocks chan Block, err error) {
err = ErrNotImplemented
return
}