summary refs log tree commit diff
path: root/crypto/src
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2023-02-14 14:31:49 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2023-02-14 14:31:49 +0700
commitb0ac018a1ae1c7ab19ba047d50b9b4353ba2e0a7 (patch)
tree4b04803149498b1ad12e7f27e823cdec08a44a22 /crypto/src
parentFix exception type (diff)
downloadBouncyCastle.NET-ed25519-b0ac018a1ae1c7ab19ba047d50b9b4353ba2e0a7.tar.xz
Improve DerObjectIdentifier cache
- see https://github.com/bcgit/bc-csharp/pull/416
Diffstat (limited to 'crypto/src')
-rw-r--r--crypto/src/asn1/DerObjectIdentifier.cs28
1 files changed, 18 insertions, 10 deletions
diff --git a/crypto/src/asn1/DerObjectIdentifier.cs b/crypto/src/asn1/DerObjectIdentifier.cs

index 06a7b25f3..96e61cdc5 100644 --- a/crypto/src/asn1/DerObjectIdentifier.cs +++ b/crypto/src/asn1/DerObjectIdentifier.cs
@@ -1,6 +1,7 @@ using System; using System.IO; using System.Text; +using System.Threading; using Org.BouncyCastle.Math; using Org.BouncyCastle.Utilities; @@ -205,19 +206,26 @@ namespace Org.BouncyCastle.Asn1 internal static DerObjectIdentifier CreatePrimitive(byte[] contents, bool clone) { - int hashCode = Arrays.GetHashCode(contents); - int first = hashCode & 1023; + int index = Arrays.GetHashCode(contents); - lock (Cache) - { - DerObjectIdentifier entry = Cache[first]; - if (entry != null && Arrays.AreEqual(contents, entry.GetContents())) - { - return entry; - } + index ^= index >> 20; + index ^= index >> 10; + index &= 1023; + + var originalEntry = Cache[index]; + if (originalEntry != null && Arrays.AreEqual(contents, originalEntry.GetContents())) + return originalEntry; - return Cache[first] = new DerObjectIdentifier(contents, clone); + var newEntry = new DerObjectIdentifier(contents, clone); + + var exchangedEntry = Interlocked.CompareExchange(ref Cache[index], newEntry, originalEntry); + if (exchangedEntry != originalEntry) + { + if (exchangedEntry != null && Arrays.AreEqual(contents, exchangedEntry.GetContents())) + return exchangedEntry; } + + return newEntry; } private static bool IsValidIdentifier(string identifier)