![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
Alex13 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 280 Регистрация: 30.12.2005 Где: Новосибирск Репутация: нет Всего: 1 |
Бекграунд.
Дабы вы смогли луше понять мой вопрос, изложу общую задачу. Пишу кеширующий HTTP прокси-сервер с пулом рабочих потоков и poll()'ом в основе, в рамках курсовой, кеш должен жить в оперативной памяти. Помимо прочего требуется корректно отрабатывать такой сценарий: 1) Приходит запрос, в целом удовлетворяющий требованиям для помещения в кеш. 2) Начинается загрузка файла в кеш. При этом файл отдается в chunked encoding, т. е. в заголовке его длина не указывается. 3) Параллельно из записи в кеше данные начинают отдаваться клиенту. 4) В это время приходит второй запрос к тому же адресу. Вместо того, чтобы начать его качать еще раз мы, естественно, присасываемся к существующей (недокачанной) записи кеша и так же начинаем отдавать оттуда данные по мере появления. 5) Спустя некоторое время мы видим, что файл оказался большой (например, скачали 100 мб и продолжаем качать) и в память рискует не поместиться, поэтому мы переключаемся в "разрушающий" режим работы буффера кеша. При этом данные, которые были отправлены всем успевшим подключиться должны из буфера удаляться, чтобы освободить память. Естественно, после этого момента подключение новых клиентов к этой записи кеша уже невозможно. 6) После того, как файл докачался и был отдан всем клиентам, запись кеша уничтожается. Задача По замыслу происходить это будет так: один "логический" поток (т. е. общая последовательность действий, хоть она и может исполняться разными воркерами) будет качать файл и писать в кеш, другой - отдавать клиенту. Мне требуется структура данных, буффер, удовлетворяющий следующим требованиям: 1) Динамически расширяющийся, хранящийся в памяти. 2) Поддержка нескольких независимых читателей, каждый со всоим "курсором". 3) Данные, записанные в буффер тут же становятся доступны всем читателям. 4) Возможность на лету переключиться в "разрушающий" режим, описанный выше. 5) Желательно, чтобы довыделение памяти происходило блоками настраиваемого размера, чтобы уменьшить количество выделений памяти. 6) Желательно, чтобы все это реализовывало интерфейс стандартных потоков ввода-вывода. Понимаю, что требования довольно крутые, но если удастся их выполнить, что будет прямо рай на земле, а не прокси. Найденные решения Ничего лучше std::stringstream я так и не нашел, но он удовлетворяет лишь двум требованиям из 6. Вопрос Знает ли кто-нибудь готовый класс, реализующий все эти плюшки или компоненты, от которых можно оттолкнуться при написании такого класса самостоятельно? -------------------- Самая страшная ошибка - это ошибка, не имеющая явных причин и конкретных последствий. Антисоциальный блог. |
|||
|
||||
Леопольд |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
http://www.cplusplus.com/reference/stl/deque/
за основу Это сообщение отредактировал(а) Леопольд - 30.11.2010, 22:08 -------------------- вопросов больше чем ответов |
|||
|
||||
Alex13 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 280 Регистрация: 30.12.2005 Где: Новосибирск Репутация: нет Всего: 1 |
Спасибо за ответ, однако этот класс фактически решает только проблему динамического расширения и быстрого добавления/удаления элементов. Однако он при этом дает пачку новых проблем:
1) Если элементами очереди делать просто char, то операция чтения становится убийственно медленной штукой, поскольку разрозненные чары (по спецификации они не обязаны храниться подряд в памяти) надо будет собрать в один блок и только потом вернуть. Но по логике кеша чтение из него производится несколько раз, а запись - только один и лучше уж иметь быстрое чтение и медленную запись, чем наоборот. 2) Если элементами очереди сделать блоки чаров, то будут сложности с позиционированием курсора чтения с точностью большей чем до одного блока и обработкой кусков данных, не кратных размеру блока. В свете вышесказанного мне больше нравится vector или string, но для них все равно придется самостоятельно реализовывать большую часть требований. -------------------- Самая страшная ошибка - это ошибка, не имеющая явных причин и конкретных последствий. Антисоциальный блог. |
|||
|
||||
Леопольд |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Этот умеет незаметно перераспределять память. Операция push_back (и даже push_front) лекго может заинвалидить все текущие итераторы (aka указатели). А ещё он хорошо растёт вверх, но вниз не очень. Т.е. не освобождает выделенную память, а оставляет на потом.
deque этим не страдает, и из/в неё можно удалять/добавлять не по одному инстансу а пачками. http://cplusplus.com/reference/stl/deque/insert/ http://cplusplus.com/reference/stl/deque/erase/ Память она выделяет/освобождает блоками фиксированного размера. Итераторы с рандомным доступом. Несколько медленнее чем у вектора, ведь надо сперва посчитать к какому блоку итератор относится, потом вычислить индекс (указатель) в этом блоке, после чего можно получить элемент. Но не настолько:
Из STL, deque лучше всего подходит под предъявленные требования. Это сообщение отредактировал(а) Леопольд - 1.12.2010, 14:26 -------------------- вопросов больше чем ответов |
|||
|
||||
Alex13 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 280 Регистрация: 30.12.2005 Где: Новосибирск Репутация: нет Всего: 1 |
А вот это уже звучит интереснее, спасибо.
Хотя мне не обязательно было использовать только STL, решение звучит заманчиво. Пока я дожидался ответа, я наткнулся на Boost.Iostreams, что дает уже неплохую базу вместе с deque. -------------------- Самая страшная ошибка - это ошибка, не имеющая явных причин и конкретных последствий. Антисоциальный блог. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |