Ejemplo n.º 1
0
        public void TableCache_IndexDoesNotResurrectAfterExpiring()
        {
            var conditions = new SearchConditions();

            conditions.AddCondition("Author", new SearchCondition(ScanOperator.NotEqual, Guid.NewGuid().ToString().ToDynamoDbEntry(typeof(string))));

            // there should be no index yet
            Assert.IsNull(this.TableCache.GetEntities(conditions, null, null, false));

            // creating an index
            using (var indexCreator = this.TableCache.StartCreatingIndex(conditions))
            {
                indexCreator.AddEntityToIndex(new EntityKey(Guid.NewGuid(), Guid.NewGuid()), this.ToDocumentConverter(BooksHelper.CreateBook(persistToDynamoDb: false)));
                indexCreator.AddEntityToIndex(new EntityKey(Guid.NewGuid(), Guid.NewGuid()), this.ToDocumentConverter(BooksHelper.CreateBook(persistToDynamoDb: false)));
            }

            this.DropIndexEntityFromCache(conditions.Key);

            // now updating the same index
            this.TableCache.UpdateCacheAndIndexes
            (
                new Dictionary <EntityKey, Document>
            {
                { new EntityKey(Guid.NewGuid(), Guid.NewGuid()), this.ToDocumentConverter(BooksHelper.CreateBook(persistToDynamoDb: false)) }
            },
                new Dictionary <EntityKey, Document>(),
                new EntityKey[] { }
            );

            // the index should still be dropped
            Assert.IsNull(this.TableCache.GetEntities(conditions, null, null, false));
            Assert.IsNull(this.TableCache.GetEntities(conditions, null, null, false));
        }
Ejemplo n.º 2
0
        public void TableCache_LocalChangesAreNeverOverwrittenWhenCreatingAnIndex()
        {
            var bookKey1 = new EntityKey(1, 1);
            var book1    = BooksHelper.CreateBook(author: "Mark Twain", numPages: 1, persistToDynamoDb: false);
            var bookKey2 = new EntityKey(2, 2);
            var book2    = BooksHelper.CreateBook(author: "Mark Twain", numPages: 2, persistToDynamoDb: false);
            var book21   = BooksHelper.CreateBook(author: "Mark Twain", numPages: 21, persistToDynamoDb: false);
            var bookKey3 = new EntityKey(3, 3);
            var book3    = BooksHelper.CreateBook(author: "Mark Twain", numPages: 3, persistToDynamoDb: false);

            // creating and filling one index with a filter
            var index1 = new SearchConditions();

            index1.AddCondition("Author", new SearchCondition(ScanOperator.Equal, "Mark Twain".ToDynamoDbEntry(typeof(string))));
            using (var indexCreator = this.TableCache.StartCreatingIndex(index1))
            {
                indexCreator.AddEntityToIndex(bookKey1, this.ToDocumentConverter(book1));
                indexCreator.AddEntityToIndex(bookKey2, this.ToDocumentConverter(book2));
            }

            // now start creating another index
            var index2 = new SearchConditions();

            using (var indexCreator = this.TableCache.StartCreatingIndex(index2))
            {
                // loading some garnish
                indexCreator.AddEntityToIndex(new EntityKey(Guid.NewGuid(), Guid.NewGuid()), this.ToDocumentConverter(BooksHelper.CreateBook(author: "Mark Twain", persistToDynamoDb: false)));
                indexCreator.AddEntityToIndex(new EntityKey(Guid.NewGuid(), Guid.NewGuid()), this.ToDocumentConverter(BooksHelper.CreateBook(author: "Mark Twain", persistToDynamoDb: false)));

                // in parallel modifying existing index
                this.TableCache.UpdateCacheAndIndexes
                (
                    new Dictionary <EntityKey, Document>
                {
                    { bookKey3, this.ToDocumentConverter(book3) }
                },
                    new Dictionary <EntityKey, Document>
                {
                    { bookKey2, this.ToDocumentConverter(book21) }
                },
                    new [] { bookKey1 }
                );

                indexCreator.AddEntityToIndex(new EntityKey(Guid.NewGuid(), Guid.NewGuid()), this.ToDocumentConverter(BooksHelper.CreateBook(author: "Mark Twain", persistToDynamoDb: false)));

                // loading the same books to the second index - these should be discarded
                indexCreator.AddEntityToIndex(bookKey2, this.ToDocumentConverter(book2));
                indexCreator.AddEntityToIndex(bookKey1, this.ToDocumentConverter(book1));
            }

            // the second index shouldn't be created
            Assert.IsNull(this.TableCache.GetEntities(index2, null, null, false));

            // the first index should now contain book3 and book21
            var expectedBooks = new[] { book3, book21 };
            var loadedBooks   = this.TableCache.GetEntities(index1, null, "NumPages", false).Select(d => (Book)d.ToObject(typeof(Book)));

            this.DeepCompareBookCollections(expectedBooks, loadedBooks);
        }
