public void RemoveKeyIfStillThere(TWeakOwningKey weakOwningKey)
 {
     lock (mLock)
     {
         WeakOwningKeyToContained.Remove(weakOwningKey);
     }
 }
示例#2
0
 public TContained GetAndBuildIfAbsent(TWeakOwningKey weakOwningKey, Func <TContained> buildANewOne)
 {
     lock (mLock) // key - it builds *inside* the lock
     {
         return(WeakOwningKeyToContained.GetValue(weakOwningKey, k => buildANewOne()));
     }
 }
 public TSharedContained GetFromWeakOwningKey(TWeakOwningKey weakOwningKey) // resource key is more a guard at this stage that you were ever an intentional client.
 {
     lock (mLock)
     {
         return(WeakOwningKeyToContained.GetValue(weakOwningKey, _ => throw new Exception("No - assumption of this wider container that key existence implies membership always - grave coding or assumption error in container.")).Item1);
     }
 }
示例#4
0
 public TContained GetValue(TWeakOwningKey weakOwningKey)
 {
     lock (mLock)
     {
         return(WeakOwningKeyToContained.GetValue(weakOwningKey, _ => throw new Exception("No - assumption of this wider container that key existence implies membership always - grave coding or assumption error in container.")));
     }
 }
示例#5
0
 public void Add(TWeakOwningKey weakOwningKey, TContained contained)
 {
     lock (mLock)
     {
         WeakOwningKeyToContained.Add(weakOwningKey, contained);
     }
 }
示例#6
0
 public TContained SwapOutValueWithExistingAsAtomicOperation(TWeakOwningKey weakOwningKey, TContained replacementValue)
 {
     lock (mLock) // key - it builds *inside* the lock
     {
         var preReplacementValue = WeakOwningKeyToContained.GetValue(weakOwningKey, _ => throw new Exception("No - assumption of this wider container that key existence implies membership always - grave coding or assumption error in container."));
         WeakOwningKeyToContained.Remove(weakOwningKey); // the add doesn't allow a duplicate
         WeakOwningKeyToContained.Add(weakOwningKey, replacementValue);
         return(preReplacementValue);
     }
 }
 // This would be 'always' if Shared were made a hard direct reference
 public void AddKeyIfValueAvailable(TWeakOwningKey weakOwningKey)
 {
     lock (mLock)
     {
         if (PossibleRecovery.TryGetTarget(out var currentContained))
         {
             var newKeyHolderID = Guid.NewGuid();
             var newKeyHolder   = NewWeakOwningKeyLifeWatcher(mLock, IDToWeakOfOwningKey, newKeyHolderID);
             IDToWeakOfOwningKey.Add(newKeyHolderID, new WeakReference <TWeakOwningKey>(weakOwningKey));
             WeakOwningKeyToContained.Add(weakOwningKey, Tuple.Create(currentContained, newKeyHolder));
         }
     }
 }
        public void AddUnrepresentedKeyWithRecreateIfMissing(TWeakOwningKey weakOwningKey, Func <TSharedContained> toCreateIfMissing)
        {
            var newKeyHolderID = Guid.NewGuid();
            var newKeyHolder   = NewWeakOwningKeyLifeWatcher(mLock, IDToWeakOfOwningKey, newKeyHolderID);

            lock (mLock)
            {
                if (PossibleRecovery.TryGetTarget(out var currentContained))
                {
                    WeakOwningKeyToContained.Add(weakOwningKey, Tuple.Create(currentContained, newKeyHolder)); // can fail/grenade
                    IDToWeakOfOwningKey.Add(newKeyHolderID, new WeakReference <TWeakOwningKey>(weakOwningKey));
                }
                else
                {
                    currentContained = toCreateIfMissing();
                    PossibleRecovery.SetTarget(currentContained);
                    WeakOwningKeyToContained.Add(weakOwningKey, Tuple.Create(currentContained, newKeyHolder)); // can fail/grenade
                    IDToWeakOfOwningKey.Add(newKeyHolderID, new WeakReference <TWeakOwningKey>(weakOwningKey));
                }
            }
        }
