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 package main
import "errors"
var ErrNotImplemented = errors.New("Not implemented")
type ( type (
Block struct {
Key []byte
Data []byte
}
Session interface { Session interface {
Fetch(hash, key []byte) ([]byte, error) Fetch(hash, key []byte) ([]byte, error)
InTransaction() bool InTransaction() bool
Store(hash, key, value []byte) (bool, error) Store(hash, key, value []byte) (bool, error)
AllKeys(hash []byte, done chan struct{}) (chan []byte, int, error) AllKeys(hash []byte, done chan struct{}) (chan []byte, int, error)
SpatialQuery(hash, first, second []byte, done chan struct{}) (chan Block, error)
BeginTransaction() error BeginTransaction() error
CommitTransaction() error CommitTransaction() error
Close() error Close() error

View File

@ -112,10 +112,6 @@ func (c *Connection) Hkeys(hash []byte) bool {
return c.writeError(err) return c.writeError(err)
} }
if err != nil {
return c.writeError(err)
}
if n == 0 { if n == 0 {
return c.writeEmptyArray() return c.writeEmptyArray()
} }
@ -126,15 +122,44 @@ func (c *Connection) Hkeys(hash []byte) bool {
} }
for key := range keys { for key := range keys {
if err := c.writeBulkString(key); err != nil { if err = c.writeBulkString(key); err != nil {
logError(err) logError(err)
close(keys)
return false return false
} }
} }
return true 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 { func (c *Connection) writeError(err error) bool {
logError(err) logError(err)
if _, err = c.conn.Write(redisError); err != nil { 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 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 Multi() bool
Exec() bool Exec() bool
Hkeys(hash []byte) bool Hkeys(hash []byte) bool
HSpatial(hash, first, second []byte) bool
} }
type RedisCommandExecutor struct { type RedisCommandExecutor struct {
@ -217,6 +218,21 @@ func (rce *RedisCommandExecutor) execute() bool {
return false return false
} }
return rce.commands.Hkeys(hash) 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) log.Printf("WARN: unknown command: '%s'\n", cmd)
return false return false

View File

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