OLD | NEW |
1 Datastore implementation internals | 1 Datastore implementation internals |
2 ================================== | 2 ================================== |
3 | 3 |
4 This document contains internal implementation details for this in-memory | 4 This document contains internal implementation details for this in-memory |
5 version of datastore. It's mostly helpful to understand what's going on in this | 5 version of datastore. It's mostly helpful to understand what's going on in this |
6 implementation, but it also can reveal some insight into how the real appengine | 6 implementation, but it also can reveal some insight into how the real appengine |
7 datastore works (though note that the specific encodings are different). | 7 datastore works (though note that the specific encodings are different). |
8 | 8 |
9 Additionally note that this implementation cheats by moving some of the Key | 9 Additionally note that this implementation cheats by moving some of the Key |
10 bytes into the table (collection) names (like the namespace, property name for | 10 bytes into the table (collection) names (like the namespace, property name for |
11 the builtin indexes, etc.). The real implementation contains these bytes in the | 11 the builtin indexes, etc.). The real implementation contains these bytes in the |
12 table row keys, I think. | 12 table row keys, I think. |
13 | 13 |
14 | 14 |
15 Internal datastore key/value collection schema | 15 Internal datastore key/value collection schema |
16 ---------------------------------------------- | 16 ---------------------------------------------- |
17 | 17 |
18 The datastore implementation here uses several different tables ('collections') | 18 The datastore implementation here uses several different tables ('collections') |
19 to manage state for the data. The schema for these tables is enumerated below | 19 to manage state for the data. The schema for these tables is enumerated below |
20 to make the code a bit easier to reason about. | 20 to make the code a bit easier to reason about. |
21 | 21 |
22 All datastore user objects (Keys, Properties, PropertyMaps, etc.) are serialized | 22 All datastore user objects (Keys, Properties, PropertyMaps, etc.) are serialized |
23 using `github.com/luci/gae/service/datastore/serialize`, which in turn uses the | 23 using `github.com/luci/gae/service/datastore/serialize`, which in turn uses the |
24 primitives available in `github.com/luci/luci-go/common/cmpbin`. The encodings | 24 primitives available in `github.com/luci/luci-go/common/cmpbin`. The encodings |
25 are important to understanding why the schemas below sort correctly when | 25 are important to understanding why the schemas below sort correctly when |
26 compared only using `bytes.Compare` (aka `memcmp`). This doc will assume that | 26 compared only using `bytes.Compare` (aka `memcmp`). This doc will assume that |
27 you're familiar with those encodings, but will point out where we diverge from | 27 you're familiar with those encodings, but will point out where we diverge from |
28 the stock encodings. | 28 the stock encodings. |
29 | 29 |
30 All encoded Property values used in gkvlite Keys (i.e. index rows) are | 30 All encoded Property values used in memory store Keys (i.e. index rows) are |
31 serialized using the settings `serialize.WithoutContext`, and | 31 serialized using the settings `serialize.WithoutContext`, and |
32 `datastore.ShouldIndex`. | 32 `datastore.ShouldIndex`. |
33 | 33 |
34 ### Primary table | 34 ### Primary table |
35 | 35 |
36 The primary table maps datastore keys to entities. | 36 The primary table maps datastore keys to entities. |
37 | 37 |
38 - Name: `"ents:" + namespace` | 38 - Name: `"ents:" + namespace` |
39 - Key: serialized datastore.Property containing the entity's datastore.Key | 39 - Key: serialized datastore.Property containing the entity's datastore.Key |
40 - Value: serialized datastore.PropertyMap | 40 - Value: serialized datastore.PropertyMap |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 of the suffix will always be the datastore key. The suffix is then used to call | 371 of the suffix will always be the datastore key. The suffix is then used to call |
372 back to the user, according to the query type: | 372 back to the user, according to the query type: |
373 | 373 |
374 * keys-only queries just directly return the Key | 374 * keys-only queries just directly return the Key |
375 * projection queries return the projected fields from the decoded suffix. | 375 * projection queries return the projected fields from the decoded suffix. |
376 Remember how we added all the projections after the orders? This is why. The | 376 Remember how we added all the projections after the orders? This is why. The |
377 projected values are pulled directly from the index, instead of going to the | 377 projected values are pulled directly from the index, instead of going to the |
378 main entity table. | 378 main entity table. |
379 * normal queries pull the decoded Key from the "ents" table, and return that | 379 * normal queries pull the decoded Key from the "ents" table, and return that |
380 entity to the user. | 380 entity to the user. |
OLD | NEW |