Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Adding API ConditionalWeakTable.AddOrUpdate (#8490)
Browse files Browse the repository at this point in the history
* Added ConditionalWeakTable.AddOrUpdate
  • Loading branch information
safern authored and jkotas committed Dec 10, 2016
1 parent b6a0b9a commit 6ba12d0
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/mscorlib/model.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6475,6 +6475,7 @@
<Type Name="System.Runtime.CompilerServices.ConditionalWeakTable&lt;TKey,TValue&gt;">
<Member Name="#ctor" />
<Member Name="Add(TKey,TValue)" />
<Member Name="AddOrUpdate(TKey,TValue)" />
<Member Name="Remove(TKey)" />
<Member Name="TryGetValue(TKey,TValue@)" />
<Member Name="GetValue(TKey,System.Runtime.CompilerServices.ConditionalWeakTable+CreateValueCallback)" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,37 @@ public void Add(TKey key, TValue value)
}
}

//--------------------------------------------------------------------------------------------
// key: key to add or update. May not be null.
// value: value to associate with key.
//
// If the key is already entered into the dictionary, this method will update the value associated with key.
//--------------------------------------------------------------------------------------------
public void AddOrUpdate(TKey key, TValue value)
{
if (key == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}

lock (_lock)
{
object otherValue;
int entryIndex = _container.FindEntry(key, out otherValue);

// if we found a key we should just update, if no we should create a new entry.
if (entryIndex != -1)
{
_container.UpdateValue(entryIndex, value);
}
else
{
CreateEntry(key, value);
}

}
}

//--------------------------------------------------------------------------------------------
// key: key to remove. May not be null.
//
Expand Down Expand Up @@ -495,6 +526,19 @@ internal bool Remove(TKey key)
return false;
}


internal void UpdateValue(int entryIndex, TValue newValue)
{
Debug.Assert(entryIndex != -1);

VerifyIntegrity();
_invalid = true;

_entries[entryIndex].depHnd.SetSecondary(newValue);

_invalid = false;
}

//----------------------------------------------------------------------------------------
// This does two things: resize and scrub expired keys off bucket lists.
//
Expand Down Expand Up @@ -796,6 +840,11 @@ public void GetPrimaryAndSecondary(out object primary, out object secondary)
nGetPrimaryAndSecondary(_handle, out primary, out secondary);
}

public void SetSecondary(object secondary)
{
nSetSecondary(_handle, secondary);
}

//----------------------------------------------------------------------
// Forces dependentHandle back to non-allocated state (if not already there)
// and frees the handle if needed.
Expand All @@ -821,6 +870,9 @@ public void Free()
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void nGetPrimaryAndSecondary(IntPtr dependentHandle, out object primary, out object secondary);

[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void nSetSecondary(IntPtr dependentHandle, object secondary);

[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void nFree(IntPtr dependentHandle);
#endregion
Expand Down
10 changes: 10 additions & 0 deletions src/vm/comdependenthandle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,13 @@ FCIMPL3(VOID, DependentHandle::nGetPrimaryAndSecondary, OBJECTHANDLE handle, Obj
}
FCIMPLEND

FCIMPL2(VOID, DependentHandle::nSetSecondary, OBJECTHANDLE handle, Object *_secondary)
{
FCALL_CONTRACT;

_ASSERTE(handle != NULL && _secondary != NULL);

OBJECTREF secondary(_secondary);
SetDependentHandleSecondary(handle, secondary);
}
FCIMPLEND
1 change: 1 addition & 0 deletions src/vm/comdependenthandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class DependentHandle
static FCDECL2(VOID, nGetPrimary, OBJECTHANDLE handle, Object **outPrimary);
static FCDECL3(VOID, nGetPrimaryAndSecondary, OBJECTHANDLE handle, Object **outPrimary, Object **outSecondary);
static FCDECL1(VOID, nFree, OBJECTHANDLE handle);
static FCDECL2(VOID, nSetSecondary, OBJECTHANDLE handle, Object *secondary);
};

#endif
Expand Down
1 change: 1 addition & 0 deletions src/vm/ecalllist.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ FCFuncStart(gDependentHandleFuncs)
FCFuncElement("nGetPrimary", DependentHandle::nGetPrimary)
FCFuncElement("nGetPrimaryAndSecondary", DependentHandle::nGetPrimaryAndSecondary)
FCFuncElement("nFree", DependentHandle::nFree)
FCFuncElement("nSetSecondary", DependentHandle::nSetSecondary)
FCFuncEnd()

#ifndef FEATURE_CORECLR
Expand Down

0 comments on commit 6ba12d0

Please sign in to comment.