Russian Qt Forum

Программирование => Общий => Тема начата: Igors от Май 31, 2017, 11:22



Название: Зашарить данные
Отправлено: Igors от Май 31, 2017, 11:22
Добрый день

Есть немаленький код который работает но не шарит данные. Максимально упрощенный псевдокод
Код
C++ (Qt)
struct Target {
..
 QString mFullFileName;       // полное имя файла данных
 Geometry * mGeometryList;   // список данных
};
 
struct Geometry {
 Geometry * mPrev, * mNext;  // двусвязный спысок
...
 qint64 mVerPos;      // смещение данных в файле
 uint32 mVerSize;     // размер данных
 Container * mData;   // данные (потенциально большие)
};
Юзер может добавлять/удалять любое число Target'ов которые возможно будут юзать одни и те же файлы загружая из них одни и те же данные. Как организовать шару?

Спасибо


Название: Re: Зашарить данные
Отправлено: Авварон от Май 31, 2017, 12:16
Чем std::shared_ptr не угодил? Пока проблематика неясна.


Название: Re: Зашарить данные
Отправлено: Igors от Май 31, 2017, 13:09
Ну хорошо, действуем прямолинейно
Код
C++ (Qt)
struct Geometry {
...
std::shared_ptr<Container> mData;
};
И что делать когда юзер создает новый Target? Как узнать что какие-то части данного файла уже загружены?


Название: Re: Зашарить данные
Отправлено: Old от Май 31, 2017, 13:13
Очередная тема про менеджеры ресурсов...  Сколько же можно... :-\

P.S. И да, шарить нужно не Container, а Geometry.


Название: Re: Зашарить данные
Отправлено: Igors от Июнь 06, 2017, 08:43
Сделал важное изменение. Заменил пассивные данных mVerPos и mVerSize (которые вычислялись сверху) на ключ по которому данные ищутся в файле, в псевдокоде для простоты строка 
Код
C++ (Qt)
struct Target {
..
 QString mFullFileName;       // полное имя файла данных
 Geometry * mGeometryList;   // список данных
};
 
struct Geometry {
 Geometry * mPrev, * mNext;  // двусвязный спысок
...
 QString mDataKey;      // ключ для поиска данных в файле
 Container * mData;   // данные (потенциально большие)
};

Ладно, решил действовать стандартно, использовать связку shared+weak. Выходит такая конструкция
Код
C++ (Qt)
// ключ - тот что выше, значение - загруженные данные
typedef QMap<QString, QWeakPointer<Container> > TContainerMap;  
 
// ключ - полное имя файла, значение - мапа выше
typedef QMap<QString, TContainerMap> TFileMap;  
 
// глобальная мапа
TFileMap theFileMap;
 
// этот метод лазит по мапам
// возвращает имеющийся шаред или создает новый (с нулевыми данными)
static QSharedPointer<Container> Geometry::Make( const QString & keyFile, const QString & keyData );      
 
Теперь копирование и удаление работают (правда остаются orphan weak, ну это не горит). Хуже с самой зарядкой данных (загрузкой их из файлов). Приходится делать так:

- собрать все Target'ы использующие данный файл (дорого)
- зачистить шаред во всех принадлежащих им Geometry
- открыть файл и для всех Geometry вызвать Make - если данные ненулевые то они уже загружены кем-то из шарящих. Иначе (контейнер пуст) найти данные в файле и загрузить в контейнер

Это работает, но "поиск всех" (по всем имеющимся данным) не выглядит хорошо. Как можно это улучшить?