Beispiel #1
0
        public AccountsCache(AccountMetadataService metadata, IConfiguration config, ILogger <AccountsCache> logger) : base(config)
        {
            Metadata = metadata;
            Config   = config.GetCacheConfig();
            Logger   = logger;

            Logger.LogDebug("Initializing accounts cache...");

            using var db = GetConnection();
            var totalAccounts = db.QueryFirst <int>(@"SELECT COUNT(*) FROM ""Accounts""");

            var count    = Math.Min(totalAccounts, Config.MaxAccounts);
            var capacity = count < Config.MaxAccounts
                ? Math.Min((int)(count * 1.1), Config.MaxAccounts)
                : Config.MaxAccounts;
            var sql = @"
                SELECT   *
                FROM     ""Accounts""
                ORDER BY ""LastLevel"" DESC
                LIMIT    @limit";

            using var reader = db.ExecuteReader(sql, new { limit = (int)(count * Config.LoadRate) });

            var userParser     = reader.GetRowParser <RawUser>();
            var delegateParser = reader.GetRowParser <RawDelegate>();
            var contractParser = reader.GetRowParser <RawContract>();

            AccountsById      = new Dictionary <int, RawAccount>(capacity);
            AccountsByAddress = new Dictionary <string, RawAccount>(capacity);

            while (reader.Read())
            {
                RawAccount account = reader.GetInt32(2) switch
                {
                    0 => userParser(reader),
                    1 => delegateParser(reader),
                    2 => contractParser(reader),
                    _ => throw new Exception($"Invalid raw account type")
                };

                AccountsById.Add(account.Id, account);
                AccountsByAddress.Add(account.Address, account);
            }

            Logger.LogDebug($"Loaded {AccountsByAddress.Count} of {totalAccounts} accounts");
        }
Beispiel #2
0
        public async Task <List <(int Id, string Address)> > Update(int fromLevel)
        {
            var sql = @"
                SELECT   *
                FROM     ""Accounts""
                WHERE    ""LastLevel"" >= @fromLevel";

            using var db     = GetConnection();
            using var reader = await db.ExecuteReaderAsync(sql, new { fromLevel });

            var userParser     = reader.GetRowParser <RawUser>();
            var delegateParser = reader.GetRowParser <RawDelegate>();
            var contractParser = reader.GetRowParser <RawContract>();

            var accounts = new List <(int Id, string Address)>(64);

            await Sema.WaitAsync();

            while (reader.Read())
            {
                RawAccount account = reader.GetInt32(2) switch
                {
                    0 => userParser(reader),
                    1 => delegateParser(reader),
                    2 => contractParser(reader),
                    _ => throw new Exception($"Invalid raw account type")
                };

                AccountsById[account.Id]           = account;
                AccountsByAddress[account.Address] = account;

                accounts.Add((account.Id, account.Address));
            }

            Logger.LogDebug($"Updated {accounts.Count} accounts");

            Sema.Release();

            CheckCacheSize();

            return(accounts);
        }