From 8add41a6e37994577d928bc312801ddfa1c33173 Mon Sep 17 00:00:00 2001 From: lucy96chen <47800040+lucy96chen@users.noreply.github.com> Date: Mon, 17 Oct 2022 17:38:59 -0700 Subject: Shader cache index implementation (#2452) --- source/core/slang-digest-builder.h | 35 ++++++++++++++++++++ source/core/slang-digest-util.cpp | 66 ++++++++++++++++++++++++++++++++++++++ source/core/slang-digest-util.h | 43 +++++++++++++++++++++++++ source/core/slang-digest.h | 35 -------------------- source/core/slang-linked-list.h | 44 ++++++++++++++++--------- 5 files changed, 172 insertions(+), 51 deletions(-) create mode 100644 source/core/slang-digest-builder.h create mode 100644 source/core/slang-digest-util.cpp create mode 100644 source/core/slang-digest-util.h delete mode 100644 source/core/slang-digest.h (limited to 'source/core') diff --git a/source/core/slang-digest-builder.h b/source/core/slang-digest-builder.h new file mode 100644 index 000000000..47c0cd8f7 --- /dev/null +++ b/source/core/slang-digest-builder.h @@ -0,0 +1,35 @@ +#pragma once +#include "slang-md5.h" +#include "../../slang.h" + +namespace Slang +{ + using slang::Digest; + + // Wrapper struct that holds objects necessary for hashing. + struct DigestBuilder + { + public: + DigestBuilder() + { + hashGen.init(&context); + } + + template + void addToDigest(T item) + { + hashGen.update(&context, item); + } + + Digest finalize() + { + Digest hash; + hashGen.finalize(&context, &hash); + return hash; + } + + private: + MD5HashGen hashGen; + MD5Context context; + }; +} diff --git a/source/core/slang-digest-util.cpp b/source/core/slang-digest-util.cpp new file mode 100644 index 000000000..d235f2cf0 --- /dev/null +++ b/source/core/slang-digest-util.cpp @@ -0,0 +1,66 @@ +// string-digest-util.cpp +#include "slang-digest-util.h" + +#include "../core/slang-basic.h" +#include "../core/slang-digest-builder.h" +#include "../core/slang-md5.h" +#include "../core/slang-char-util.h" + +namespace Slang +{ + +/*static*/ Digest DigestUtil::computeDigestForStringSlice(UnownedStringSlice text) +{ + DigestBuilder builder; + builder.addToDigest(text); + return builder.finalize(); +} + +/*static*/ Digest DigestUtil::combine(const Digest& digestA, const Digest& digestB) +{ + DigestBuilder builder; + builder.addToDigest(digestA); + builder.addToDigest(digestB); + return builder.finalize(); +} + +/*static*/ String DigestUtil::toString(const Digest& digest) +{ + StringBuilder hashString; + + uint8_t* uint8Hash = (uint8_t*)digest.values; + + for (Index i = 0; i < 16; ++i) + { + auto hashSegmentString = String(uint8Hash[i], 16); + + if (hashSegmentString.getLength() == 1) + { + hashString.append("0"); + } + hashString.append(hashSegmentString.getBuffer()); + } + + return hashString; +} + +/*static*/ Digest DigestUtil::fromString(UnownedStringSlice hashString) +{ + uint8_t uint8Hash[16]; + + // When the hash is converted to a String, ReverseInternalAscii is called + // at the very end. Since there is no way to get a char* for hashString to pass + // to ReverseInternalAscii to flip the string back, we instead loop starting from + // the end and work backwards towards the beginning. + for (Index i = 0; i < 16; i++) + { + uint8Hash[i] = (uint8_t)CharUtil::getHexDigitValue(hashString[i * 2]) * 16 + + (uint8_t)CharUtil::getHexDigitValue(hashString[i * 2 + 1]); + } + + Digest digest; + memcpy(digest.values, uint8Hash, 16); + return digest; +} + +} diff --git a/source/core/slang-digest-util.h b/source/core/slang-digest-util.h new file mode 100644 index 000000000..1e272fd5e --- /dev/null +++ b/source/core/slang-digest-util.h @@ -0,0 +1,43 @@ +// slang-digest-utils.h - Utility functions specifically designed to be used with slang::Digest +#pragma once +#include "../../slang.h" +#include "slang-string.h" + +namespace Slang +{ + using slang::Digest; + + struct DigestUtil + { + // Compute the digest for an UnownedStringSlice + static Digest computeDigestForStringSlice(UnownedStringSlice text); + + // Combines the two provided digests. + static Digest combine(const Digest& digestA, const Digest& digestB); + + // Returns the hash stored in digest as a String. + static String toString(const Digest& digest); + + // Returns the hash represented by hashString as a Digest. + static Digest fromString(UnownedStringSlice hashString); + }; + + inline StringBuilder& operator<<(StringBuilder& sb, const Digest& d) + { + // Must cast to uint8_t* first in order to correctly account for + // endianness. + uint8_t* uint8Hash = (uint8_t*)d.values; + + for (Index i = 0; i < 16; ++i) + { + int hashSegment = uint8Hash[i]; + // Check if we need to append a leading zero. + if (hashSegment < 16) + { + sb << "0"; + } + sb.append(hashSegment, 16); + } + return sb; + } +} diff --git a/source/core/slang-digest.h b/source/core/slang-digest.h deleted file mode 100644 index 47c0cd8f7..000000000 --- a/source/core/slang-digest.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once -#include "slang-md5.h" -#include "../../slang.h" - -namespace Slang -{ - using slang::Digest; - - // Wrapper struct that holds objects necessary for hashing. - struct DigestBuilder - { - public: - DigestBuilder() - { - hashGen.init(&context); - } - - template - void addToDigest(T item) - { - hashGen.update(&context, item); - } - - Digest finalize() - { - Digest hash; - hashGen.finalize(&context, &hash); - return hash; - } - - private: - MD5HashGen hashGen; - MD5Context context; - }; -} diff --git a/source/core/slang-linked-list.h b/source/core/slang-linked-list.h index 7c9987397..38da2ccce 100644 --- a/source/core/slang-linked-list.h +++ b/source/core/slang-linked-list.h @@ -243,6 +243,12 @@ public: { LinkedNode* n = new LinkedNode(this); n->Value = nData; + AddFirst(n); + count++; + return n; + }; + void AddFirst(LinkedNode* n) + { n->prev = 0; n->next = head; if (head) @@ -250,24 +256,12 @@ public: head = n; if (!tail) tail = n; - count++; - return n; - }; - void Delete(LinkedNode* n, int Count = 1) + } + void RemoveFromList(LinkedNode* n) { - LinkedNode*n1, *n2 = 0, *tn; + LinkedNode*n1, *n2 = 0; n1 = n->prev; - tn = n; - int numDeleted = 0; - for (int i = 0; i < Count; i++) - { - n2 = tn->next; - delete tn; - tn = n2; - numDeleted++; - if (tn == 0) - break; - } + n2 = n->next; if (n1) n1->next = n2; else @@ -276,6 +270,24 @@ public: n2->prev = n1; else tail = n1; + n->prev = nullptr; + n->next = nullptr; + } + void Delete(LinkedNode* n, int Count = 1) + { + LinkedNode*cur, *next; + cur = n; + int numDeleted = 0; + for (int i = 0; i < Count; i++) + { + next = cur->next; + RemoveFromList(cur); + delete cur; + cur = next; + numDeleted++; + if (cur == 0) + break; + } count -= numDeleted; } void Clear() -- cgit v1.2.3