blob: ee587dffa973ab80e44909d551edc1a0508fa814 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Objects.hpp"
#include "CacheableDate.hpp"
#include "ICacheableKey.hpp"
using namespace System;
using namespace System::Collections;
using namespace Apache::Geode::Client;
namespace Apache {
namespace Geode {
Int32 Objects::Hash(... array<Object^>^ values) {
return Objects::GetHashCode(values);
}
Int32 Objects::GetHashCode(Object^ value) {
if (nullptr == value) {
return 0;
} else if (auto s = dynamic_cast<String^>(value)) {
return GetHashCode(s);
} else if (auto i = dynamic_cast<Int32^>(value)) {
return GetHashCode(*i);
} else if (auto l = dynamic_cast<Int64^>(value)) {
return GetHashCode(*l);
} else if (auto s = dynamic_cast<Int16^>(value)) {
return GetHashCode(*s);
} else if (auto s = dynamic_cast<Char^>(value)) {
return GetHashCode(*s);
} else if (auto d = dynamic_cast<DateTime^>(value)) {
return GetHashCode(*d);
} else if (auto b = dynamic_cast<SByte^>(value)) {
return GetHashCode(*b);
} else if (auto s = dynamic_cast<Single^>(value)) {
return GetHashCode(*s);
} else if (auto d = dynamic_cast<Double^>(value)) {
return GetHashCode(*d);
} else if (auto b = dynamic_cast<Boolean^>(value)) {
return GetHashCode(*b);
} else if (auto k = dynamic_cast<ICacheableKey^>(value)) {
return k->GetHashCode();
} else if (auto c = dynamic_cast<IDictionary^>(value)) {
return GetHashCode(c);
} else if (auto c = dynamic_cast<ICollection^>(value)) {
return GetHashCode(c);
}
return value->GetHashCode();
}
Int32 Objects::GetHashCode(String^ value) {
Int32 hash = 0;
for each(auto c in value) {
hash = 31 * hash + c;
}
return hash;
}
Int32 Objects::GetHashCode(Char value) { return value; }
Int32 Objects::GetHashCode(Boolean value) { return value ? 1231 : 1237; }
Int32 Objects::GetHashCode(SByte value) { return value; }
Int32 Objects::GetHashCode(Int16 value) { return value; }
Int32 Objects::GetHashCode(Int32 value) { return value; }
Int32 Objects::GetHashCode(Int64 value) {
return static_cast<Int32>(value ^ (value >> 32));
}
union float_int64_t {
float f;
int32_t u;
};
constexpr auto kJavaFloatNaN = 0x7fc00000;
Int32 Objects::GetHashCode(Single value) {
float_int64_t v;
if (Single::IsNaN(value)) {
// .NET and Java don't aggree on NaN encoding
v.u = kJavaFloatNaN;
} else {
v.f = value;
}
return GetHashCode(v.u);
}
union double_int64_t {
double d;
int64_t u;
};
constexpr auto kJavaDoubleNaN = 0x7ff8000000000000L;
Int32 Objects::GetHashCode(Double value) {
double_int64_t v;
if (Double::IsNaN(value)) {
// .NET and Java don't aggree on NaN encoding
v.u = kJavaDoubleNaN;
} else {
v.d = value;
}
return GetHashCode(v.u);
}
Int32 Objects::GetHashCode(DateTime^ value) {
if (value == nullptr) {
return 0;
}
return GetHashCode(*value);
}
Int32 Objects::GetHashCode(DateTime value) {
auto timeSpanSinceEpoch = value - CacheableDate::EpochTime;
auto milliseconds = timeSpanSinceEpoch.Ticks / TimeSpan::TicksPerMillisecond;
return GetHashCode(milliseconds);
}
Int32 Objects::GetHashCode(ICollection^ value) {
if (value == nullptr) {
return 0;
}
int result = 1;
for each (auto element in value) {
result = 31 * result + Objects::GetHashCode(element);
}
return result;
}
Int32 Objects::GetHashCode(System::Collections::IDictionary^ dictionary) {
int h = 0;
for each(System::Collections::DictionaryEntry^ entry in dictionary)
{
h = h + (GetHashCode(entry->Key) ^ GetHashCode(entry->Value));
}
return h;
}
} // namespace Geode
} // namespace Apache