| OLD | NEW | 
|    1 // Copyright 2015 The Chromium Authors. All rights reserved. |    1 // Copyright 2015 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 package memory |    5 package memory | 
|    6  |    6  | 
|    7 import ( |    7 import ( | 
|    8         "bytes" |    8         "bytes" | 
|    9         "runtime" |    9         "runtime" | 
|   10         "sync" |   10         "sync" | 
|   11  |   11  | 
 |   12         "github.com/luci/gae/service/datastore" | 
|   12         "github.com/luci/gkvlite" |   13         "github.com/luci/gkvlite" | 
|   13 ) |   14 ) | 
|   14  |   15  | 
|   15 func gkvCollide(o, n *memCollection, f func(k, ov, nv []byte)) { |   16 func gkvCollide(o, n memCollection, f func(k, ov, nv []byte)) { | 
 |   17 »       if o != nil && !o.IsReadOnly() { | 
 |   18 »       »       panic("old collection is r/w") | 
 |   19 »       } | 
 |   20 »       if n != nil && !n.IsReadOnly() { | 
 |   21 »       »       panic("new collection is r/w") | 
 |   22 »       } | 
 |   23  | 
|   16         // TODO(riannucci): reimplement in terms of *iterator. |   24         // TODO(riannucci): reimplement in terms of *iterator. | 
|   17         oldItems, newItems := make(chan *gkvlite.Item), make(chan *gkvlite.Item) |   25         oldItems, newItems := make(chan *gkvlite.Item), make(chan *gkvlite.Item) | 
|   18 »       walker := func(c *memCollection, ch chan<- *gkvlite.Item, wg *sync.WaitG
     roup) { |   26 »       walker := func(c memCollection, ch chan<- *gkvlite.Item, wg *sync.WaitGr
     oup) { | 
|   19                 defer close(ch) |   27                 defer close(ch) | 
|   20                 defer wg.Done() |   28                 defer wg.Done() | 
|   21                 if c != nil { |   29                 if c != nil { | 
|   22                         c.VisitItemsAscend(nil, true, func(i *gkvlite.Item) bool
      { |   30                         c.VisitItemsAscend(nil, true, func(i *gkvlite.Item) bool
      { | 
|   23                                 ch <- i |   31                                 ch <- i | 
|   24                                 return true |   32                                 return true | 
|   25                         }) |   33                         }) | 
|   26                 } |   34                 } | 
|   27         } |   35         } | 
|   28  |   36  | 
| (...skipping 30 matching lines...) Expand all  Loading... | 
|   59         } |   67         } | 
|   60         wg.Wait() |   68         wg.Wait() | 
|   61 } |   69 } | 
|   62  |   70  | 
|   63 // memStore is a gkvlite.Store which will panic for anything which might |   71 // memStore is a gkvlite.Store which will panic for anything which might | 
|   64 // otherwise return an error. |   72 // otherwise return an error. | 
|   65 // |   73 // | 
|   66 // This is reasonable for in-memory Store objects, since the only errors that |   74 // This is reasonable for in-memory Store objects, since the only errors that | 
|   67 // should occur happen with file IO on the underlying file (which of course |   75 // should occur happen with file IO on the underlying file (which of course | 
|   68 // doesn't exist). |   76 // doesn't exist). | 
|   69 type memStore gkvlite.Store |   77 type memStore interface { | 
 |   78 »       datastore.TestingSnapshot | 
|   70  |   79  | 
|   71 func (*memStore) ImATestingSnapshot() {} |   80 »       GetCollection(name string) memCollection | 
 |   81 »       GetCollectionNames() []string | 
 |   82 »       GetOrCreateCollection(name string) memCollection | 
 |   83 »       Snapshot() memStore | 
|   72  |   84  | 
|   73 func newMemStore() *memStore { |   85 »       IsReadOnly() bool | 
|   74 »       ret, err := gkvlite.NewStore(nil) |  | 
|   75 »       memoryCorruption(err) |  | 
|   76 »       return (*memStore)(ret) |  | 
|   77 } |  | 
|   78  |  | 
|   79 func (ms *memStore) Snapshot() *memStore { |  | 
|   80 »       ret := (*memStore)((*gkvlite.Store)(ms).Snapshot()) |  | 
|   81 »       runtime.SetFinalizer((*gkvlite.Store)(ret), func(s *gkvlite.Store) { |  | 
|   82 »       »       go s.Close() |  | 
|   83 »       }) |  | 
|   84 »       return ret |  | 
|   85 } |  | 
|   86  |  | 
|   87 func (ms *memStore) MakePrivateCollection(cmp gkvlite.KeyCompare) *memCollection
      { |  | 
|   88 »       return (*memCollection)((*gkvlite.Store)(ms).MakePrivateCollection(cmp)) |  | 
|   89 } |  | 
|   90  |  | 
|   91 func (ms *memStore) GetCollection(name string) *memCollection { |  | 
|   92 »       return (*memCollection)((*gkvlite.Store)(ms).GetCollection(name)) |  | 
|   93 } |  | 
|   94  |  | 
|   95 func (ms *memStore) SetCollection(name string, cmp gkvlite.KeyCompare) *memColle
     ction { |  | 
|   96 »       return (*memCollection)((*gkvlite.Store)(ms).SetCollection(name, cmp)) |  | 
|   97 } |  | 
|   98  |  | 
|   99 func (ms *memStore) GetCollectionNames() []string { |  | 
|  100 »       return (*gkvlite.Store)(ms).GetCollectionNames() |  | 
|  101 } |   86 } | 
|  102  |   87  | 
|  103 // memCollection is a gkvlite.Collection which will panic for anything which |   88 // memCollection is a gkvlite.Collection which will panic for anything which | 
|  104 // might otherwise return an error. |   89 // might otherwise return an error. | 
|  105 // |   90 // | 
|  106 // This is reasonable for in-memory Store objects, since the only errors that |   91 // This is reasonable for in-memory Store objects, since the only errors that | 
|  107 // should occur happen with file IO on the underlying file (which of course |   92 // should occur happen with file IO on the underlying file (which of course | 
|  108 // doesn't exist. |   93 // doesn't exist. | 
|  109 type memCollection gkvlite.Collection |   94 type memCollection interface { | 
 |   95 »       Name() string | 
 |   96 »       Delete(k []byte) bool | 
 |   97 »       Get(k []byte) []byte | 
 |   98 »       GetTotals() (numItems, numBytes uint64) | 
 |   99 »       MinItem(withValue bool) *gkvlite.Item | 
 |  100 »       Set(k, v []byte) | 
 |  101 »       VisitItemsAscend(target []byte, withValue bool, visitor gkvlite.ItemVisi
     tor) | 
|  110  |  102  | 
|  111 func (mc *memCollection) Get(k []byte) []byte { |  103 »       IsReadOnly() bool | 
|  112 »       ret, err := (*gkvlite.Collection)(mc).Get(k) |  104 } | 
 |  105  | 
 |  106 type memStoreImpl struct { | 
 |  107 »       s  *gkvlite.Store | 
 |  108 »       ro bool | 
 |  109 } | 
 |  110  | 
 |  111 var _ memStore = (*memStoreImpl)(nil) | 
 |  112  | 
 |  113 func (*memStoreImpl) ImATestingSnapshot() {} | 
 |  114  | 
 |  115 func (ms *memStoreImpl) IsReadOnly() bool { return ms.ro } | 
 |  116  | 
 |  117 func newMemStore() memStore { | 
 |  118 »       store, err := gkvlite.NewStore(nil) | 
 |  119 »       memoryCorruption(err) | 
 |  120 »       ret := memStore(&memStoreImpl{store, false}) | 
 |  121 »       if *logMemCollectionFolder != "" { | 
 |  122 »       »       ret = wrapTracingMemStore(ret) | 
 |  123 »       } | 
 |  124 »       return ret | 
 |  125 } | 
 |  126  | 
 |  127 func (ms *memStoreImpl) Snapshot() memStore { | 
 |  128 »       if ms.ro { | 
 |  129 »       »       return ms | 
 |  130 »       } | 
 |  131 »       ret := ms.s.Snapshot() | 
 |  132 »       runtime.SetFinalizer(ret, func(s *gkvlite.Store) { go s.Close() }) | 
 |  133 »       return &memStoreImpl{ret, true} | 
 |  134 } | 
 |  135  | 
 |  136 func (ms *memStoreImpl) GetCollection(name string) memCollection { | 
 |  137 »       coll := ms.s.GetCollection(name) | 
 |  138 »       if coll == nil { | 
 |  139 »       »       return nil | 
 |  140 »       } | 
 |  141 »       return &memCollectionImpl{coll, ms.ro} | 
 |  142 } | 
 |  143  | 
 |  144 func (ms *memStoreImpl) GetOrCreateCollection(name string) memCollection { | 
 |  145 »       coll := ms.GetCollection(name) | 
 |  146 »       if coll == nil { | 
 |  147 »       »       coll = &memCollectionImpl{(ms.s.SetCollection(name, nil)), ms.ro
     } | 
 |  148 »       } | 
 |  149 »       return coll | 
 |  150 } | 
 |  151  | 
 |  152 func (ms *memStoreImpl) GetCollectionNames() []string { | 
 |  153 »       return ms.s.GetCollectionNames() | 
 |  154 } | 
 |  155  | 
 |  156 type memCollectionImpl struct { | 
 |  157 »       c  *gkvlite.Collection | 
 |  158 »       ro bool | 
 |  159 } | 
 |  160  | 
 |  161 var _ memCollection = (*memCollectionImpl)(nil) | 
 |  162  | 
 |  163 func (mc *memCollectionImpl) Name() string     { return mc.c.Name() } | 
 |  164 func (mc *memCollectionImpl) IsReadOnly() bool { return mc.ro } | 
 |  165  | 
 |  166 func (mc *memCollectionImpl) Get(k []byte) []byte { | 
 |  167 »       ret, err := mc.c.Get(k) | 
|  113         memoryCorruption(err) |  168         memoryCorruption(err) | 
|  114         return ret |  169         return ret | 
|  115 } |  170 } | 
|  116  |  171  | 
|  117 func (mc *memCollection) MinItem(withValue bool) *gkvlite.Item { |  172 func (mc *memCollectionImpl) MinItem(withValue bool) *gkvlite.Item { | 
|  118 »       ret, err := (*gkvlite.Collection)(mc).MinItem(withValue) |  173 »       ret, err := mc.c.MinItem(withValue) | 
|  119         memoryCorruption(err) |  174         memoryCorruption(err) | 
|  120         return ret |  175         return ret | 
|  121 } |  176 } | 
|  122  |  177  | 
|  123 func (mc *memCollection) Set(k, v []byte) { |  178 func (mc *memCollectionImpl) Set(k, v []byte) { | 
|  124 »       err := (*gkvlite.Collection)(mc).Set(k, v) |  179 »       err := mc.c.Set(k, v) | 
|  125         memoryCorruption(err) |  180         memoryCorruption(err) | 
|  126 } |  181 } | 
|  127  |  182  | 
|  128 func (mc *memCollection) Delete(k []byte) bool { |  183 func (mc *memCollectionImpl) Delete(k []byte) bool { | 
|  129 »       ret, err := (*gkvlite.Collection)(mc).Delete(k) |  184 »       ret, err := mc.c.Delete(k) | 
|  130         memoryCorruption(err) |  185         memoryCorruption(err) | 
|  131         return ret |  186         return ret | 
|  132 } |  187 } | 
|  133  |  188  | 
|  134 func (mc *memCollection) VisitItemsAscend(target []byte, withValue bool, visitor
      gkvlite.ItemVisitor) { |  189 func (mc *memCollectionImpl) VisitItemsAscend(target []byte, withValue bool, vis
     itor gkvlite.ItemVisitor) { | 
|  135 »       err := (*gkvlite.Collection)(mc).VisitItemsAscend(target, withValue, vis
     itor) |  190 »       if !mc.ro { | 
 |  191 »       »       panic("attempting to VisitItemsAscend from r/w memCollection") | 
 |  192 »       } | 
 |  193 »       err := mc.c.VisitItemsAscend(target, withValue, visitor) | 
|  136         memoryCorruption(err) |  194         memoryCorruption(err) | 
|  137 } |  195 } | 
|  138  |  196  | 
|  139 func (mc *memCollection) GetTotals() (numItems, numBytes uint64) { |  197 func (mc *memCollectionImpl) GetTotals() (numItems, numBytes uint64) { | 
|  140 »       numItems, numBytes, err := (*gkvlite.Collection)(mc).GetTotals() |  198 »       numItems, numBytes, err := mc.c.GetTotals() | 
|  141         memoryCorruption(err) |  199         memoryCorruption(err) | 
|  142         return |  200         return | 
|  143 } |  201 } | 
| OLD | NEW |