Название: QSharedPointer и/или implicit sharing? Отправлено: Igors от Апрель 21, 2019, 08:24 Добрый день
Типовая ситуация: есть объекты которые могут интенсивно дублироваться. Объекты имеют весомые данные которые хотелось бы иметь шареными, обычно всякие контейнеры (но не объекты целиком). Однако в любой момент юзер может изменить любую копию, и она становится уникальной. Затем может и нажать undo - нужно как-то опять зашарить. Также есть возможность изменить сразу N копий, если делать по уму, их тоже надо шарить. Также I/O - нужно как-то поддерживать шаринг на записи и чтении. Конечно "как-то" сделать можно, но хотелось бы тщательнее продумать перед реализацией. Поделитесь опытом. Спасибо Название: Re: QSharedPointer и/или implicit sharing? Отправлено: Авварон от Апрель 21, 2019, 22:56 Забавно как этот анду постоянно вылезает:)
Но собственно "зашарить обратно"... зачем? Как вы храните анду реду? Диффами или стейтом? Если диффами, то ничего шарить не надо - на старый стейт применили дифф, получили новый, итого объект один. Если стейтом, то надо всегда "шарить" иначе потеряется новый стейт при анду и реду сделать не выйдет. Как всегда в постановке не видно проблемы, но щаз выяснятся "детали" Название: Re: QSharedPointer и/или implicit sharing? Отправлено: Igors от Апрель 22, 2019, 07:45 Забавно как этот анду постоянно вылезает:) Это норм, undo - прекрасная проверка архитектуры на вшивостьНо собственно "зашарить обратно"... зачем? Как вы храните анду реду? Диффами или стейтом? Если диффами, то ничего шарить не надо - на старый стейт применили дифф, получили новый, итого объект один. Если стейтом, то надо всегда "шарить" иначе потеряется новый стейт при анду и реду сделать не выйдет. Ну если ничего не делать (как собсно Вы предлагаете) - то и проблем никаких не увидеть :) Как всегда в постановке не видно проблемы, но щаз выяснятся "детали" Ладно, копнем. Диффы сразу отбросим. Я думаю по сути тут решение одно: мапа/хеш, и простая логика типа: данные с таким ключом есть в хеше? Да - берем их, нет - заводим новые и помещаем в хеш. Подобная задачка когда-то у меня была, запомнилось что применить вумные указатели не удалось. В самом деле - если в хеше сидит QSharedPointer - клиент его не удалит. Можно хранить в хеше weak, но это выглядит как-то странно, да и неаккуратно - надо как-то подчищать неиспользуемые трупики. В общем тогда я ничего не придумал и сделал по-народному со счетчиком ссылок. Актуально редактирование - хотелось бы иметь поведение имплисит шары, но с учетом мапы/хеша. Название: Re: QSharedPointer и/или implicit sharing? Отправлено: ssoft от Апрель 22, 2019, 08:03 Никаких хешей не нужно.
Если состояния хранятся целиком, то * Перед операцией запоминаем состояние со всеми имплисит шаред контейнерами. * Изменяем данные текущего состояния. Здесь контейнеры копируются при необходимости, но состояние, которое мы запомнили, всё также неизмененный имплисит шаред. * В случае undo, просто возвращаемся к запомненному состоянию. При необходимости redo, предварительно запоминаем измененное состояние. Танцы вокруг хеша могут существенно нагрузить логику программы и процессор. Частый поиск в хеше, необходимость чистки и т.п. еще тот геморрой. Название: Re: QSharedPointer и/или implicit sharing? Отправлено: RedDog от Апрель 22, 2019, 09:11 Танцы вокруг хеша могут существенно нагрузить логику программы и процессор. Частый поиск в хеше, необходимость чистки и т.п. еще тот геморрой. Зачем тогда в компе процессор нужен, если его не нагружать?Название: Re: QSharedPointer и/или implicit sharing? Отправлено: ssoft от Апрель 22, 2019, 10:04 Зачем тогда в компе процессор нужен, если его не нагружать? Чтобы эффективно нагружать полезной логикой, а не просто воздух греть).Тем более, что здесь речь идет о высокопроизводительной графике, всяких fps60+))). Название: Re: QSharedPointer и/или implicit sharing? Отправлено: Igors от Апрель 22, 2019, 12:02 Никаких хешей не нужно. Ничего не понял. Вот пример/псевдокод чего я хочуЕсли состояния хранятся целиком, то * Перед операцией запоминаем состояние со всеми имплисит шаред контейнерами. * Изменяем данные текущего состояния. Здесь контейнеры копируются при необходимости, но состояние, которое мы запомнили, всё также неизмененный имплисит шаред. * В случае undo, просто возвращаемся к запомненному состоянию. При необходимости redo, предварительно запоминаем измененное состояние. Танцы вокруг хеша могут существенно нагрузить логику программы и процессор. Частый поиск в хеше, необходимость чистки и т.п. еще тот геморрой. Код При этом если измененный контейнер данных уже существует - он должен шариться (вместо создания нового как делает Qt имплисит шара). Не вижу как тут обойтись без хеша/мапы Чтобы эффективно нагружать полезной логикой, а не просто воздух греть). Тогда для Вас свежая задачка в Говорилка > Геометрия :) Увы, за хорошими словами часто скрывается любовь не к графике, а богомерзким железкам (подороже)Тем более, что здесь речь идет о высокопроизводительной графике, всяких fps60+))). Название: Re: QSharedPointer и/или implicit sharing? Отправлено: ssoft от Апрель 22, 2019, 15:45 На вскидку такой прототип решения
Код
Название: Re: QSharedPointer и/или implicit sharing? Отправлено: Igors от Апрель 23, 2019, 09:21 На вскидку такой прототип решения Ой, мама :) По поводу undo - у меня оно льется в файл перед тем как данные "честно" удаляются. При выполнении undo - читаются из файла. Т.е. ситуация в принципе такая же как и "юзер изменил данные", только источник изменений другой.Хотелка - шарить вновь прибывшие данные (без разницы откуда они пришли). Конечно это имеет смысл если дубликатов ожидается много - ну так оно и есть. "Не мудрствуя лукаво" это можно сделать напр так (распишем пример выше) Код: void SetIndex( SomeClass & target, int index, int value ) Да, но.. это как-то совсем "не современно" и " не модно" :) Ведь колоссальный арсенал современных средств никак не используется. Ну вот совсем никак. Неужели нет ничего лучшего чем "жалкий велик"? :) Такое же недоумение по поводу организации хеша/мапы (кстати о птичках: выбор между ними здесь не очевиден). Как и неск лет назад, я в упор не вижу ничего лучшего чем завести ручной счетчик ссылок. Название: Re: QSharedPointer и/или implicit sharing? Отправлено: Авварон от Апрель 24, 2019, 10:45 Так ну если состояние в файл сброшено, то что шарить?
Название: Re: QSharedPointer и/или implicit sharing? Отправлено: Igors от Апрель 24, 2019, 14:23 Так ну если состояние в файл сброшено, то что шарить? Сама запись в файл ничего не меняет, все как и было так и осталось шареным. Но если данные удалены а затем читаются из файла (нажато undo), то они "примкнут" к шареным, новых экземпляров создаваться не будет. Название: Re: QSharedPointer и/или implicit sharing? Отправлено: ssoft от Апрель 24, 2019, 15:05 Чтобы восстановить шару, нужен какой-то ключ. Либо контрольная сумма, либо любой другой уникальный признак, чтобы отобразить его в конкретную шару.
Если такой признак получить невозможно, то придется сравнивать сами данные. А это может быть ресурсоемко (создать->сравнить со всеми->удалить, если такие данные уже есть). В любом случае требуется наличие некоторого менеджера шар, который собственно их восстановлением и будет заниматься. Так как это частный случай, то менеджер шар придется писать самостоятельно. А случай здесь частный, так как признак отображения и способ отображения признака в шару зависят от конкретной прикладной задачи. Название: Re: QSharedPointer и/или implicit sharing? Отправлено: Igors от Апрель 24, 2019, 15:38 Чтобы восстановить шару, нужен какой-то ключ. Либо контрольная сумма, либо любой другой уникальный признак, чтобы отобразить его в конкретную шару. Да, ключи здесь - головнякЕсли такой признак получить невозможно, то придется сравнивать сами данные. А это может быть ресурсоемко (создать->сравнить со всеми->удалить, если такие данные уже есть). Да, сравнение напр вектора индексов может быть затратно. В любом случае требуется наличие некоторого менеджера шар, который собственно их восстановлением и будет заниматься. Ну вот, как обычно, теория/прогресс "умывает руки", и я остаюсь со своими великами :) Случай, мол, "частный". Никак не могу с Вами согласиться. Конкретика здесь только в ключах, необходимость оптимизации дубликатов - задача весьма типовая.Так как это частный случай, то менеджер шар придется писать самостоятельно. А случай здесь частный, так как признак отображения и способ отображения признака в шару зависят от конкретной прикладной задачи. Пример: банальное текстурирование объектов - каждый может иметь N текстур, при этом даже на одном объекте они частенько повторяются, а сами объекты могут интенсивно дублироваться. Так что мне, грузить все текстуры подряд? Это просто не катит т.к. может занять десятки минут, да и карта наверное свалится в эмуляцию. Название: Re: QSharedPointer и/или implicit sharing? Отправлено: Igors от Апрель 24, 2019, 15:48 Ну хорошо, вот хотелось бы поговорить об организации мапы/хеша. Я вижу такую простую схему
- все по образцу QCache - может и унаследоваться от него. А вот в тип T (хранимое значение) добавить методы ref/deref, ну и руками их +/- Практически меня это вполне устраивает, но смущает добровольный и полный отказ от вумных указателей, которые здесь, вроде бы, очень "в масть". Как же так - явный, махровый шаринг, а применить стандартные средства не удается... Или я не прав? Название: Re: QSharedPointer и/или implicit sharing? Отправлено: Авварон от Апрель 24, 2019, 15:57 Ну так у вас "сохранение в файл" основная проблема, а не "букварь".
Вот у вас есть шаренный кустринг, вы записали его в файл дважды. Потом файл прочитали и ОПА получили два кустринга. Как так вышло-то? Тут надо уходить от коровы и писать на шаред_птрах всё. Ну или на ExcplicitlySharedPointer. В любом случае, должно быть явно видно, что пошарено, а что нет. С точки зрения пользователя (то есть вас) пошаренный кустринг - это ДВА РАЗНЫХ кустринга. На то он и неявный шаринг. Название: Re: QSharedPointer и/или implicit sharing? Отправлено: Igors от Апрель 25, 2019, 10:15 Тут надо уходить от коровы и писать на шаред_птрах всё. Ну или на ExcplicitlySharedPointer. Каким образом? Ни тот ни другой никакого хеша имеющихся экземпляров не имеют |