示例#9
0
        // At first glance, this may look redundant - why not return Option<TContained> then the caller build it to the new key and insert it?
        // Then, realize that the use case may have others come in from different threads with the same key!!
        // Currently, holding the full lock thwarts this outright, the next guy will simply find the value.
        // Perhaps another would be to extend the container to have a per-weak-owning-key lockable.

        // Or WeakOwningKeyToContained containing Either<Func<TContained>, TContained> and have the left portion have a closed-over 'wait'
        // However, because ergonomically .Match(x => x(), x => x) will be inside lock (mLock) so the wait and PulseAll may have to be off of mLock
        // Minor performance matter but the Wait then has to be a loop as all are awakened.
        //
        // Better would be to have the 'Either' but simply factor the primary lock and have everyone return an 'either' out of it.
        public TContained GetAndIfAbsentBuildSplitInjectAndOuterReturnInsideTheLock(TWeakOwningKey weakOwningKey, Func <InjectAndOuterReturn <TContained> > getToInjectAndOuterReturn)
        {
            lock (mLock) // key - it builds *inside* the lock
            {
                var ifNotInitiallyFoundThisIsInjectAndOuterReturn = None <InjectAndOuterReturn <TContained> >();
                var r =
                    WeakOwningKeyToContained.GetValue(weakOwningKey, k =>
                {
                    // weakOwningKey/k (which should be identical) are irrelevant.

                    var toInjectAndOuterReturn = getToInjectAndOuterReturn();
                    ifNotInitiallyFoundThisIsInjectAndOuterReturn = Some(toInjectAndOuterReturn);     // mark outer code that this path was taken and has a return that's different to what's to be injected
                    return(toInjectAndOuterReturn.ToInject);
                });

                // Really, the to-inject decision is made inside of the underlying container's lock - this could be outside of mLock FWIW
                return
                    (ifNotInitiallyFoundThisIsInjectAndOuterReturn.Match(
                         x => x.ToReturn, // injected, use the inject-return
                         () => r          // found first time, return *that*
                         ));
            }
        }
        public AddKeyResult AddKeyIfNotAlreadyPresentWithRecreateIfMissing(TWeakOwningKey weakOwningKey, Func <TSharedContained> toCreateIfMissing)
        {
            //var newKeyHolderID = Guid.NewGuid();
            //var newKeyHolder = NewWeakOwningKeyLifeWatcher(mLock, IDToWeakOfOwningKey, newKeyHolderID);

            lock (mLock)
            {
                if (PossibleRecovery.TryGetTarget(out var currentContained))
                {
                    if (WeakOwningKeyToContained.TryGetValue(weakOwningKey, out var existing))
                    {                                                                                      // already exists - do nothing
                        return(new AddKeyResult(addedWeakOwningKeyAsNew: false, createdIfMissing: false)); // one way or another, it was already there
                    }
                    else
                    {
                        var newKeyHolderID = Guid.NewGuid();
                        var newKeyHolder   = NewWeakOwningKeyLifeWatcher(mLock, IDToWeakOfOwningKey, newKeyHolderID);
                        WeakOwningKeyToContained.Add(weakOwningKey, Tuple.Create(currentContained, newKeyHolder)); // should never fail - no existing
                        IDToWeakOfOwningKey.Add(newKeyHolderID, new WeakReference <TWeakOwningKey>(weakOwningKey));
                        return(new AddKeyResult(addedWeakOwningKeyAsNew: true, createdIfMissing: false));
                    }
                }
                else
                {
                    if (WeakOwningKeyToContained.TryGetValue(weakOwningKey, out var existing))
                    {   // already exists - do nothing
                        throw new Exception("Contradiction - Recovery value doesn't exist but value slot does!");
                    }
                    else
                    {
                        currentContained = toCreateIfMissing();
                        PossibleRecovery.SetTarget(currentContained);
                        var newKeyHolderID = Guid.NewGuid();
                        var newKeyHolder   = NewWeakOwningKeyLifeWatcher(mLock, IDToWeakOfOwningKey, newKeyHolderID);
                        WeakOwningKeyToContained.Add(weakOwningKey, Tuple.Create(currentContained, newKeyHolder)); // can fail/grenade
                        IDToWeakOfOwningKey.Add(newKeyHolderID, new WeakReference <TWeakOwningKey>(weakOwningKey));
                        return(new AddKeyResult(addedWeakOwningKeyAsNew: true, createdIfMissing: true));
                    }
                }

                /*
                 * if (PossibleRecovery.TryGetTarget(out var currentContained))
                 * {
                 * IDToWeakOfOwningKey.Add(newKeyHolderID, new WeakReference<TWeakOwningKey>(weakOwningKey));
                 *
                 *
                 * }
                 * else
                 * {
                 * IDToWeakOfOwningKey.Add(newKeyHolderID, new WeakReference<TWeakOwningKey>(weakOwningKey));
                 *
                 *
                 * currentContained = toCreateIfMissing();
                 * PossibleRecovery.SetTarget(currentContained);
                 * }
                 *
                 * if (WeakOwningKeyToContained.TryGetValue(weakOwningKey, out var existing))
                 * {   // already exists
                 * WeakOwningKeyToContained.Remove()
                 * }
                 * else
                 * {
                 * WeakOwningKeyToContained.Add(weakOwningKey, Tuple.Create(currentContained, newKeyHolder));
                 * }
                 */
            }
        }
示例#11
0
 public TContained GetAndBuildIfAbsent(TWeakOwningKey weakOwningKey, Func <TContained> buildANewOne)
 {
     // internally locks
     return(WeakOwningKeyToContained.GetValue(weakOwningKey, k => buildANewOne()));
 }
示例#12
0
 public void Add(TWeakOwningKey weakOwningKey, TContained contained)
 {
     // this internally locks
     WeakOwningKeyToContained.Add(weakOwningKey, contained);
 }