Ejemplo n.º 3
0
        public void TableCache_EntityModificationIsReflectedInIndexes()
        {
            var book    = BooksHelper.CreateBook(numPages: 150, persistToDynamoDb: false);
            var bookKey = new EntityKey(Guid.NewGuid(), Guid.NewGuid());

            // creating two filters
            var filter1 = new SearchConditions();

            filter1.AddCondition("NumPages", new SearchCondition(ScanOperator.GreaterThan, 100.ToDynamoDbEntry(typeof(int))));
            var filter2 = new SearchConditions();

            filter2.AddCondition("NumPages", new SearchCondition(ScanOperator.LessThanOrEqual, 100.ToDynamoDbEntry(typeof(int))));

            // creating two indexes
            using (var indexCreator = this.TableCache.StartCreatingIndex(filter1))
            {
                indexCreator.AddEntityToIndex(bookKey, this.ToDocumentConverter(book));
            }
            using (this.TableCache.StartCreatingIndex(filter2))
            {
            }

            // now modifying the book so, that it should disappear in index1 and appear in index2
            book.NumPages = 50;
            this.TableCache.UpdateCacheAndIndexes
            (
                new Dictionary <EntityKey, Document>(),
                new Dictionary <EntityKey, Document>
            {
                { bookKey, this.ToDocumentConverter(book) }
            },
                new EntityKey[0]
            );

            // checking index sizes
            Assert.AreEqual(0, this.TableCache.GetEntities(filter1, null, null, false).Count());
            Assert.AreEqual(1, this.TableCache.GetEntities(filter2, null, null, false).Count());
        }
Ejemplo n.º 4
0
        public void TableCache_IndexIsDiscardedIfBeingCreatedTwiceInParallel()
        {
            // creating an empty index
            var conditions = new SearchConditions();

            conditions.AddCondition("PublishYear", new SearchCondition(ScanOperator.IsNull));

            this._cacheHitCount  = 0;
            this._cacheMissCount = 0;

            Assert.IsNull(this.TableCache.GetEntities(conditions, null, null, false));
            Assert.AreEqual(this._cacheHitCount, 0);
            Assert.AreNotEqual(this._cacheMissCount, 0);


            // creating an index and interrupting it's creation
            using (this.TableCache.StartCreatingIndex(conditions))
            {
                this.TableCache.StartCreatingIndex(conditions);
            }

            this._cacheHitCount  = 0;
            this._cacheMissCount = 0;

            Assert.IsNull(this.TableCache.GetEntities(conditions, null, null, false));
            Assert.AreEqual(this._cacheHitCount, 0);
            Assert.AreNotEqual(this._cacheMissCount, 0);

            // one more time
            this._cacheHitCount  = 0;
            this._cacheMissCount = 0;

            Assert.IsNull(this.TableCache.GetEntities(conditions, null, null, false));
            Assert.AreEqual(this._cacheHitCount, 0);
            Assert.AreNotEqual(this._cacheMissCount, 0);
        }
Ejemplo n.º 5
0
        public void TableCache_ManyLargeIndexesAreCreatedAndUpdated()
        {
            const int IndexCount = 10;
            const int IndexSize  = 100;
            const int FilterSize = 10;

            var filters = new Dictionary <SearchConditions, List <EntityKey> >();
            var dt      = DateTime.Parse("1601-01-01");

            for (int i = 0; i < IndexCount; i++)
            {
                var filter = new SearchConditions();

                filter.AddCondition("Name", new SearchCondition(ScanOperator.Equal, i.ToString().ToDynamoDbEntry(typeof(string))));

                for (int j = 0; j < FilterSize; j++)
                {
                    dt = dt + TimeSpan.FromSeconds(i);
                    filter.AddCondition("LastRentTime", new SearchCondition(ScanOperator.GreaterThan, dt.ToDynamoDbEntry(typeof(DateTime))));
                }

                var entityKeys = new List <EntityKey>();
                for (int j = 0; j < IndexSize; j++)
                {
                    entityKeys.Add(new EntityKey(Guid.NewGuid(), Guid.NewGuid()));
                }

                filters[filter] = entityKeys;
            }

            Parallel.ForEach(filters, kv =>
            {
                var doc = this.ToDocumentConverter(BooksHelper.CreateBook(persistToDynamoDb: false));

                var filter = kv.Key;
                using (var indexCreator = this.TableCache.StartCreatingIndex(filter))
                {
                    foreach (var k in kv.Value)
                    {
                        indexCreator.AddEntityToIndex(k, doc);
                    }
                }
            });

            // now sequentially removing all the entities except one in each index
            foreach (var kv in filters)
            {
                foreach (var k in kv.Value.Skip(1))
                {
                    this.TableCache.UpdateCacheAndIndexes
                    (
                        new Dictionary <EntityKey, Document>(),
                        new Dictionary <EntityKey, Document>(),
                        new[] { k }
                    );
                }
            }

            // now checking, that each index contains only one entity
            Parallel.ForEach(filters, kv =>
            {
                var loadedBooks = this.TableCache.GetEntities(kv.Key, null, null, true);

                Assert.AreEqual(1, loadedBooks.Count());
            });
        }
