aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--handlers.go4
-rw-r--r--shards.go63
2 files changed, 40 insertions, 27 deletions
diff --git a/handlers.go b/handlers.go
index b4668f8..2f07500 100644
--- a/handlers.go
+++ b/handlers.go
@@ -15,7 +15,7 @@ func handleGet(conn net.Conn, args []string) {
key := args[1]
- result := db.Execute(key, func(s *Shard) interface{}{
+ result := db.ExecuteRead(key, func(s *Shard) interface{}{
item, exists := s.data[key]
if !exists {
return nil
@@ -46,7 +46,7 @@ func handleExists(conn net.Conn, args []string) {
}
key := args[1]
- result := db.Execute(key, func(s *Shard) interface{}{
+ result := db.ExecuteRead(key, func(s *Shard) interface{}{
_, exists := s.data[key]
if exists {
return 1
diff --git a/shards.go b/shards.go
index ae6e069..279d9b1 100644
--- a/shards.go
+++ b/shards.go
@@ -6,7 +6,7 @@ import (
"sync"
)
type Shard struct{
- mu sync.Mutex
+ mu sync.RWMutex
id int
data map[string]Item
}
@@ -25,30 +25,43 @@ func (db *RedisDB) Execute(key string, fn func(*Shard) interface{}) interface{}
defer shard.mu.Unlock()
return fn(shard)
}
-
+func (db *RedisDB) ExecuteRead(key string, fn func(*Shard) interface{}) interface{} {
+ shard := db.getShard(key)
+ shard.mu.RLock()
+ defer shard.mu.RUnlock()
+ return fn(shard)
+}
func ( db *RedisDB) ExecuteMulti(keys []string, fn func([]*Shard) interface{})interface{}{
- shardMap := make(map[int]*Shard)
- for _, k := range keys {
- shard := db.getShard(k)
- shardMap[shard.id] = shard
- }
- var sortedIDs []int
- for id := range shardMap {
- sortedIDs = append(sortedIDs, id)
- }
- sort.Ints(sortedIDs)
- for _, id := range sortedIDs{
- shardMap[id].mu.Lock()
- }
- defer func(){
- for i := len(sortedIDs)-1; i >= 0; i --{
- shardMap[sortedIDs[i]].mu.Unlock()
+ if len(keys) == 1{
+ shard := db.getShard(keys[0])
+ shard.mu.Lock()
+ defer shard.mu.Unlock()
+ shards := []*Shard{shard}
+ return fn(shards)
+ }else{
+ shardMap := make(map[int]*Shard)
+ for _, k := range keys {
+ shard := db.getShard(k)
+ shardMap[shard.id] = shard
}
- }()
-
- shards := make([]*Shard, 0, len(shardMap))
- for _, id := range sortedIDs {
- shards = append(shards, shardMap[id])
- }
- return fn(shards)
+ var sortedIDs []int
+ for id := range shardMap {
+ sortedIDs = append(sortedIDs, id)
+ }
+ sort.Ints(sortedIDs)
+ for _, id := range sortedIDs{
+ shardMap[id].mu.Lock()
+ }
+ defer func(){
+ for i := len(sortedIDs)-1; i >= 0; i --{
+ shardMap[sortedIDs[i]].mu.Unlock()
+ }
+ }()
+
+ shards := make([]*Shard, 0, len(shardMap))
+ for _, id := range sortedIDs {
+ shards = append(shards, shardMap[id])
+ }
+ return fn(shards)
+ }
}