OLD | NEW |
---|---|
1 In-memory appengine wrapper | 1 In-memory appengine wrapper |
2 =========================== | 2 =========================== |
3 | 3 |
4 | 4 |
5 Notes on the internal encodings | 5 Notes on the internal encodings |
6 ------------------------------- | 6 ------------------------------- |
7 | 7 |
8 All datatypes inside of the index Collections of the gkvlite Store are stored | 8 All datatypes inside of the index Collections of the gkvlite Store are stored |
9 in a manner which allows them to be compared entirely via bytes.Compare. All | 9 in a manner which allows them to be compared entirely via bytes.Compare. All |
10 types are prefixed by a sortable type byte which encodes the sort-order of types | 10 types are prefixed by a sortable type byte which encodes the sort-order of types |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
80 | 80 |
81 The end-result is semantically equivalent, with the exception that Query Cursors | 81 The end-result is semantically equivalent, with the exception that Query Cursors |
82 on the real datastore will potentially return the same Key in the first Cursor | 82 on the real datastore will potentially return the same Key in the first Cursor |
83 use as well as on the 2nd (or Nth) cursor use, where this method will not. | 83 use as well as on the 2nd (or Nth) cursor use, where this method will not. |
84 | 84 |
85 collections | 85 collections |
86 ents:ns -> key -> value | 86 ents:ns -> key -> value |
87 (rootkind, rootid, __entity_group__,1) -> {_ _version__: int} | 87 (rootkind, rootid, __entity_group__,1) -> {_ _version__: int} |
88 (rootkind, rootid, __entity_group_ids__,1) - > {__version__: int} | 88 (rootkind, rootid, __entity_group_ids__,1) - > {__version__: int} |
89 (__entity_group_ids__,1) -> {__version__: in t} | 89 (__entity_group_ids__,1) -> {__version__: in t} |
90 // TODO(iannucci): Journal every entity write in a log with a globally | |
91 // increasing version number (aka "timestamp"). | |
M-A Ruel
2015/05/31 23:03:15
http://googlecloudplatform.blogspot.ca/2015/05/Got
iannucci
2015/05/31 23:31:33
Yeah, that's not what I'm referring to at all :).
| |
92 // | |
93 // TODO(iannucci): Use the value in idx collection to indicate the last | |
94 // global log version reflected in this index. Then index updates can happ en | |
95 // in parallel, in a truly eventually-consistent fashion (and completely | |
96 // avoid holding the DB writelock while calculating index entries). | |
97 // Unfortunately, copying new records (and removing old ones) into the DB | |
98 // would still require holding global writelock. | |
99 // | |
100 // TODO(iannucci): how do we garbage-collect the journal? | |
101 // | |
102 // TODO(iannucci): add the ability in gkvlite to 'swap' a collection with | |
103 // another one, transactionally? Not sure if this is possible to do easily . | |
104 // If we had this, then we could do all the index writes for a given index | |
105 // on the side, and then do a quick swap into place with a writelock. As | |
106 // long as every index only has a single goroutine writing it, then this | |
107 // would enable maximum concurrency, since all indexes could update in | |
108 // parallel and only synchronize for the duration of a single pointer swap . | |
109 idx -> kind|A?|[-?prop]* = nil | |
90 idx:ns:kind -> key = nil | 110 idx:ns:kind -> key = nil |
91 idx:ns:kind|prop -> propval|key = [prev val] | 111 idx:ns:kind|prop -> propval|key = [prev val] |
92 idx:ns:kind|-prop -> -propval|key = [next val] | 112 idx:ns:kind|-prop -> -propval|key = [next val] |
93 idx:ns:kind|A|?prop|?prop -> A|propval|propval|key = [prev/next val]|[pre v/next val] | 113 idx:ns:kind|A|?prop|?prop -> A|propval|propval|key = [prev/next val]|[pre v/next val] |
94 idx:ns:kind|?prop|?prop -> propval|propval|key = [prev/next val]|[prev/ next val] | 114 idx:ns:kind|?prop|?prop -> propval|propval|key = [prev/next val]|[prev/ next val] |
95 | |
96 // to add persistence later | |
97 idx: -> kind,A?,[-?prop]* | |
OLD | NEW |