Как создать api для постоянной коллекции на C #?

Я думаю о создании постоянной коллекции (списков или других) на C #, но я не могу придумать хороший API.

Я использую « постоянный » в смысле Clojure : постоянный список - это список, который ведет себя так, как если бы он имеет семантику значения вместо семантики ссылки, но не вызывает накладных расходов копирования типов больших значений. Постоянные коллекции используют копирование при записи для разделения внутренней структуры. Псевдокод:

l1 = PersistentList()
l1.add("foo")
l1.add("bar")
l2 = l1
l1.add("baz")

print(l1) # ==> ["foo", "bar", "baz"]
print(l2) # ==> ["foo", "bar"]
# l1 and l2 share a common structure of ["foo", "bar"] to save memory

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

Одним из способов повышения эффективности было бы ведение счетчика ссылок на вашу структуру данных (хотя Я не думаю, что Clojure так работает). Если refcount равен 1, вы держите единственную ссылку, поэтому выполняйте обновления разрушительно. Если счетчик ссылок выше, значит, кто-то еще имеет ссылку на него, которая должна вести себя как тип значения, поэтому выполняйте копирование при записи, чтобы не мешать другим источникам ссылки.

В API для такой структуры данных можно было бы выставить счетчик ссылок, что значительно снижает удобство использования API, или нельзя было бы выполнить счетчик ссылок, что привело бы к ненужным накладным расходам на копирование при записи, если каждая операция выполняется COW'ed, или API теряет свое поведение типа значения, и пользователю приходится управлять COW вручную.

Если бы в C # были конструкторы копирования для структур, это было бы возможно. Можно определить структуру, содержащую ссылку на реальную структуру данных, и выполнять все вызовы incref () / Decf () в конструкторе копирования и деструкторе структуры.

Есть ли способ сделать что-то вроде подсчета ссылок или конструкторов копирования структур автоматически в C #, не беспокоя пользователей API?

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

  • Для ясности, я просто спрашиваю об API. В Clojure уже есть реализация этого, написанная на Java.
  • Конечно, можно создать такой интерфейс, используя структуру со ссылкой на реальную коллекцию, которая COW'ed при каждой операции. Использование реф-подсчета было бы оптимизацией, чтобы избежать ненужного COWing, но, очевидно, это невозможно с разумным API.

5
задан JanKanis 16 November 2010 в 12:33
поделиться