From 150b9b7c676ecf8497103fb887d888a768dc8742 Mon Sep 17 00:00:00 2001 From: Adlai Holler Date: Fri, 28 Apr 2017 18:50:05 -0700 Subject: [PATCH 1/3] Simplify hashing --- AsyncDisplayKit.xcodeproj/project.pbxproj | 16 +- Source/ASImageNode.mm | 33 ++-- Source/ASTextNode.mm | 11 +- Source/Details/ASCollectionLayoutContext.mm | 14 +- Source/Private/ASEqualityHashHelpers.h | 186 -------------------- Source/Private/ASEqualityHashHelpers.mm | 45 ----- Source/Private/ASHashing.h | 46 +++++ Source/Private/ASHashing.m | 47 +++++ Source/TextKit/ASTextKitAttributes.mm | 30 ++-- 9 files changed, 158 insertions(+), 270 deletions(-) delete mode 100644 Source/Private/ASEqualityHashHelpers.h delete mode 100644 Source/Private/ASEqualityHashHelpers.mm create mode 100644 Source/Private/ASHashing.h create mode 100644 Source/Private/ASHashing.m diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index 9f072f507..8c2c6cffd 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -390,8 +390,8 @@ DECBD6E81BE56E1900CF4905 /* ASButtonNode.h in Headers */ = {isa = PBXBuildFile; fileRef = DECBD6E51BE56E1900CF4905 /* ASButtonNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; DECBD6EA1BE56E1900CF4905 /* ASButtonNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */; }; DEFAD8131CC48914000527C4 /* ASVideoNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEC47E01C20C2DD00EC1693 /* ASVideoNode.mm */; }; - E516FC7F1E9FE24200714FF4 /* ASEqualityHashHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = E516FC7D1E9FE24200714FF4 /* ASEqualityHashHelpers.h */; }; - E516FC801E9FE24200714FF4 /* ASEqualityHashHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = E516FC7E1E9FE24200714FF4 /* ASEqualityHashHelpers.mm */; }; + E516FC7F1E9FE24200714FF4 /* ASHashing.h in Headers */ = {isa = PBXBuildFile; fileRef = E516FC7D1E9FE24200714FF4 /* ASHashing.h */; }; + E516FC801E9FE24200714FF4 /* ASHashing.m in Sources */ = {isa = PBXBuildFile; fileRef = E516FC7E1E9FE24200714FF4 /* ASHashing.m */; }; E55D86331CA8A14000A0C26F /* ASLayoutElement.mm in Sources */ = {isa = PBXBuildFile; fileRef = E55D86311CA8A14000A0C26F /* ASLayoutElement.mm */; }; E5711A2C1C840C81009619D4 /* ASCollectionElement.h in Headers */ = {isa = PBXBuildFile; fileRef = E5711A2A1C840C81009619D4 /* ASCollectionElement.h */; settings = {ATTRIBUTES = (Private, ); }; }; E5711A301C840C96009619D4 /* ASCollectionElement.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5711A2D1C840C96009619D4 /* ASCollectionElement.mm */; }; @@ -824,8 +824,8 @@ DEC146B51C37A16A004A0EE7 /* ASCollectionInternal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ASCollectionInternal.m; path = Details/ASCollectionInternal.m; sourceTree = ""; }; DECBD6E51BE56E1900CF4905 /* ASButtonNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASButtonNode.h; sourceTree = ""; }; DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASButtonNode.mm; sourceTree = ""; }; - E516FC7D1E9FE24200714FF4 /* ASEqualityHashHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEqualityHashHelpers.h; sourceTree = ""; }; - E516FC7E1E9FE24200714FF4 /* ASEqualityHashHelpers.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASEqualityHashHelpers.mm; sourceTree = ""; }; + E516FC7D1E9FE24200714FF4 /* ASHashing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASHashing.h; sourceTree = ""; }; + E516FC7E1E9FE24200714FF4 /* ASHashing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASHashing.m; sourceTree = ""; }; E52405B21C8FEF03004DC8E7 /* ASLayoutTransition.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASLayoutTransition.mm; sourceTree = ""; }; E52405B41C8FEF16004DC8E7 /* ASLayoutTransition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutTransition.h; sourceTree = ""; }; E55D86311CA8A14000A0C26F /* ASLayoutElement.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASLayoutElement.mm; sourceTree = ""; }; @@ -1278,8 +1278,8 @@ 058D0A0C195D050800B7D73C /* ASDisplayNodeInternal.h */, 6959433D1D70815300B0EE1F /* ASDisplayNodeLayout.h */, 6959433C1D70815300B0EE1F /* ASDisplayNodeLayout.mm */, - E516FC7D1E9FE24200714FF4 /* ASEqualityHashHelpers.h */, - E516FC7E1E9FE24200714FF4 /* ASEqualityHashHelpers.mm */, + E516FC7D1E9FE24200714FF4 /* ASHashing.h */, + E516FC7E1E9FE24200714FF4 /* ASHashing.m */, 6900C5F31E8072DA00BCD75C /* ASImageNode+Private.h */, 68B8A4DB1CBD911D007E4543 /* ASImageNode+AnimatedImagePrivate.h */, 058D0A0D195D050800B7D73C /* ASImageNode+CGExtras.h */, @@ -1603,7 +1603,7 @@ 254C6B791BF94DF4003EC431 /* ASTextKitEntityAttribute.h in Headers */, CC3B20841C3F76D600798563 /* ASPendingStateController.h in Headers */, DE6EA3231C14000600183B10 /* ASDisplayNode+FrameworkPrivate.h in Headers */, - E516FC7F1E9FE24200714FF4 /* ASEqualityHashHelpers.h in Headers */, + E516FC7F1E9FE24200714FF4 /* ASHashing.h in Headers */, 9C70F20F1CDBE9FF007D6C76 /* ASLayoutManager.h in Headers */, 6947B0C31E36B5040007C478 /* ASStackPositionedLayout.h in Headers */, DBABFAFC1C6A8D2F0039EA4A /* _ASTransitionContext.h in Headers */, @@ -1961,7 +1961,7 @@ CCA282B91E9EA8E40037E8B7 /* AsyncDisplayKit+Tips.m in Sources */, 636EA1A51C7FF4EF00EE152F /* ASDefaultPlayButton.m in Sources */, B350623D1B010EFD0018CF92 /* _ASAsyncTransaction.mm in Sources */, - E516FC801E9FE24200714FF4 /* ASEqualityHashHelpers.mm in Sources */, + E516FC801E9FE24200714FF4 /* ASHashing.m in Sources */, 6947B0C51E36B5040007C478 /* ASStackPositionedLayout.mm in Sources */, B35062401B010EFD0018CF92 /* _ASAsyncTransactionContainer.m in Sources */, AC026B721BD57DBF00BBC17E /* _ASHierarchyChangeSet.mm in Sources */, diff --git a/Source/ASImageNode.mm b/Source/ASImageNode.mm index d975d0908..ef92f22cb 100644 --- a/Source/ASImageNode.mm +++ b/Source/ASImageNode.mm @@ -32,7 +32,7 @@ #import #import #import -#import +#import #import #import @@ -100,19 +100,26 @@ - (BOOL)isEqual:(id)object - (NSUInteger)hash { - NSUInteger subhashes[] = { - // Profiling shows that the work done in UIImage's `hash` is on the order of 0.005ms on an A5 processor - // and isn't proportional to the size of the image. - [_image hash], - ASHashFromCGSize(_backingSize), - ASHashFromCGRect(_imageDrawRect), - AS::hash()(_isOpaque), - [_backgroundColor hash], - AS::hash()((void*)_preContextBlock), - AS::hash()((void*)_postContextBlock), - AS::hash()((void*)_imageModificationBlock), + struct { + NSUInteger imageHash; + CGSize backingSize; + CGRect imageDrawRect; + BOOL isOpaque; + NSUInteger backgroundColorHash; + void *preContextBlock; + void *postContextBlock; + void *imageModificationBlock; + } data = { + _image.hash, + _backingSize, + _imageDrawRect, + _isOpaque, + _backgroundColor.hash, + (void *)_preContextBlock, + (void *)_postContextBlock, + (void *)_imageModificationBlock }; - return ASIntegerArrayHash(subhashes, sizeof(subhashes) / sizeof(subhashes[0])); + return ASHashBytes(&data, sizeof(data)); } @end diff --git a/Source/ASTextNode.mm b/Source/ASTextNode.mm index 742626400..251ab237d 100644 --- a/Source/ASTextNode.mm +++ b/Source/ASTextNode.mm @@ -34,7 +34,7 @@ #import #import -#import +#import #import /** @@ -68,7 +68,14 @@ @implementation ASTextNodeRendererKey - (NSUInteger)hash { - return _attributes.hash() ^ ASHashFromCGSize(_constrainedSize); + struct { + size_t attributesHash; + CGSize constrainedSize; + } data = { + _attributes.hash(), + _constrainedSize + }; + return ASHashBytes(&data, sizeof(data)); } - (BOOL)isEqual:(ASTextNodeRendererKey *)object diff --git a/Source/Details/ASCollectionLayoutContext.mm b/Source/Details/ASCollectionLayoutContext.mm index 6fa2e3fc4..d84de9f67 100644 --- a/Source/Details/ASCollectionLayoutContext.mm +++ b/Source/Details/ASCollectionLayoutContext.mm @@ -21,7 +21,7 @@ #import #import #import -#import +#import @implementation ASCollectionLayoutContext @@ -57,12 +57,16 @@ - (BOOL)isEqual:(id)other - (NSUInteger)hash { - NSUInteger subhashes[] = { - ASHashFromCGSize(_viewportSize), - [_elements hash], + struct { + CGSize viewportSize; + NSUInteger elementsHash; + NSUInteger addlInfoHash; + } data = { + _viewportSize, + _elements.hash, [_additionalInfo hash] }; - return ASIntegerArrayHash(subhashes, sizeof(subhashes) / sizeof(subhashes[0])); + return ASHashBytes(&data, sizeof(data)); } @end diff --git a/Source/Private/ASEqualityHashHelpers.h b/Source/Private/ASEqualityHashHelpers.h deleted file mode 100644 index 1457f75c7..000000000 --- a/Source/Private/ASEqualityHashHelpers.h +++ /dev/null @@ -1,186 +0,0 @@ -// -// ASEqualityHashHelpers.h -// Texture -// -// Copyright (c) 2014-present, Facebook, Inc. All rights reserved. -// This source code is licensed under the BSD-style license found in the -// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional -// grant of patent rights can be found in the PATENTS file in the same directory. -// -// Modifications to this file made after 4/13/2017 are: Copyright (c) 2017-present, -// Pinterest, Inc. Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// - -#import -#import -#import - -#import - -// From folly: -// This is the Hash128to64 function from Google's cityhash (available -// under the MIT License). We use it to reduce multiple 64 bit hashes -// into a single hash. -ASDISPLAYNODE_INLINE uint64_t ASHashCombine(const uint64_t upper, const uint64_t lower) { - // Murmur-inspired hashing. - const uint64_t kMul = 0x9ddfea08eb382d69ULL; - uint64_t a = (lower ^ upper) * kMul; - a ^= (a >> 47); - uint64_t b = (upper ^ a) * kMul; - b ^= (b >> 47); - b *= kMul; - return b; -} - -#if __LP64__ -ASDISPLAYNODE_INLINE size_t ASHash64ToNative(uint64_t key) { - return key; -} -#else - -// Thomas Wang downscaling hash function -ASDISPLAYNODE_INLINE size_t ASHash64ToNative(uint64_t key) { - key = (~key) + (key << 18); - key = key ^ (key >> 31); - key = key * 21; - key = key ^ (key >> 11); - key = key + (key << 6); - key = key ^ (key >> 22); - return (uint32_t) key; -} -#endif - -NSUInteger ASHashFromCGPoint(const CGPoint point); - -NSUInteger ASHashFromCGSize(const CGSize size); - -NSUInteger ASHashFromCGRect(const CGRect rect); - -NSUInteger ASIntegerArrayHash(const NSUInteger *subhashes, NSUInteger count); - -namespace AS { - // Default is not an ObjC class - template - struct is_objc_class : std::false_type { }; - - // Conditionally enable this template specialization on whether T is convertible to id, makes the is_objc_class a true_type - template - struct is_objc_class::value, bool>::type> : std::true_type { }; - - // ASUtils::hash()(value) -> either std::hash if c++ or [o hash] if ObjC object. - template struct hash; - - // For non-objc types, defer to std::hash - template struct hash::value>::type> { - size_t operator ()(const T& a) { - return std::hash()(a); - } - }; - - // For objc types, call [o hash] - template struct hash::value>::type> { - size_t operator ()(id o) { - return [o hash]; - } - }; - - template struct is_equal; - - // For non-objc types use == operator - template struct is_equal::value>::type> { - bool operator ()(const T& a, const T& b) { - return a == b; - } - }; - - // For objc types, check pointer equality, then use -isEqual: - template struct is_equal::value>::type> { - bool operator ()(id a, id b) { - return a == b || [a isEqual:b]; - } - }; - -}; - -namespace ASTupleOperations -{ - // Recursive case (hash up to Index) - template ::value - 1> - struct _hash_helper - { - static size_t hash(Tuple const& tuple) - { - size_t prev = _hash_helper::hash(tuple); - using TypeForIndex = typename std::tuple_element::type; - size_t thisHash = AS::hash()(std::get(tuple)); - return ASHashCombine(prev, thisHash); - } - }; - - // Base case (hash 0th element) - template - struct _hash_helper - { - static size_t hash(Tuple const& tuple) - { - using TypeForIndex = typename std::tuple_element<0,Tuple>::type; - return AS::hash()(std::get<0>(tuple)); - } - }; - - // Recursive case (elements equal up to Index) - template ::value - 1> - struct _eq_helper - { - static bool equal(Tuple const& a, Tuple const& b) - { - bool prev = _eq_helper::equal(a, b); - using TypeForIndex = typename std::tuple_element::type; - auto aValue = std::get(a); - auto bValue = std::get(b); - return prev && AS::is_equal()(aValue, bValue); - } - }; - - // Base case (0th elements equal) - template - struct _eq_helper - { - static bool equal(Tuple const& a, Tuple const& b) - { - using TypeForIndex = typename std::tuple_element<0,Tuple>::type; - auto& aValue = std::get<0>(a); - auto& bValue = std::get<0>(b); - return AS::is_equal()(aValue, bValue); - } - }; - - - template struct hash; - - template - struct hash> - { - size_t operator()(std::tuple const& tt) const - { - return _hash_helper>::hash(tt); - } - }; - - - template struct equal_to; - - template - struct equal_to> - { - bool operator()(std::tuple const& a, std::tuple const& b) const - { - return _eq_helper>::equal(a, b); - } - }; - -} diff --git a/Source/Private/ASEqualityHashHelpers.mm b/Source/Private/ASEqualityHashHelpers.mm deleted file mode 100644 index 441861ebb..000000000 --- a/Source/Private/ASEqualityHashHelpers.mm +++ /dev/null @@ -1,45 +0,0 @@ -// -// ASEqualityHashHelpers.mm -// Texture -// -// Copyright (c) 2014-present, Facebook, Inc. All rights reserved. -// This source code is licensed under the BSD-style license found in the -// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional -// grant of patent rights can be found in the PATENTS file in the same directory. -// -// Modifications to this file made after 4/13/2017 are: Copyright (c) 2017-present, -// Pinterest, Inc. Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// - -#import - -#import - -NSUInteger ASHashFromCGPoint(const CGPoint point) -{ - return ASHash64ToNative(ASHashCombine(std::hash()(point.x), std::hash()(point.y))); -} - -NSUInteger ASHashFromCGSize(const CGSize size) -{ - return ASHash64ToNative(ASHashCombine(std::hash()(size.width), std::hash()(size.height))); -} - -NSUInteger ASHashFromCGRect(const CGRect rect) -{ - return ASHashFromCGPoint(rect.origin) + ASHashFromCGSize(rect.size); -} - -NSUInteger ASIntegerArrayHash(const NSUInteger *subhashes, NSUInteger count) -{ - uint64_t result = subhashes[0]; - for (int ii = 1; ii < count; ++ii) { - result = ASHashCombine(result, subhashes[ii]); - } - return ASHash64ToNative(result); -} - diff --git a/Source/Private/ASHashing.h b/Source/Private/ASHashing.h new file mode 100644 index 000000000..3c905b70b --- /dev/null +++ b/Source/Private/ASHashing.h @@ -0,0 +1,46 @@ +// +// ASHashing.h +// Texture +// +// Copyright (c) 2014-present, Facebook, Inc. All rights reserved. +// This source code is licensed under the BSD-style license found in the +// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional +// grant of patent rights can be found in the PATENTS file in the same directory. +// +// Modifications to this file made after 4/13/2017 are: Copyright (c) 2017-present, +// Pinterest, Inc. Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN +ASDISPLAYNODE_EXTERN_C_BEGIN + +/** + * When std::hash is unavailable, this function will hash a bucket o' bits real fast. + * The hashing algorithm is copied from CoreFoundation's private function CFHashBytes. + * https://opensource.apple.com/source/CF/CF-1153.18/CFUtilities.c.auto.html + * + * Simple example: + * CGRect myRect = { ... }; + * ASHashBytes(&myRect, sizeof(myRect)); + * + * Example: + * struct { + * NSUInteger imageHash; + * CGSize size; + * } data = { + * _image.hash, + * _bounds.size + * }; + * return ASHashBytes(&data, sizeof(data)); + */ +NSUInteger ASHashBytes(void *bytes, size_t length); + +ASDISPLAYNODE_EXTERN_C_END +NS_ASSUME_NONNULL_END diff --git a/Source/Private/ASHashing.m b/Source/Private/ASHashing.m new file mode 100644 index 000000000..a248087a8 --- /dev/null +++ b/Source/Private/ASHashing.m @@ -0,0 +1,47 @@ +// +// ASHashing.m +// Texture +// +// Copyright (c) 2014-present, Facebook, Inc. All rights reserved. +// This source code is licensed under the BSD-style license found in the +// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional +// grant of patent rights can be found in the PATENTS file in the same directory. +// +// Modifications to this file made after 4/13/2017 are: Copyright (c) 2017-present, +// Pinterest, Inc. Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// + +#import + +#define ELF_STEP(B) T1 = (H << 4) + B; T2 = T1 & 0xF0000000; if (T2) T1 ^= (T2 >> 24); T1 &= (~T2); H = T1; + +/** + * The hashing algorithm copied from CoreFoundation CFHashBytes function. + * https://opensource.apple.com/source/CF/CF-1153.18/CFUtilities.c.auto.html + */ +NSUInteger ASHashBytes(void *bytesarg, size_t length) { + /* The ELF hash algorithm, used in the ELF object file format */ + uint8_t *bytes = (uint8_t *)bytesarg; + UInt32 H = 0, T1, T2; + SInt32 rem = (SInt32)length; + while (3 < rem) { + ELF_STEP(bytes[length - rem]); + ELF_STEP(bytes[length - rem + 1]); + ELF_STEP(bytes[length - rem + 2]); + ELF_STEP(bytes[length - rem + 3]); + rem -= 4; + } + switch (rem) { + case 3: ELF_STEP(bytes[length - 3]); + case 2: ELF_STEP(bytes[length - 2]); + case 1: ELF_STEP(bytes[length - 1]); + case 0: ; + } + return H; +} + +#undef ELF_STEP diff --git a/Source/TextKit/ASTextKitAttributes.mm b/Source/TextKit/ASTextKitAttributes.mm index c1bc231b5..3e6dc8082 100755 --- a/Source/TextKit/ASTextKitAttributes.mm +++ b/Source/TextKit/ASTextKitAttributes.mm @@ -17,27 +17,35 @@ #import -#import - -#include +#import NSString *const ASTextKitTruncationAttributeName = @"ck_truncation"; NSString *const ASTextKitEntityAttributeName = @"ck_entity"; size_t ASTextKitAttributes::hash() const { - NSUInteger subhashes[] = { + struct { + NSUInteger attrStringHash; + NSUInteger truncationStringHash; + NSUInteger avoidTrunactionSetHash; + NSLineBreakMode lineBreakMode; + NSUInteger maximumNumberOfLines; + NSUInteger exclusionPathsHash; + CGSize shadowOffset; + NSUInteger shadowColorHash; + CGFloat shadowOpacity; + CGFloat shadowRadius; + } data = { [attributedString hash], [truncationAttributedString hash], [avoidTailTruncationSet hash], - std::hash()(lineBreakMode), - std::hash()(maximumNumberOfLines), + lineBreakMode, + maximumNumberOfLines, [exclusionPaths hash], - std::hash()(shadowOffset.width), - std::hash()(shadowOffset.height), + shadowOffset, [shadowColor hash], - std::hash()(shadowOpacity), - std::hash()(shadowRadius), + shadowOpacity, + shadowRadius, }; - return ASIntegerArrayHash(subhashes, sizeof(subhashes) / sizeof(subhashes[0])); + return ASHashBytes(&data, sizeof(data)); } From c218b1bc6b237aa4a9c2854d2a5fab1025b877fb Mon Sep 17 00:00:00 2001 From: Adlai Holler Date: Fri, 28 Apr 2017 18:52:19 -0700 Subject: [PATCH 2/3] Update chingling --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bcbcd664..b4d99448f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,4 +4,5 @@ - Add support for IGListKit post-removal-of-IGListSectionType, in preparation for IGListKit 3.0.0 release. (Adlai-Holler)[https://github.com/Adlai-Holler] (#49)[https://github.com/TextureGroup/Texture/pull/49] - Fix `__has_include` check in ASLog.h [Philipp Smorygo](Philipp.Smorygo@jetbrains.com) - Fix potential deadlock in ASControlNode [Garrett Moon](https://github.com/garrettmoon) -- [Yoga Beta] Improvements to the experimental support for Yoga layout [Scott Goodson](appleguy) \ No newline at end of file +- [Yoga Beta] Improvements to the experimental support for Yoga layout [Scott Goodson](appleguy) +- Simplified & optimized hashing code. [Adlai Holler](https://github.com/Adlai-Holler) [#86](https://github.com/TextureGroup/Texture/pull/86) \ No newline at end of file From e2efeba0f9e4490e96af71f66fad5378052b55ee Mon Sep 17 00:00:00 2001 From: Adlai Holler Date: Fri, 28 Apr 2017 18:52:51 -0700 Subject: [PATCH 3/3] Update license --- Source/Private/ASHashing.h | 9 ++------- Source/Private/ASHashing.m | 9 ++------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/Source/Private/ASHashing.h b/Source/Private/ASHashing.h index 3c905b70b..c658a42d3 100644 --- a/Source/Private/ASHashing.h +++ b/Source/Private/ASHashing.h @@ -2,13 +2,8 @@ // ASHashing.h // Texture // -// Copyright (c) 2014-present, Facebook, Inc. All rights reserved. -// This source code is licensed under the BSD-style license found in the -// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional -// grant of patent rights can be found in the PATENTS file in the same directory. -// -// Modifications to this file made after 4/13/2017 are: Copyright (c) 2017-present, -// Pinterest, Inc. Licensed under the Apache License, Version 2.0 (the "License"); +// Copyright (c) 2017-present, Pinterest, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // diff --git a/Source/Private/ASHashing.m b/Source/Private/ASHashing.m index a248087a8..9f6d0f234 100644 --- a/Source/Private/ASHashing.m +++ b/Source/Private/ASHashing.m @@ -2,13 +2,8 @@ // ASHashing.m // Texture // -// Copyright (c) 2014-present, Facebook, Inc. All rights reserved. -// This source code is licensed under the BSD-style license found in the -// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional -// grant of patent rights can be found in the PATENTS file in the same directory. -// -// Modifications to this file made after 4/13/2017 are: Copyright (c) 2017-present, -// Pinterest, Inc. Licensed under the Apache License, Version 2.0 (the "License"); +// Copyright (c) 2017-present, Pinterest, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at //