Надежные коллекции Service Fabric — Применяются ли ключевые фильтры в детерминированном порядке для CreateEnumerableAsync?

#azure-service-fabric

#azure-service-fabric

Вопрос:

Я пытаюсь реализовать разбивку на страницы на основе курсора для надежного словаря. Я знаю, что IReliableDictionary ключи должны быть реализованы IComparable , и что IReliableDictionary этот метод для перечисления словарных записей:

 IAsyncEnumerable<KeyValuePair<TKey,TValue>>> 
CreateEnumerableAsync (
    ITransaction txn, 
    Func<TKey,bool> filter,
    EnumerationMode enumerationMode);
  

Когда EnumerationMode.Ordered используется, я предполагаю, что мы перечисляем пары ключ-значение в соответствии с IComparable реализацией ключа.

Можем ли мы также предположить, что filter параметр применяется к каждому ключу в порядке IComparable реализации ключа? Может быть, другой способ спросить — расположены ли ключи в памяти и / или перечислены в порядке их IComparable реализации? Если да, задокументировано ли это поведение или его следует рассматривать как деталь реализации, которая может измениться?

Ответ №1:

Я провел эксперимент, используя образец веб-сайта для голосования, и ключи, похоже, фильтруются в порядке их IComparable реализации, с некоторыми оговорками:

  • Похоже, что фильтр может запускаться несколько раз по одному и тому же ключу
  • Фильтр может быть применен к элементам, которые были недавно удалены

VotingData.Controllers.VoteDataController имеет следующие операции get и put для составления списка и добавления категорий голосования:

 [HttpPut("{name}")]
public async Task<IActionResult> Put(string name)
{
    IReliableDictionary<string, int> votesDictionary = await this.stateManager.GetOrAddAsync<IReliableDictionary<string, int>>("counts");

    using (ITransaction tx = this.stateManager.CreateTransaction())
    {
        await votesDictionary.AddOrUpdateAsync(tx, name, 1, (key, oldvalue) => oldvalue   1);
        await tx.CommitAsync();
    }

    return new OkResult();
}
  

Я изменил, Get чтобы перечислять votesDictionary по порядку, и применил фильтр, который формирует список ключей, видимых фильтром:

 [HttpGet]
public async Task<IActionResult> Get()
{
     CancellationToken ct = new CancellationToken();
     IReliableDictionary<string, int> votesDictionary = await this.stateManager.GetOrAddAsync<IReliableDictionary<string, int>>("counts");            

     var filteredKeys = new List<string>();

     using (ITransaction tx = this.stateManager.CreateTransaction())
     {
        IAsyncEnumerable<KeyValuePair<string, int>> list = await votesDictionary.CreateEnumerableAsync(tx,                                                                                                        key =>
                                                                                                     {
                                                                                                           lock (this.locker)
                                                                                                           {
                                                                                                               filteredKeys.Add(key);
                                                                                                               return true;
                                                                                                           }
                                                                                                       },
                                                                                                       EnumerationMode.Ordered);
        IAsyncEnumerator<KeyValuePair<string, int>> enumerator = list.GetAsyncEnumerator();
        List<KeyValuePair<string, int>> result = new List<KeyValuePair<string, int>>();

        while (await enumerator.MoveNextAsync(ct))
        {
            result.Add(enumerator.Current);
        }
         return this.Json(result);
    }
}
  

Я добавил ключи в словарь в случайном алфавитном порядке и обновил страницу для выполнения Get запроса. При каждом обновлении filteredKeys коллекция содержала мои записи в отсортированном алфавитном порядке. Как упоминалось выше, коллекция иногда содержала повторяющиеся записи для определенных строк. Когда я удалил элементы из коллекции и обновил страницу, я обнаружил, что удаленные ключи все еще были добавлены в filteredKeys , хотя эти элементы не были возвращены в результирующем перечислении.

Комментарии:

1. Не в восторге от принятия моего собственного ответа в этом случае — хотелось бы увидеть что-то более авторитетное. Тем не менее, эксперимент показывает, что, хотя фильтры применяются в порядке следования ключей, на них нельзя положиться для точного перечисления текущего набора ключей (никаких удаленных ключей, каждый ключ обрабатывается один раз).