【问题标题】:How to increase the reference count of subarrays when the refcount of the holding array increases?当持有数组的引用计数增加时,如何增加子数组的引用计数?
【发布时间】:2014-06-20 21:10:17
【问题描述】:

我有一个工作正常的 COWarray,但现在我想像这样扩展维度的数量:

type
  TCOWArray2<T> = record
  private
    type
      TItem = record
        fItems: TArray<T>;
        fStart, fFinish: NativeInt;
      end;
  private
    fItems: array of TItem;
  private
     methods
  public
     ....
  end;

数组将其项目分成块。每个子数组都有例如100 个项目,但平均数组需要很多项目。
对外只显示一维数组,但在内部,T 类型的数据存储在子数组中。

通过这种方式,当单个项目发生更改时,我可以只进行很少的复制就可以进行写入副本。 不是克隆所有 20,000 个项目,而是仅克隆 100 个项目加上具有 200 个项目的平均数组,即仅 300 个项目减少了近 99% 的工作量和存储量。

问题是我需要跟踪主数组的引用计数的变化并将这些变化传播到子数组。

类似:

procedure TCOWArray<T>.SomeMember.AddRef;
var
  Item: TItem;
begin
  inherited;
  for Item in fItems do Item.IncreaseRefCount;
end;

显然出于性能原因,我将使用普通的 for i 循环

我该怎么做?
我正在考虑添加一个自定义 TInterfaced 对象,但我不确定如何使其工作。

【问题讨论】:

  • 这是似曾相识的。您可以使用SetLength 解决问题,而不是手动调整引用计数。
  • @DavidHeffernan,不,大卫,我需要增加子数组的引用计数,而不是将其重置为 1。将其重置为 1 是使用 SetLength I 完成的现在知道(谢谢)并且有效。我现在需要反向操作。
  • 一旦确定要写入哪个子数组,在那个子数组上使用 SetLength()。
  • 在主数组上调用 SetLength。这为您提供了一个独特的副本,这就是您想要的主阵列。它将自动增加所有子数组的引用计数。现在在您计划修改的子数组上调用 SetLength。这也使它独一无二。换句话说,您已经为TCOWArray&lt;T&gt; 解决了这个问题,现在您正试图为TCOWArray&lt;TCOWArray&lt;T&gt;&gt; 重新解决它,却没有意识到这只是您已经完成的工作的专门化。
  • 啊哈,好吧,这是有道理的。我反其道而行之,却被卡住了。

标签: arrays delphi delphi-xe2 reference-counting copy-on-write


【解决方案1】:

这似乎是多维系列问题中的第二个。

系列的第一个问题,外部维度,在这里:Why does the compiler insist my function is inline when it's not? 虽然问题标题涉及错误消息,但最终变成了关于实现写入时复制数组的问题。那是问题的一维版本。

现在我们继续讨论这个问题。这是二维版本。我们以与第一个问题相同的方式解决它。因为它实际上是完全相同的问题。一旦我们可以解决一维数组,同样的解决方案也适用于 N 维数组。

当您需要修改数组的元素时,请在您的内部数组上调用SetLength。这为您提供了一个独特的外部数组。此处发生的任何复制,仅复制对内部子数组的引用。

然后确定需要操作的内部子数组。完成后,再次调用SetLength 以使该内部子数组唯一。然后修改值。

添加多少维度并不重要。答案总是一样的。我希望这个问题可以终止这个系列! ;-)

【讨论】:

  • 是的,这是有道理的,我是从内向外工作,但你需要从外向内工作。一旦你意识到它是如何工作的,就很容易了。
猜你喜欢
  • 1970-01-01
  • 2018-04-24
  • 2017-10-06
  • 1970-01-01
  • 2017-11-04
  • 2015-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多