public async Task MaterializeAsync(ILogStore store, byte[] secretKey = default, long?startingFrom = default, CancellationToken cancellationToken = default) { if (startingFrom == default) { startingFrom = Interlocked.Read(ref _index) + 1; } foreach (var entry in store.StreamEntries((ulong)startingFrom, secretKey)) { Interlocked.Exchange(ref _index, (long)entry.Index.GetValueOrDefault()); foreach (var @object in entry.Objects) { switch (@object.Data) { case Namespace ns: { var key = ns; Namespaces.Add(key); _namespace = key; if (!Revisions.ContainsKey(_namespace.Value)) { Revisions.Add(_namespace.Value, new Dictionary <string, ulong>(StringComparer.OrdinalIgnoreCase)); } if (!Manifest.ContainsKey(_namespace.Value)) { Manifest.Add(_namespace.Value, new Dictionary <ulong, List <Schema> >()); } if (!Roles.ContainsKey(_namespace.Value)) { Roles.Add(_namespace.Value, new List <string>()); } break; } case Schema schema: { var key = schema.Name; if (!Revisions[_namespace.Value].TryGetValue(key, out var revision)) { Revisions[_namespace.Value].Add(key, revision = 1); } if (!Manifest[_namespace.Value].TryGetValue(revision, out var manifest)) { Manifest[_namespace.Value].Add(revision, manifest = new List <Schema>()); } if (!Schemas.TryGetValue(key, out var schemaMap)) { Schemas.Add(key, schemaMap = new Dictionary <ulong, List <Schema> >()); } if (!schemaMap.TryGetValue(revision, out var list)) { schemaMap.Add(revision, list = new List <Schema>()); } manifest.Add(schema); list.Add(schema); await _events.OnSchemaAddedAsync(store, schema, cancellationToken); break; } case RevokeRole revokeRole: { if (!revokeRole.Verify()) { throw new InvalidOperationException($"invalid {revokeRole.Type}"); } if (RoleGrants.TryGetValue(_namespace.Value, out var lookup) && lookup.Count == 1 && lookup[Constants.DefaultOwnerRole].Count == 1) { throw new CannotRemoveSingleOwnerException("cannot revoke admin rights of only owner"); } break; } default: throw new NotImplementedException(@object.Data.GetType().Name); } } } }