public IndexRepository(Network network, string folder, IDateTimeProvider dateTimeProvider, ILoggerFactory loggerFactory, Dictionary <string, IndexExpression> requiredIndexes = null) :
            base(network, folder, dateTimeProvider, loggerFactory)
        {
            Guard.NotNull(network, nameof(network));
            Guard.NotEmpty(folder, nameof(folder));
            Guard.NotNull(dateTimeProvider, nameof(dateTimeProvider));
            Guard.NotNull(loggerFactory, nameof(loggerFactory));

            this.tableNames = new HashSet <string> {
                "Block", "Transaction", "Common"
            };
            this.Indexes         = new ConcurrentDictionary <string, Index>();
            this.requiredIndexes = requiredIndexes;

            using (DBreeze.Transactions.Transaction transaction = this.DBreeze.GetTransaction())
            {
                transaction.SynchronizeTables("Block", "Common");
                transaction.ValuesLazyLoadingIsOn = false;

                // Discover and add indexes to dictionary and tables to synchronize.
                foreach (Row <string, string> row in transaction.SelectForwardStartsWith <string, string>("Common", IndexTablePrefix))
                {
                    if (!row.Exists)
                    {
                        continue;
                    }

                    string name  = row.Key.Substring(IndexTablePrefix.Length);
                    Index  index = Index.Parse(this, row.Value, row.Key);
                    if (index.compiled != null)
                    {
                        this.Indexes.AddOrReplace(name, index);
                        if (!this.tableNames.Contains(row.Key))
                        {
                            this.tableNames.Add(row.Key);
                        }
                    }
                }

                // Remove any index tables that are not being used (not transactional).
                foreach (string indexTable in this.GetIndexTables())
                {
                    if (!transaction.Select <string, string>("Common", indexTable).Exists)
                    {
                        this.DeleteIndexTable(indexTable);
                    }
                }
            }
        }
        public override Task InitializeAsync()
        {
            Task task = base.InitializeAsync().ContinueWith((o) =>
            {
                using (DBreeze.Transactions.Transaction transaction = this.DBreeze.GetTransaction())
                {
                    transaction.SynchronizeTables("Block", "Common");

                    // Ensure this is set so that the base code calls us to index blocks.
                    SaveTxIndex(transaction, true);

                    // Clean-up any invalid indexes.
                    foreach (Row <string, string> row in transaction.SelectForwardStartsWith <string, string>("Common", IndexTablePrefix))
                    {
                        string name = row.Key.Substring(IndexTablePrefix.Length);
                        if (!this.Indexes.ContainsKey(name))
                        {
                            DropIndex(name, transaction);
                        }
                    }

                    // Create configured indexes that do not exist yet.
                    transaction.ValuesLazyLoadingIsOn = false;
                    if (this.requiredIndexes != null)
                    {
                        foreach (KeyValuePair <string, IndexExpression> kv in this.requiredIndexes)
                        {
                            if (!this.Indexes.ContainsKey(kv.Key))
                            {
                                IndexExpression index = kv.Value;
                                this.CreateIndex(transaction, kv.Key, index.Many, index.Builder, index.Dependencies);
                            }
                        }
                    }

                    // One commit per transaction.
                    transaction.Commit();
                }
            });

            return(task);
        }