带有Boost和外部数据源的飞线重量

Flyweights with Boost and external data sources

本文关键字:飞线 数据源 Boost 外部 带有      更新时间:2023-10-16

也许有一个简单的方法我没有看到,所以希望有人能向我解释。

假设我有一门课:

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对象,因为可能会有数百万个对它们的引用,而实际上它们包含大量数据。它们将在namefileName上一起被散列。

我需要什么才能做到这一点?我需要boost::flyweight来调用AReader.readObject并散列/存储生成的A类。

AReader是否需要成为一个完整的工厂并用作定制工厂?或者,是否可以在flyweight中使用默认工厂,并以某种方式使用AReader来生成A实例(而不是实现工厂所需的整个存储模式),也许可以通过将AReader实例作为flyweights中某些东西的参数?或者,是否可以从外部数据源获取const公共变量(即,一旦设置,它们就不会更改),而不需要求助于第二个类?

编辑

我也对其他不使用Boost的建议持开放态度。我当然可以编写我自己的轻量级实现,或者任何其他模式(如果更适合的话)。但如果我能使用已经存在的东西,那将是最好的。无论什么都可以最大限度地减少我需要编写的代码量,因为和往常一样,截止日期很短。

我还没有使用Boost::flyweight,但从外观上看,密钥至少需要是Assignable(除了是EqualityComparableHashable)。对于您的const成员,您键入的显然是而不是Assignable。从外观上看,如果您有密钥提取器,则不必将其设为Assignable。使用密钥提取器,仅密钥需要是Assignable

在您的案例中使用flyweight的基本方法是让readObject返回一个flyweight。在内部,readObject会创建一个全新的对象,当您创建相应的轻量级对象时,它会检查该对象是否已经在轻量级存储中。如果是这样,它将丢弃您的新对象,并返回一个引用存储中对象的蝇量级。如果没有,它会将新对象添加到其池中。

现在,实现起来应该很简单,但根据您的用例,效率可能会很低。为了获得更好的性能,您可以使用key_value功能,该功能允许您通过对象的键引用对象,并且只有在存储中尚未存在对象时才创建对象。

虽然key_value飞线重量似乎很合适,但似乎有一个小问题。您应该能够通过只使用一个键类型的参数(key_value flyweights)来构造key_value飞重。因此,要使它与您想要的密钥(文件名+名称)一起工作,您必须将这两个字段打包为一个字段(元组?甚至不确定这是否有效。)

假设你有兴趣用最少的工作量获得最大的结果,为什么不像Flyweight Basics中演示的那样,只Flyweight类中的字符串呢?

这意味着A对象不会按照您想要的方式进行散列,但字符串很容易进行蝇加权,并且这些似乎是您的内存问题字段。(除非这过于简单化)