|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
Привет всем! Имеется последовательность элементов вот такого вида: Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
Нужно придумать структуру данных для хранения этой последовательности, чтобы она обслуживала вот такой алгоритм: Есть два потока - обновлятель и читатель. Читатель должен иметь возможность 1. Наблюдать эту последовательность всегда упорядоченной по Level 2. Безопасно итерировать по ней без блокировок Обновлятель должен уметь 1. вставлять новые элементы. Что есть новый и что не новый определяется по Id 2. удалять существующие 3. обновлять измеренные значения. В идеале и Level тоже, но если не получится - переживу 4. избегать копирования больших объемов данных при вставках и удалениях 5. по возможности выполнять перечисленные операции за логарифмическое время Изменения происходят со скоростью 10^2 в секунду. Длина последовательности порядка 10^4. Несколько независимых экземпляров этого алгоритма должны работать в одном процессе с разными, никак не связанными экземплярами последовательностей. Экземпляров этих будет порядка 10^1. Читатель просматривает последовательность несколько раз в секунду. Важно, чтобы он всегда просматривал ее в порядке убывания Level. Допустимо, что во время просмотра обновлятель что-то поменяет. Главное, чтобы это обновление не обрушило читателю foreach и не привело к тому, что порядок просмотра перестанет быть упорядочен по Level. Мысли крутятся вокруг очереди с приоритетом. Но тут есть два независимых ключа, по одному идет поиск, а по другому - сортировка. Этого известный мне алгоритм очереди с приоритетом на основе бинарной кучи не поддерживает. Язык реализации C#. Спасибо ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2018, 13:33 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
SergASh1. Наблюдать эту последовательность всегда упорядоченной по Level А где "эта" последовательность? Measurement1-MeasurementN ? Как она может быть упорядочена по Level? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2018, 13:46 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
Извините вопрос снимается. Невнимательно прочитал условие ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2018, 13:47 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
SergASh, попробуйте ConcurrentBag<T> из https://msdn.microsoft.com/library/Dd997305(v=VS.100).aspx?f=255&MSPPError=-2147217396 orderby для просмотра можно любой сделать ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2018, 13:56 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
Cat2, задание мне тут видится академическое и важно сама реализация такой последовательности. как я понял из задания, для многопоточности использовать надо ReaderWriterLockSlim в качестве коллекции использовать LinkedList Чтоб коллекция всегда была сортированной, нам нужно найти то место, куда вставляем элемент, находим такой элемент через бинарный поиск у которого сложность как раз O(log(n)) и вставляем. Всё остальное, точно так же. и т.д. и т.п. бесплатное такое точно делать не будут. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2018, 14:25 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
SergASh2. Безопасно итерировать по ней без блокировок Roman Mejtes, А п.п. выше как будет работать без блокировок? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2018, 14:40 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
Cat2SergASh, попробуйте ConcurrentBag<T> из orderby для просмотра можно любой сделать orderby означает копирование всего контейнера и потом сортировку. Это, мягко говоря, не очень эффективно ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2018, 15:11 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
SergASh, Для foreach блокировка по любому нужна при изменении. Неважно на каком уровне кода. Imho ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2018, 15:15 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
SergAShCat2SergASh, попробуйте ConcurrentBag<T> из orderby для просмотра можно любой сделать orderby означает копирование всего контейнера и потом сортировку. Это, мягко говоря, не очень эффективно Так как раз и получится "версионная" изолированность обработки, что вроде и надо автору SergAShДопустимо, что во время просмотра обновлятель что-то поменяет. Главное, чтобы это обновление не обрушило читателю foreach и не привело к тому, что порядок просмотра перестанет быть упорядочен по Level. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2018, 15:24 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
Во время foreach коллекцию менять нельзя в принципе - это в сам .NET встроено. Будет иксепшен. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2018, 16:48 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
смысл в том, чтоб вставлять элементы с учётом их положения после сортировки. Так как список изначально (по заданию) сортирован для него доступен бинарый поиск, который соответствующий "логорифмической сложности" O(log2n) что соответствует заданию Нужно найти положение элемента и вставить его через Insert в List<T> Вот примерный, вариант для вставки элемента в коллекцию, с учётом сортировки Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2018, 20:58 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
Roman Mejtes Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
слегка подправил ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2018, 21:01 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
В данном примере идет вставка с задержкой в 10 мс (10^2 в секунду) элементов MyStruct, генерируются значения случ. образом. Каждую секунду коллекция перебирается, подсчитывается её размер и суммарный Measurement и отображается на экран В коллекции _list элементы всегда в обратной сортировке по Level, по этому читая итератором всегда нужная последовательность. Добавление\Обновление происходит с O(log2n) Пример на коленке сделан, сильно не судите строго Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121.
... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2018, 22:13 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
Roman Mejtes, внутри List обычный массив, как следствие вставка и удаление требуют сдвига всех последующих элементов, что не быстро и чем ближе к началу - тем медленнее. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.06.2018, 09:32 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
>SergASh, вчера, 13:33 http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1296919&msg=21518500][21518500] >… Есть два потока - обновлятель и читатель. Рассмотри вариант, когда обновлятель измерения пишет не в основной список, а в промежуточный циклический массив. Читатель с нужной для него скоростью сначала обрабатывает циклический массив с переписью информации в основной список, а уж затем сканирует основной список. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.06.2018, 11:26 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
fkthatВо время foreach коллекцию менять нельзя в принципе - это в сам .NET встроено. Будет иксепшен.А если свой Enumerator реализовать? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.06.2018, 12:46 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
Dima T, В List<T> для получения элемента коллекции по индексу требует O(1), а у LinkedList O(n). Вставка в массив это часть алгоритма и она входит в (n), я пренебрегаю данный работой и считаю её за N. То есть на требования задачи это не влияет. А вообще есть класс SortedSet<T>, в нём сразу реализовано бинарное дерево и всё остальное, можно использовать его. По сути тоже самое. B для вставки, удаления и извлечения объекта там сложно O(log n) ... |
|||
:
Нравится:
Не нравится:
|
|||
26.06.2018, 12:54 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
refregfkthatВо время foreach коллекцию менять нельзя в принципе - это в сам .NET встроено. Будет иксепшен.А если свой Enumerator реализовать? Если свой, то, как бы, можно. Только при этом можно легко нарваться на всякие неприятные вещи, типа, перечисления одного и того же элемента два раза, или наоборот пропуска какого-нибудь элемента. От этого в стандартные коллекции фреймворка и встроена защита в виде запрета на изменение. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.06.2018, 15:20 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
fkthat, Даже не в ошибке дело, а в самом смысле. Как будем ходить по элементам если спереди могут всё грохнуть, сзади и прямо под ногами другим потоком? Смысл foreach - обойти список весь, а не топать где ступенька появилась. Единственный вариант без блока это версионность, но подходит ли по условию это к ТС. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.06.2018, 15:44 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
fkthatrefregпропущено... А если свой Enumerator реализовать?Если свой, то, как бы, можно. Только при этом можно легко нарваться на всякие неприятные вещи, типа, перечисления одного и того же элемента два раза, или наоборот пропуска какого-нибудь элемента. От этого в стандартные коллекции фреймворка и встроена защита в виде запрета на изменение.То есть ты против тех задания? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.06.2018, 16:32 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
Petro123fkthat, Даже не в ошибке дело, а в самом смысле. Как будем ходить по элементам если спереди могут всё грохнуть, сзади и прямо под ногами другим потоком? Смысл foreach - обойти список весь, а не топать где ступенька появилась. Единственный вариант без блока это версионность, но подходит ли по условию это к ТС. надо CQRS + ES :) ... |
|||
:
Нравится:
Не нравится:
|
|||
26.06.2018, 16:33 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
>SergASh, вчера, 13:33 http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1296919&msg=21518500] [21518500] >Имеется последовательность… int ID можно ли рассматривать в качестве индекса "последовательности (вектора) порядка 10^4"? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.06.2018, 19:00 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
ВМоисеевint ID можно ли рассматривать в качестве индекса "последовательности (вектора) порядка 10^4"? По ID элементы последовательности уникальны. Но они идут не подряд, а случайно. Так что выделить память под все возможные айди не получится если в этом был вопрос ... |
|||
:
Нравится:
Не нравится:
|
|||
27.06.2018, 09:39 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
Roman MejtesDima T, А вообще есть класс SortedSet<T>, в нём сразу реализовано бинарное дерево и всё остальное, можно использовать его. По сути тоже самое. B для вставки, удаления и извлечения объекта там сложно O(log n) SortedSet<T> отсортирован по одному ключу. Чтоб найти там элемент по другому ключу нужен полный перебор. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.06.2018, 09:45 |
|
Хитрая очередь с приоритетом без блокировок
|
|||
---|---|---|---|
#18+
Petro123fkthat, Как будем ходить по элементам если спереди могут всё грохнуть, сзади и прямо под ногами другим потоком? Смысл foreach - обойти список весь, а не топать где ступенька появилась. Единственный вариант без блока это версионность, но подходит ли по условию это к ТС. Эта дилемма понятна. Либо версионность и копирование, либо скорость и хождение по постоянно меняющейся структуре. В этой задаче выбор в пользу последнего. Если вам известен способ достичь версионности более экономно, чем копированием, то хотелось бы узнать как. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.06.2018, 09:48 |
|
|
start [/forum/topic.php?fid=20&tid=1399316]: |
0ms |
get settings: |
8ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
75ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
67ms |
get tp. blocked users: |
1ms |
others: | 313ms |
total: | 499ms |
0 / 0 |