summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pyisda/curve.pxd7
-rw-r--r--pyisda/curve.pyx42
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(<char*>curve.fArray, sizeof(TRatePt) * curve.fNumItems)
+ seed = Hash64WithSeed(<char*>&(curve.fBaseDate), sizeof(TDate), seed)
+ seed = Hash64WithSeed(<char*>&(curve.fBasis), sizeof(double), seed)
+ return Hash64WithSeed(<char*>&(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 = <unsigned char*>malloc(curve_size * sizeof(unsigned char))
- serialize(curve, buf)
- cdef uint64_t r = Hash64(<char*>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 = <unsigned char*>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(<char*>buf, buf_size)
- free(buf)
- return r
+ cdef uint64_t seed = hash_curve(self._thisptr.get())
+ return Hash64WithSeed(<char*>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 = <unsigned char*>malloc(buf_size)
- unsigned char* cursor = buf + size
- serialize(curve, buf)
- cursor += self.ticker.copy(<char*>cursor, self.ticker.length(), 0)
- memcpy(cursor, self.recovery_rates.get(), curve.fNumItems * sizeof(double))
- cdef uint64_t r = Hash64(<char*>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(<char*>self.recovery_rates.get(),
+ sizeof(double) * self._thisptr.get().fNumItems, seed)
@classmethod
def from_flat_hazard(cls, base_date, double rate, Basis basis=CONTINUOUS,