From 5aa9d6efaaa5f59351e5a93ff23ca531cf48bf4c Mon Sep 17 00:00:00 2001 From: Guillaume Horel Date: Wed, 22 Nov 2017 15:27:09 -0500 Subject: no need to allocate for hashing --- pyisda/curve.pxd | 7 +++++++ pyisda/curve.pyx | 42 +++++++----------------------------------- 2 files changed, 14 insertions(+), 35 deletions(-) diff --git a/pyisda/curve.pxd b/pyisda/curve.pxd index daec974..d36de20 100644 --- a/pyisda/curve.pxd +++ b/pyisda/curve.pxd @@ -41,6 +41,7 @@ cdef extern from "isda/bastypes.h": cdef extern from "farmhash.h" namespace 'util' nogil: uint64_t Hash64(const char *buff, size_t len) + uint64_t Hash64WithSeed(const char *buff, size_t len, uint64_t seed) cdef inline size_t TCurve_size(int num_items) nogil: return sizeof(int) + sizeof(TDate) + sizeof(double) + \ @@ -57,6 +58,12 @@ cdef inline void serialize(TCurve* curve, unsigned char* buf) nogil: buf += sizeof(double) memcpy(buf, &(curve.fDayCountConv), sizeof(long)) +cdef inline uint64_t hash_curve(TCurve* curve) nogil: + cdef uint64_t seed = Hash64(curve.fArray, sizeof(TRatePt) * curve.fNumItems) + seed = Hash64WithSeed(&(curve.fBaseDate), sizeof(TDate), seed) + seed = Hash64WithSeed(&(curve.fBasis), sizeof(double), seed) + return Hash64WithSeed(&(curve.fDayCountConv), sizeof(long), seed) + cdef inline unsigned char* deserialize(unsigned char* buf, TCurve* curve) nogil: memcpy(&curve.fNumItems, buf, sizeof(curve.fNumItems)) buf += sizeof(curve.fNumItems) diff --git a/pyisda/curve.pyx b/pyisda/curve.pyx index e852d3d..f7f48d9 100644 --- a/pyisda/curve.pyx +++ b/pyisda/curve.pyx @@ -76,14 +76,7 @@ cdef class Curve(object): return instance def __hash__(self): - cdef: - TCurve* curve = self._thisptr.get() - size_t curve_size = TCurve_size(curve.fNumItems) - unsigned char* buf = malloc(curve_size * sizeof(unsigned char)) - serialize(curve, buf) - cdef uint64_t r = Hash64(buf, curve_size) - free(buf) - return r + return hash_curve(self._thisptr.get()) def inspect(self): """ method to inspect the content of the C struct @@ -354,20 +347,8 @@ cdef class YieldCurve(Curve): return instance def __hash__(self): - cdef: - TCurve* curve = self._thisptr.get() - size_t size = TCurve_size(curve.fNumItems) - size_t buf_size = size + sizeof(size_t) + sizeof(TDate) * self.dates.size() - unsigned char* buf = malloc(buf_size) - unsigned char* cursor = buf + size - serialize(curve, buf) - size = self.dates.size() - memcpy(cursor, &size, sizeof(size_t)) - cursor += sizeof(size_t) - memcpy(cursor, self.dates.data(), sizeof(TDate) * size) - cdef uint64_t r = Hash64(buf, buf_size) - free(buf) - return r + cdef uint64_t seed = hash_curve(self._thisptr.get()) + return Hash64WithSeed(self.dates.data(), sizeof(TDate) * self.dates.size(), seed) @classmethod def from_discount_factors(cls, base_date, list dates, double[:] dfs, str day_count_conv): @@ -615,19 +596,10 @@ cdef class SpreadCurve(Curve): return instance def __hash__(self): - cdef: - TCurve* curve = self._thisptr.get() - size_t size = TCurve_size(curve.fNumItems) - size_t buf_size = size + sizeof(size_t) + self.ticker.length() + \ - curve.fNumItems * sizeof(double) - unsigned char* buf = malloc(buf_size) - unsigned char* cursor = buf + size - serialize(curve, buf) - cursor += self.ticker.copy(cursor, self.ticker.length(), 0) - memcpy(cursor, self.recovery_rates.get(), curve.fNumItems * sizeof(double)) - cdef uint64_t r = Hash64(buf, buf_size) - free(buf) - return r + cdef uint64_t seed = hash_curve(self._thisptr.get()) + seed = Hash64WithSeed(self.ticker.data(), self.ticker.length(), seed) + return Hash64WithSeed(self.recovery_rates.get(), + sizeof(double) * self._thisptr.get().fNumItems, seed) @classmethod def from_flat_hazard(cls, base_date, double rate, Basis basis=CONTINUOUS, -- cgit v1.2.3-70-g09d2