diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2023-02-14 14:31:49 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2023-02-14 14:31:49 +0700 |
commit | b0ac018a1ae1c7ab19ba047d50b9b4353ba2e0a7 (patch) | |
tree | 4b04803149498b1ad12e7f27e823cdec08a44a22 | |
parent | Fix exception type (diff) | |
download | BouncyCastle.NET-ed25519-b0ac018a1ae1c7ab19ba047d50b9b4353ba2e0a7.tar.xz |
Improve DerObjectIdentifier cache
- see https://github.com/bcgit/bc-csharp/pull/416
-rw-r--r-- | crypto/src/asn1/DerObjectIdentifier.cs | 28 |
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) |