powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Класс редактирования данных. Нужны советы по реализации
7 сообщений из 7, страница 1 из 1
Класс редактирования данных. Нужны советы по реализации
    #38747296
lepixa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть задача: написать класс, позволяющий редактировать данные в памяти. Указатель на данные и их начальный размер передаются в конструктор. Редактирование, на первый взгляд, тривиальное и реализуется тремя методами класса:
Код: plaintext
1.
2.
3.
void Change(unsigned long StartByte, const void *NewData, unsigned long DataSize);
void Delete(unsigned long StartByte, unsigned long Size);
void Insert(unsigned long StartByte, const void *Data, unsigned long DataSize);

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

Представим, есть объект класса с переданным ему для редактирования блоком данных. Допустим, у нас произошел последовательный вызов таких методов:
Код: plaintext
1.
2.
3.
Insert(5, MyData, 10); // Вставляем между 4-ым и 5-ым байтами 10 байтов MyData.
Delete(7, 2);          // Удаляем 7-ой и 8-ой байты.
Delete(4, 10);         // Удаляем с 4-го по 13-ый байты.

На деле, такая запись аналогична записи:
Код: plaintext
1.
Delete(4, 2);

Поэтому реальное изменение данных "на лету" не оптимально, если учесть, что промежуточный результат (как я уже писал) мне не интересен. "Компоновкой" получившегося должен заниматься отдельный метод, возвращающий результат всей работы объекта:
Код: plaintext
1.
unsigned long GetData(void *Buffer, unsigned long BufferSize);

Осталось только придумать, как хранить и обрабатывать информацию о поступивших изменениях. Вот с этим-то у меня и затык. Ничего, что очевидно выигрывает у memcpy() и memmove() по скорости и ресурсам, в голову не приходит. Поделитесь своими мыслями.

Ах, да! Чуть не забыл главное условие: никаких стандартных и, уж тем более, сторонних библиотек. Только "чистый" C++ и WinAPI.
...
Рейтинг: 0 / 0
Класс редактирования данных. Нужны советы по реализации
    #38747310
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lepixaПоэтому возникла мысль не изменять данные при каждом вызове методов, а только
лишь сохранять информацию об изменениях. А когда будет запрошен результат, тогда уж и
формировать его.
Мысль забавная, но бесперспективная.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Класс редактирования данных. Нужны советы по реализации
    #38747364
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну почему же бесперспективная?
Если каждое изменение по отдельности требует некоторого старт-стопа у которых большой оверхед, и можно все операции сгруппировать в один общий пакет (как пример рисование в OpenGL), то озвученный подход очень даже правильный и перспективный.
А если нужно иметь историю изменений с возможностью просмотра полного лога изменений, то это будет единственным возможным решением.

Хотя для примитивной арифметики это действительно будет из пушки по воробьям.

А по существу вопроса:
Сделай себе класс "изменение".
В главном классе сделай вектор с элементами этого типа.
А по GetData() будешь пробегать по вектору и накладывать все изменения по очереди. И в конце записывать полученный результат в стартовое значение и чистить вектор.
Все просто и легко.
...
Рейтинг: 0 / 0
Класс редактирования данных. Нужны советы по реализации
    #38747373
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lepixa
Казалось бы, все просто: выделяй память, заменяй, удаляй, добавляй... Однако в процессе редактирования данных промежуточные итоги мне не нужны - требуется только конечный результат. Поэтому возникла мысль не изменять данные при каждом вызове методов, а только лишь сохранять информацию об изменениях. А когда будет запрошен результат, тогда уж и формировать его.



Не сомневаюсь, что такие технологии уже используются. Вам нужно написать метод, на входе будет очередь операций FIFO, например , на выходе оптимизированный стек операций.

Да, тогда все ваши методы и т.п. будут не реентерабельны.
...
Рейтинг: 0 / 0
Класс редактирования данных. Нужны советы по реализации
    #38747399
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хранить несложно, пиши в массив лог изменений. При хранении придется также хранить MyData для инсертов.

Сложно вот это:
lepixa... Представим, есть объект класса с переданным ему для редактирования блоком данных. Допустим, у нас произошел последовательный вызов таких методов:
Код: plaintext
1.
2.
3.
Insert(5, MyData, 10); // Вставляем между 4-ым и 5-ым байтами 10 байтов MyData.
Delete(7, 2);          // Удаляем 7-ой и 8-ой байты.
Delete(4, 10);         // Удаляем с 4-го по 13-ый байты.

На деле, такая запись аналогична записи:
Код: plaintext
1.
Delete(4, 2);


Начни с того что попробуй реализовать это упрощение. ИМХУ получится долгоиграющая считалка, которая сожрет все сэкономленное время.

Такие задачи решаются по другому: почитай как это устроено в MSSQL-сервере (в книгах по нему это подробно расписано). Если упрощенно: там идет постраничное хранение, физически страницы в памяти не по порядку, есть отдельный индекс страниц (хранящий их логический порядок), страницы заполнены неполностью, в случае вставки просто дописываются в нужную страницу, если ее нехватает - создается пустая страница и исправляется индекс. Изменения вносятся сразу, но для вставки не требуется сдвигать весь хвост, сдвиг только в пределах страницы.

lepixaОднако в процессе редактирования данных промежуточные итоги мне не нужны - требуется только конечный результат.
Тогда это можно распараллелить: первый поток просто ставит задания на изменения в очередь, а второй читает и вносит эти изменения в данные. Но тут остается проблема с хранением MyData для инсертов.
...
Рейтинг: 0 / 0
Класс редактирования данных. Нужны советы по реализации
    #38747545
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lepixaКазалось бы, все просто: выделяй память, заменяй, удаляй, добавляй... Однако в процессе редактирования данных промежуточные итоги мне не нужны - требуется только конечный результат. Поэтому возникла мысль не изменять данные при каждом вызове методов, а только лишь сохранять информацию об изменениях. А когда будет запрошен результат, тогда уж и формировать его.

Мысль весьма сомнительна. Она будет "играть" только если подготовителные операции для одного изменения велики по сравнению
с этим изменением, и изменений много (и к каждому изменению подготовка одинакова).
В условиях, когда кол-во и качество изменений диктуется извне (клиентом класса), ещё более сомнительна.
...
Рейтинг: 0 / 0
Класс редактирования данных. Нужны советы по реализации
    #38747547
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lepixaОсталось только придумать, как хранить и обрабатывать информацию о поступивших изменениях. Вот с этим-то у меня и затык. Ничего, что очевидно выигрывает у memcpy() и memmove() по скорости и ресурсам, в голову не приходит. Поделитесь своими мыслями.


А там ничего более и не нужно.
А для реализации отложенных модификаций -- паттерн Command и потом его проигрывание.

Я рекомендую всё же сделать сначала простейшую реализацию, а затем уже усложнять оптимизациями.
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Класс редактирования данных. Нужны советы по реализации
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]