diff --git a/lib/go/camli/index/index.go b/lib/go/camli/index/index.go index d1ff955d5..62752f3f5 100644 --- a/lib/go/camli/index/index.go +++ b/lib/go/camli/index/index.go @@ -26,10 +26,34 @@ import ( ) type IndexStorage interface { - // ... - // Add key/value - // Add batch key/values - // Prefix scan iterator + Set(key, value string) os.Error + Delete(key string) os.Error + + BeginBatch() BatchMutation + CommitBatch(b BatchMutation) os.Error +} + +type BatchMutation interface { + Set(key, value string) + Delete(key string) +} + +type mutation struct { + key string + value string // used if !delete + delete bool // if to be deleted +} + +type batch struct { + m []mutation +} + +func (b *batch) Delete(key string) { + b.m = append(b.m, mutation{key: key, delete: true}) +} + +func (b *batch) Set(key, value string) { + b.m = append(b.m, mutation{key: key, value: value}) } type Index struct { diff --git a/lib/go/camli/index/memindex.go b/lib/go/camli/index/memindex.go index 5865f22be..a036d00e8 100644 --- a/lib/go/camli/index/memindex.go +++ b/lib/go/camli/index/memindex.go @@ -18,6 +18,7 @@ package index import ( "os" + "sync" "camli/blobserver" "camli/jsonconfig" @@ -30,15 +31,56 @@ func init() { blobserver.RegisterStorageConstructor("memory-only-dev-indexer", blobserver.StorageConstructor(newMemoryIndexFromConfig)) } +// memKeys is a naive in-memory implementation of IndexStorage for test & development +// purposes only. type memKeys struct { + mu sync.Mutex // guards db db db.DB } +func (mk *memKeys) Set(key, value string) os.Error { + mk.mu.Lock() + defer mk.mu.Unlock() + return mk.db.Set([]byte(key), []byte(value)) +} + +func (mk *memKeys) Delete(key string) os.Error { + mk.mu.Lock() + defer mk.mu.Unlock() + return mk.db.Delete([]byte(key)) +} + +func (mk *memKeys) BeginBatch() BatchMutation { + return &batch{} +} + +func (mk *memKeys) CommitBatch(bm BatchMutation) os.Error { + b, ok := bm.(*batch) + if !ok { + return os.NewError("invalid batch type; not an instance returned by BeginBatch") + } + mk.mu.Lock() + defer mk.mu.Unlock() + for _ ,m := range b.m { + if m.delete { + if err := mk.db.Delete([]byte(m.key)); err != nil { + return err + } + } else { + if err := mk.db.Set([]byte(m.key), []byte(m.value)); err != nil { + return err + } + } + } + return nil + +} + func newMemoryIndexFromConfig(ld blobserver.Loader, config jsonconfig.Obj) (blobserver.Storage, os.Error) { blobPrefix := config.RequiredString("blobSource") db := memdb.New(nil) - memStorage := &memKeys{db} + memStorage := &memKeys{db: db} ix := New(memStorage) if err := config.Validate(); err != nil {