openlang

Нужен ли этой очереди сохранённый счётчик?

Вызывающий код спрашивает у этой очереди только List.length items > 8, зато спрашивает постоянно. Очередь представлена одним неизменяемым списком OCaml, и каждое обновление возвращает новую очередь. Вариантов два. Хранить точное количество или дать запрос на порог.

С (items, count) образец пары даёт имена обоим компонентам, и с этого момента count = List.length items должно выполняться после каждого обновления. Добавление увеличивает счёт на один. Успешное извлечение уменьшает на один. Извлечение из пустой очереди оставляет ноль. Любой конструктор, принимающий оба компонента, тоже обязан держать их согласованными.

Вариант с порогом меньше. List.compare_length_with items 8 > 0 прямо выражает то, что нужно вызывающему, а документация OCaml 5.4 говорит, что это сравнение может остановиться не более чем через заданное число итераций. Сейчас само количество никто не запрашивает, и поэтому я сомневаюсь, стоит ли его хранить.

Разговор продолжается 4

Следуя доводам
  1. Ссылка на ответ

    Может, начнём с самого вопроса? exceedsLimit queue limit, с требованием, чтобы лимит был неотрицательным. Вызывающий код получает ровно тот ответ, который ему нужен, а очереди не приходится заводить второй компонент и следить за его честностью. Внутри для этого представления работу сделает List.compare_length_with.

    Если вызывающий код решает, принимать ли работу, можно назвать исходы WithinLimit и OverLimit, так ветки читаются легче. Обычный булев результат тоже годится, когда окружающий if уже объясняет различие. Оборачивать сравнение в случаи ради самих случаев не стоит.

    Если точное количество понадобится где-то ещё, кэш можно добавить тогда. И тогда создание и обновления стоит спрятать за тем же интерфейсом, чтобы никто из вызывающих не мог подменить items или count по отдельности. Пожалуй, пока такой модели достаточно.

  2. Ссылка на ответ

    OverLimit говорит производителю остановиться. А дальше? Если производители на этом блокируются, посчитайте их. Горутина, застрявшая на полном канале, обходится дёшево, но сколько их там может скопиться, ничто не ограничивает. Лимит очереди просто переносит кучу туда, где её никто не измеряет.

  3. Ссылка на ответ

    Вынесите этот интерфейс в .mli, объявив type t без определения, и ничто за пределами модуля не соберёт пару вручную. Тогда добавление счётчика позже затронет один файл, а у инварианта будет ровно одно место, где он может сломаться.

  4. Ссылка на ответ

    Ничего, пока сам что-то не добавишь. В Kotlin Channel с фиксированной ёмкостью приостанавливает send, когда заполнен, и каждый приостановленный отправитель остаётся живой корутиной со всем, что он захватил. Их ровно столько, сколько ты запустил. Ограничь запуски или поставь впереди Semaphore.

Другие стороны того же вопроса

  1. Порядок циклов для Fortran с хранением по столбцам

    Массивы в Fortran хранятся по столбцам. a(i,j) и a(i+1,j) в памяти соседи. a(i,j+1) отстоит на целый столбец. Значит, цикл, к…

    Ответы 1fortran