Flyweights с Boost и внешними источниками данных - PullRequest
7 голосов
/ 13 января 2012

Может быть, есть простой способ обойти это, что я не вижу, так что, надеюсь, кто-нибудь сможет мне это объяснить.

Допустим, у меня есть класс:

class A {
public:
  const double parameter;
  const std::string name;
  const std:: string fileName;

  A(const double parameter, const std::string name, const std::string fileName) : 
      parameter(parameter), name(name), fileName(fileName) {}; 
};

И генератор для этого класса:

class AReader {
public:
  ifstream dataFile;
  AReader(const std::string filename);
  A* readObject(const std::string objectName);
};

Я бы хотел использовать boost::flyweight для обработки этих A объектов, потому что на них могут быть миллионы ссылок, и на самом деле они содержат много данных. Они будут хешированы на name и fileName вместе.

Что мне нужно, чтобы сделать эту работу? Мне нужен boost::flyweight для вызова AReader.readObject и хеширования / сохранения результирующего класса A.

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

Редактировать

Я также открыт для других предложений, не использующих Boost. Я, конечно, могу написать свою собственную реализацию навесного веса или любой другой шаблон, если он лучше подходит. Но если бы я мог использовать то, что уже существует, это было бы лучше всего. Что бы ни сводило к минимуму объем кода, который мне нужно написать, потому что, как всегда, сроки являются короткими.

Ответы [ 3 ]

1 голос
/ 14 января 2012

Я не использовал Boost :: flyweight, но, судя по всему, ключ должен быть Assignable (в дополнение к EqualityComparable и Hashable). С вашими const участниками вы набираете явно , а не Assignable. Судя по всему, вам не нужно делать это Assignable, если у вас есть ключ-экстрактор . При использовании экстрактора ключей только ключ должен быть Assignable.

0 голосов
/ 22 января 2012

Хотя key_value Flyweight кажется подходящим, казалось бы, есть небольшая заминка.Вы должны иметь возможность построить key_value Flyweight, используя только один параметр типа ключа ( key_value flyweights ).Таким образом, чтобы заставить его работать с нужным ключом (имя файла + имя), вам нужно будет упаковать эти 2 поля в одно ( tuple ? Даже не уверен, что это сработает.)

Предполагая, что вы заинтересованы в получении максимальной отдачи с наименьшим объемом работы, почему бы не просто Flyweight строк в вашем классе, как показано в Основы Flyweight ?

Это означает Aобъекты хешируются не так, как вы хотите, но строки легко взвешиваются, и эти кажутся полями, проблемными с вашей памятью.(если это не упрощение)

0 голосов
/ 21 января 2012

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

Теперь это должно быть тривиально для реализации, но в зависимости от вашего варианта использования может быть неэффективным.Для лучшей производительности вы можете использовать функциональность key_value , которая позволяет ссылаться на объекты через их ключ и создавать их только в том случае, если их еще нет в магазине.

...