Skip to content

Caching implementation details

scale-tone edited this page Apr 16, 2017 · 2 revisions

Let's say, that an entity key is either a hashKey/rangeKey pair (if the table has both) or a hashKey (if the table only has a hashKey). Below the term "cache" means either the cache of the whole DynamoDB table or the cache of a piece of it, identified by a predefined hashKey value (if you pass that value to GetTable() method).

The following things are put to cache:

  • Entities themselves (identified by their key and serialized with BinaryFormatter).
  • Indexes. An index is a serialized DynamoDB query (a set of Query or Scan conditions) along with a set of entity keys, returned from DynamoDB for that query. An index is identified by it's key, which is a short representation of the query.
  • Projection indexes. A projection index is a serialized DynamoDB query, were a limited list of columns was requested. The query results are stored in cache along with the index (in the same cache object), so there's a limit on projection index size.
  • The list of existing indexes.

When a query is executed against the DataContext, it first tries to find an index in cache (the index must be listed in the list of indexes and must exist in cache itself). If an index is found, the cache is searched for the entities specified in the index. If at least one entity does not exist in the cache, the whole index is removed from cache and the query is redirected to DynamoDB.

When a single entity is requested by it's key, only the entity itself is loaded from cache, the indexes are not touched. Again, if the entity is missing in cache, it's requested from DynamoDB.

When an new entity is added, all known indexes are loaded from cache and the entity is checked to pass the index conditions (the conditions are converted into an Expression for that). If the newly added entity passes the index's conditions, the index is updated with this entity.

When an entity is removed, it is also removed from cache and from each existing index in cache.

When an entity is updated, it is also updated in cache.

The number of indexes stored in cache is limited to 100. This is to ensure, that cache update is never executed slower than DynamoDB update. When the limit is exceeded, the oldest indexes are explicitly removed.

NOTE: if you specify a predefined hashKey value for your entities, both "global" (without hashKey value) and "local" (associated with that hashKey value) indexes are updated in cache. So you can have both the full table and the table filtered by hashKey value in the same DataContext:

public DataTable<Review> AllReviews
{
    get
    {
        return this.GetTable<Review>
        (
            () => new EnyimTableCache(CacheClient, TimeSpan.FromDays(1))
        );
    }
}

public DataTable<Review> CurrentUserReviews
{
    get
    {
        return this.GetTable<Review>
        (
            this._curUserId,
            () => new EnyimTableCache(CacheClient, TimeSpan.FromDays(1))
        );
    }
}