anchor.diff:          current <- keys
           x.ApplyDeltas(delta)
   
  -type MapSet<'k, 'v when 'k : equality and 'k :> IUnique>(initial : pset<'k>, create : 'k -> 'v, update : 'v * 'k -> unit) =
  -    let store = Dictionary<int64, 'v>()
  +type IReuseCache =
  +    interface end
  +
  +type ReuseCache<'a>() =
  +    let store = ConditionalWeakTable<Id, ref<'a>>()
  +    
  +    interface IReuseCache
  +
  +    member x.GetOrCreate(k : 'k, f : 'k -> 'a) =
  +        let i = Unique.id k
  +        lock store (fun () ->
  +            match store.TryGetValue i with
  +                | (true, v) -> !v
  +                | _ -> 
  +                    let v = f k
  +                    store.Add(i, ref v)
  +                    v
  +        )
  +        
  +
  +type MapSet<'k, 'v when 'k : equality and 'k :> IUnique>(cache : ReuseCache<'v>, initial : pset<'k>, create : 'k -> 'v, update : 'v * 'k -> unit) =
  +    //let store = Dictionary<int64, 'v>()
       let readers = HashSet<ASetReaders.EmitReader<'v>>()
       let content = VersionedSet (HashSet())
       let readers = WeakSet<ASetReaders.EmitReader<'v>>()
       do for e in initial do
           let id = Unique.id e
  -        match store.TryGetValue id with
  -            | (true, v) -> 
  -                update(v, e)
  -            | _ ->
  -                let v = create e
  -                store.Add(id, v)
  -                content.Add v |> ignore
  +        let mutable isNew = false
  +        let v = cache.GetOrCreate(e, fun k -> isNew <- true; create k)
  +        if not (content.Add v) then
  +            update(v,e)
   
       let emit (deltas : Option<Change<'v>>) =
           lock readers (fun () ->
  
positive.code: ﻿namespace Aardvark.Base.Incremental
  
  open System.Collections.Generic
  open Aardvark.Base
  
  
  type DomainTypeAttribute() = inherit System.Attribute()
  
  type IUnique =
      abstract member Id : int64 with get, set
  
  module Unique = 
      open System.Threading
      let mutable private currentId = 1L
  
      let id (u : IUnique) =
          let old = u.Id
          if old = 0L then
              let i = Interlocked.Increment(&currentId)
              u.Id <- i
              i
          else
  
negative.code: 
          member x.Copy = x :> aset<_>
          member x.GetReader() = x.GetReader()
  
  
  type ReuseCache() =
  
      let version = ref 0L
      let store = Dict<Type, IReuseCache>()
  
      member x.GetCache<'a>() =
          let dict = store.GetOrCreate(typeof<'a>, fun t -> ReuseCache<'a>() :> IReuseCache)
          dict |> unbox<ReuseCache<'a>>
  