anchor.diff:  open ExtCore
   open ExtCore.Collections
   
  +
  +(* OPTIMIZE :   In the HashMap used in the cache, change the KeyValuePair to a simple struct-tuple
  +                so we can flip the order the index and value are stored in; this'll provide better
  +                data alignment in most cases. (E.g., name the type ValueWithKeyIndex) *)
  +// TODO : Perhaps use TagMap instead of IntMap, and tag the key indices with a tag type like KeyIndex.
   
   /// An immutable cache data structure with a Least-Recently-Used (LRU) eviction policy.
   type LruCache<'Key, 'T when 'Key : equality>
  
positive.code:         with get () =
              IntMap.count indexedKeys
  
      /// Look up a key in the cache, returning Some with the associated value and
      /// updated cache if the key is in the domain of the cache and None if not.
      member __.TryFind (key : 'Key) : ('T * LruCache<'Key, 'T>) option =
          notImpl "LruCache.TryFind"
  
      /// Tests if a key is in the domain of the cache.
      member __.ContainsKey (key : 'Key) : bool =
          notImpl "LruCache.ContainsKey"
  
      //
      member __.Add (key : 'Key, value : 'T) : LruCache<'Key, 'T> =
          // NOTE : Checked.add MUST be used when incrementing 'count'!
          notImpl "LruCache.Add"
  
      //
      member __.Remove (key : 'Key) : LruCache<'Key, 'T> =
          notImpl "LruCache.Remove"
      
      //
      member this.ChangeCapacity (newCapacity : uint32) : LruCache<'Key, 'T> =
  
negative.code: 
      //
      member __.ToSeq () : seq<'Key * 'T> =
          indexedKeys
          |> IntMap.toSeq
          |> Seq.map (fun (_, key) ->
              // Find the value using the key.
              let kvp = HashMap.find key cache
              key, kvp.Value)
  
      //
      member __.ToList () : ('Key * 'T) list =
          // Fold backwards so we don't have to reverse the created list.
          (indexedKeys, [])
          ||> IntMap.foldBack (fun keyIndex key list ->
              // Find the value using the key.
              let kvp = HashMap.find key cache
  
              // DEBUG : Assert that the index in the key-value pair is
              // equal to the one from the key-index.
              assert (keyIndex = kvp.Key)
  
              // Cons the key and value onto the list.
              (key, kvp.Value) :: list)
  
      //
      member __.ToArray () : ('Key * 'T)[] =
          let kvps = ResizeArray ()
  
          indexedKeys
          |> IntMap.iter (fun keyIndex key ->
              // Find the value using the key.
              let kvp = HashMap.find key cache
  
              // DEBUG : Assert that the index in the key-value pair is
              // equal to the one from the key-index.
              assert (keyIndex = kvp.Key)
  
              // Add the key and value to the ResizeArray
              kvps.Add (key, kvp.Value))
  
          ResizeArray.toArray kvps
  
      //
      static member OfSeq (source : seq<'Key * 'T>) : LruCache<'Key, 'T> =
          // Preconditions
          checkNonNull "source" source
  
          (empty, source)
          ||> Seq.fold (fun cache (key, value) ->
              cache.Add (key, value))
  
      //
      static member OfList (source : ('Key * 'T) list) : LruCache<'Key, 'T> =
          // Preconditions
          checkNonNull "source" source
  
          (empty, source)
          ||> List.fold (fun cache (key, value) ->
              cache.Add (key, value))
  
      //
      static member OfArray (source : ('Key * 'T)[]) : LruCache<'Key, 'T> =
          // Preconditions
          checkNonNull "source" source
          
          (empty, source)
          ||> Array.fold (fun cache (key, value) ->
              cache.Add (key, value))
  
  
  //
  