aboutsummaryrefslogtreecommitdiffhomepage
path: root/Firestore/Source/Model
diff options
context:
space:
mode:
authorGravatar Gil <mcg@google.com>2018-01-19 12:27:11 -0800
committerGravatar GitHub <noreply@github.com>2018-01-19 12:27:11 -0800
commit39d8252300015c26f1932cff42032613fdb36a09 (patch)
tree93bb3ab7c476289c4afe6cf91773a60b6f53a94d /Firestore/Source/Model
parent9f7c094f9f00a6efc0107071f109ef1bc4d7357d (diff)
Port comparison to C++ (#678)
This reimplements our comparison functions as C++ Comparators and then provides compatibility shims for interoperating with existing Objective-C usage. A few specialized comparators aren't suitable for porting but only have a single usage (e.g. CompareBytes for comparing NSData * instances). In these cases I've moved them into the caller. * Use int32_t for typeof(ID) in FSTDocumentReference * Migrate callers of FSTComparison.h to Objective-C++ * Port comparison to C++ * Migrate usages of FSTComparison.h to C++ equivalents * Remove FSTComparison
Diffstat (limited to 'Firestore/Source/Model')
-rw-r--r--Firestore/Source/Model/FSTFieldValue.mm (renamed from Firestore/Source/Model/FSTFieldValue.m)72
1 files changed, 58 insertions, 14 deletions
diff --git a/Firestore/Source/Model/FSTFieldValue.m b/Firestore/Source/Model/FSTFieldValue.mm
index a6326a7..8ffc98e 100644
--- a/Firestore/Source/Model/FSTFieldValue.m
+++ b/Firestore/Source/Model/FSTFieldValue.mm
@@ -16,6 +16,9 @@
#import "Firestore/Source/Model/FSTFieldValue.h"
+#include "Firestore/core/src/firebase/firestore/util/comparison.h"
+#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
+
#import "Firestore/Source/API/FIRGeoPoint+Internal.h"
#import "Firestore/Source/API/FIRSnapshotOptions+Internal.h"
#import "Firestore/Source/Core/FSTTimestamp.h"
@@ -24,7 +27,14 @@
#import "Firestore/Source/Model/FSTPath.h"
#import "Firestore/Source/Util/FSTAssert.h"
#import "Firestore/Source/Util/FSTClasses.h"
-#import "Firestore/Source/Util/FSTComparison.h"
+
+using firebase::firestore::util::Comparator;
+using firebase::firestore::util::CompareMixedNumber;
+using firebase::firestore::util::DoubleBitwiseEquals;
+using firebase::firestore::util::DoubleBitwiseHash;
+using firebase::firestore::util::MakeStringView;
+using firebase::firestore::util::ReverseOrder;
+using firebase::firestore::util::WrapCompare;
NS_ASSUME_NONNULL_BEGIN
@@ -208,7 +218,7 @@ NS_ASSUME_NONNULL_BEGIN
- (NSComparisonResult)compare:(FSTFieldValue *)other {
if ([other isKindOfClass:[FSTBooleanValue class]]) {
- return FSTCompareBools(self.internalValue, ((FSTBooleanValue *)other).internalValue);
+ return WrapCompare<bool>(self.internalValue, ((FSTBooleanValue *)other).internalValue);
} else {
return [self defaultCompare:other];
}
@@ -231,19 +241,22 @@ NS_ASSUME_NONNULL_BEGIN
if ([self isKindOfClass:[FSTDoubleValue class]]) {
double thisDouble = ((FSTDoubleValue *)self).internalValue;
if ([other isKindOfClass:[FSTDoubleValue class]]) {
- return FSTCompareDoubles(thisDouble, ((FSTDoubleValue *)other).internalValue);
+ return WrapCompare(thisDouble, ((FSTDoubleValue *)other).internalValue);
} else {
FSTAssert([other isKindOfClass:[FSTIntegerValue class]], @"Unknown number value: %@",
other);
- return FSTCompareMixed(thisDouble, ((FSTIntegerValue *)other).internalValue);
+ auto result = CompareMixedNumber(thisDouble, ((FSTIntegerValue *)other).internalValue);
+ return static_cast<NSComparisonResult>(result);
}
} else {
int64_t thisInt = ((FSTIntegerValue *)self).internalValue;
if ([other isKindOfClass:[FSTIntegerValue class]]) {
- return FSTCompareInt64s(thisInt, ((FSTIntegerValue *)other).internalValue);
+ return WrapCompare(thisInt, ((FSTIntegerValue *)other).internalValue);
} else {
FSTAssert([other isKindOfClass:[FSTDoubleValue class]], @"Unknown number value: %@", other);
- return -1 * FSTCompareMixed(((FSTDoubleValue *)other).internalValue, thisInt);
+ double otherDouble = ((FSTDoubleValue *)other).internalValue;
+ auto result = ReverseOrder(CompareMixedNumber(otherDouble, thisInt));
+ return static_cast<NSComparisonResult>(result);
}
}
}
@@ -334,11 +347,11 @@ NS_ASSUME_NONNULL_BEGIN
// NOTE: isEqual: should compare NaN equal to itself and -0.0 not equal to 0.0.
return [other isKindOfClass:[FSTDoubleValue class]] &&
- FSTDoubleBitwiseEquals(self.internalValue, ((FSTDoubleValue *)other).internalValue);
+ DoubleBitwiseEquals(self.internalValue, ((FSTDoubleValue *)other).internalValue);
}
- (NSUInteger)hash {
- return FSTDoubleBitwiseHash(self.internalValue);
+ return DoubleBitwiseHash(self.internalValue);
}
// NOTE: compare: is implemented in NumberValue.
@@ -347,6 +360,17 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - FSTStringValue
+/**
+ * Specialization of Comparator for NSStrings.
+ */
+template <>
+struct Comparator<NSString *> {
+ bool operator()(NSString *left, NSString *right) const {
+ Comparator<absl::string_view> lessThan;
+ return lessThan(MakeStringView(left), MakeStringView(right));
+ }
+};
+
@interface FSTStringValue ()
@property(nonatomic, copy, readonly) NSString *internalValue;
@end
@@ -385,7 +409,7 @@ NS_ASSUME_NONNULL_BEGIN
- (NSComparisonResult)compare:(FSTFieldValue *)other {
if ([other isKindOfClass:[FSTStringValue class]]) {
- return FSTCompareStrings(self.internalValue, ((FSTStringValue *)other).internalValue);
+ return WrapCompare(self.internalValue, ((FSTStringValue *)other).internalValue);
} else {
return [self defaultCompare:other];
}
@@ -556,6 +580,22 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - FSTBlobValue
+static NSComparisonResult CompareBytes(NSData *left, NSData *right) {
+ NSUInteger minLength = MIN(left.length, right.length);
+ int result = memcmp(left.bytes, right.bytes, minLength);
+ if (result < 0) {
+ return NSOrderedAscending;
+ } else if (result > 0) {
+ return NSOrderedDescending;
+ } else if (left.length < right.length) {
+ return NSOrderedAscending;
+ } else if (left.length > right.length) {
+ return NSOrderedDescending;
+ } else {
+ return NSOrderedSame;
+ }
+}
+
@interface FSTBlobValue ()
@property(nonatomic, copy, readonly) NSData *internalValue;
@end
@@ -594,7 +634,7 @@ NS_ASSUME_NONNULL_BEGIN
- (NSComparisonResult)compare:(FSTFieldValue *)other {
if ([other isKindOfClass:[FSTBlobValue class]]) {
- return FSTCompareBytes(self.internalValue, ((FSTBlobValue *)other).internalValue);
+ return CompareBytes(self.internalValue, ((FSTBlobValue *)other).internalValue);
} else {
return [self defaultCompare:other];
}
@@ -664,6 +704,10 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - FSTObjectValue
+static const NSComparator StringComparator = ^NSComparisonResult(NSString *left, NSString *right) {
+ return WrapCompare(left, right);
+};
+
@interface FSTObjectValue ()
@property(nonatomic, strong, readonly)
FSTImmutableSortedDictionary<NSString *, FSTFieldValue *> *internalValue;
@@ -677,7 +721,7 @@ NS_ASSUME_NONNULL_BEGIN
dispatch_once(&onceToken, ^{
FSTImmutableSortedDictionary<NSString *, FSTFieldValue *> *empty =
- [FSTImmutableSortedDictionary dictionaryWithComparator:FSTStringComparator];
+ [FSTImmutableSortedDictionary dictionaryWithComparator:StringComparator];
sharedEmptyInstance = [[FSTObjectValue alloc] initWithImmutableDictionary:empty];
});
return sharedEmptyInstance;
@@ -694,7 +738,7 @@ NS_ASSUME_NONNULL_BEGIN
- (id)initWithDictionary:(NSDictionary<NSString *, FSTFieldValue *> *)value {
FSTImmutableSortedDictionary<NSString *, FSTFieldValue *> *dictionary =
- [FSTImmutableSortedDictionary dictionaryWithDictionary:value comparator:FSTStringComparator];
+ [FSTImmutableSortedDictionary dictionaryWithDictionary:value comparator:StringComparator];
return [self initWithImmutableDictionary:dictionary];
}
@@ -748,7 +792,7 @@ NS_ASSUME_NONNULL_BEGIN
key2 = [enumerator2 nextObject];
}
// Only equal if both enumerators are exhausted.
- return FSTCompareBools(key1 != nil, key2 != nil);
+ return WrapCompare(key1 != nil, key2 != nil);
} else {
return [self defaultCompare:other];
}
@@ -876,7 +920,7 @@ NS_ASSUME_NONNULL_BEGIN
return cmp;
}
}
- return FSTCompareUIntegers(selfArray.count, otherArray.count);
+ return WrapCompare<int64_t>(selfArray.count, otherArray.count);
} else {
return [self defaultCompare:other];
}