Ejemplo n.º 6
0
        public void TableCache_IndexIsModifiedSuccessfully()
        {
            // creating two filters
            var allEntitiesFilter = new SearchConditions();
            var greaterThanFilter = new SearchConditions();

            greaterThanFilter.AddCondition("Author", new SearchCondition(ScanOperator.Equal, "Mark Twain".ToDynamoDbEntry(typeof(string))));
            greaterThanFilter.AddCondition("LastRentTime", new SearchCondition(ScanOperator.GreaterThan, DateTime.Parse("2010-01-31").ToDynamoDbEntry(typeof(DateTime))));

            // creating two empty indexes
            using (this.TableCache.StartCreatingIndex(greaterThanFilter))
            {
            }
            using (this.TableCache.StartCreatingIndex(allEntitiesFilter))
            {
            }

            // checking that indexes are empty
            Assert.AreEqual(0, this.TableCache.GetEntities(allEntitiesFilter, null, null, false).Count());
            Assert.AreEqual(0, this.TableCache.GetEntities(greaterThanFilter, null, null, false).Count());

            // adding a book outside the search filter
            var book1    = BooksHelper.CreateBook(author: "Mark Twain", lastRentTime: DateTime.MinValue, persistToDynamoDb: false);
            var bookKey1 = new EntityKey(Guid.NewGuid(), Guid.NewGuid());

            this.TableCache.UpdateCacheAndIndexes
            (
                new Dictionary <EntityKey, Document>
            {
                { bookKey1, this.ToDocumentConverter(book1) }
            },
                new Dictionary <EntityKey, Document>(),
                new EntityKey[0]
            );

            // checking index sizes
            Assert.AreEqual(0, this.TableCache.GetEntities(greaterThanFilter, null, null, false).Count());
            Assert.AreEqual(1, this.TableCache.GetEntities(allEntitiesFilter, null, null, false).Count());


            // adding a book inside the search filter
            var book2    = BooksHelper.CreateBook(author: "Mark Twain", lastRentTime: DateTime.Now, persistToDynamoDb: false);
            var bookKey2 = new EntityKey(Guid.NewGuid(), Guid.NewGuid());

            this.TableCache.UpdateCacheAndIndexes
            (
                new Dictionary <EntityKey, Document>
            {
                { bookKey2, this.ToDocumentConverter(book2) }
            },
                new Dictionary <EntityKey, Document>(),
                new EntityKey[0]
            );

            // checking index sizes
            Assert.AreEqual(1, this.TableCache.GetEntities(greaterThanFilter, null, null, false).Count());
            Assert.AreEqual(2, this.TableCache.GetEntities(allEntitiesFilter, null, null, false).Count());


            // adding one more book inside the search filter
            var book3    = BooksHelper.CreateBook(author: "Mark Twain", lastRentTime: DateTime.Now, persistToDynamoDb: false);
            var bookKey3 = new EntityKey(Guid.NewGuid(), Guid.NewGuid());

            this.TableCache.UpdateCacheAndIndexes
            (
                new Dictionary <EntityKey, Document>
            {
                { bookKey3, this.ToDocumentConverter(book3) }
            },
                new Dictionary <EntityKey, Document>(),
                new EntityKey[0]
            );

            // checking index sizes
            Assert.AreEqual(2, this.TableCache.GetEntities(greaterThanFilter, null, null, false).Count());
            Assert.AreEqual(3, this.TableCache.GetEntities(allEntitiesFilter, null, null, false).Count());

            // modifying an entity
            book3.LastRentTime = DateTime.Parse("2009-01-01");

            this.TableCache.UpdateCacheAndIndexes
            (
                new Dictionary <EntityKey, Document>(),
                new Dictionary <EntityKey, Document>
            {
                { bookKey3, this.ToDocumentConverter(book3) }
            },
                new EntityKey[0]
            );

            // checking index sizes
            Assert.AreEqual(1, this.TableCache.GetEntities(greaterThanFilter, null, null, false).Count());
            Assert.AreEqual(3, this.TableCache.GetEntities(allEntitiesFilter, null, null, false).Count());

            // removing one entity
            this.TableCache.UpdateCacheAndIndexes
            (
                new Dictionary <EntityKey, Document>(),
                new Dictionary <EntityKey, Document>(),
                new [] { bookKey1 }
            );

            // checking index sizes
            Assert.AreEqual(1, this.TableCache.GetEntities(greaterThanFilter, null, null, false).Count());
            Assert.AreEqual(2, this.TableCache.GetEntities(allEntitiesFilter, null, null, false).Count());


            // removing other two entities
            this.TableCache.UpdateCacheAndIndexes
            (
                new Dictionary <EntityKey, Document>(),
                new Dictionary <EntityKey, Document>(),
                new [] { bookKey2, bookKey3 }
            );

            // checking index sizes
            Assert.AreEqual(0, this.TableCache.GetEntities(greaterThanFilter, null, null, false).Count());
            Assert.AreEqual(0, this.TableCache.GetEntities(allEntitiesFilter, null, null, false).Count());
        }