diff --git a/pandas/_libs/skiplist.pxd b/pandas/_libs/skiplist.pxd new file mode 100644 index 0000000000000..82a0862112199 --- /dev/null +++ b/pandas/_libs/skiplist.pxd @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# cython: profile=False + +from cython cimport Py_ssize_t + +from numpy cimport double_t + + +cdef extern from "src/skiplist.h": + ctypedef struct node_t: + node_t **next + int *width + double value + int is_nil + int levels + int ref_count + + ctypedef struct skiplist_t: + node_t *head + node_t **tmp_chain + int *tmp_steps + int size + int maxlevels + + skiplist_t* skiplist_init(int) nogil + void skiplist_destroy(skiplist_t*) nogil + double skiplist_get(skiplist_t*, int, int*) nogil + int skiplist_insert(skiplist_t*, double) nogil + int skiplist_remove(skiplist_t*, double) nogil + + +# Note: Node is declared here so that IndexableSkiplist can be exposed; +# Node itself not intended to be exposed. +cdef class Node: + cdef public: + double_t value + list next + list width + + +cdef class IndexableSkiplist: + cdef: + Py_ssize_t size, maxlevels + Node head + + cpdef get(self, Py_ssize_t i) + cpdef insert(self, double value) + cpdef remove(self, double value) diff --git a/pandas/_libs/src/skiplist.pyx b/pandas/_libs/skiplist.pyx similarity index 95% rename from pandas/_libs/src/skiplist.pyx rename to pandas/_libs/skiplist.pyx index 1524dca38d0e0..c96413edfb0f2 100644 --- a/pandas/_libs/src/skiplist.pyx +++ b/pandas/_libs/skiplist.pyx @@ -6,8 +6,7 @@ # Cython version: Wes McKinney -cdef extern from "math.h": - double log(double x) +from libc.math cimport log # MSVC does not have log2! @@ -16,6 +15,7 @@ cdef double Log2(double x): cimport numpy as np import numpy as np +from numpy cimport double_t from random import random @@ -25,10 +25,10 @@ np.import_array() # TODO: optimize this, make less messy cdef class Node: - cdef public: - double_t value - list next - list width + # cdef public: + # double_t value + # list next + # list width def __init__(self, double_t value, list next, list width): self.value = value @@ -43,9 +43,9 @@ cdef class IndexableSkiplist: Sorted collection supporting O(lg n) insertion, removal, and lookup by rank. """ - cdef: - Py_ssize_t size, maxlevels - Node head + # cdef: + # Py_ssize_t size, maxlevels + # Node head def __init__(self, expected_size=100): self.size = 0 diff --git a/pandas/_libs/src/skiplist.pxd b/pandas/_libs/src/skiplist.pxd deleted file mode 100644 index 214aa1c7aeaf0..0000000000000 --- a/pandas/_libs/src/skiplist.pxd +++ /dev/null @@ -1,22 +0,0 @@ -cdef extern from "skiplist.h": - ctypedef struct node_t: - node_t **next - int *width - double value - int is_nil - int levels - int ref_count - - ctypedef struct skiplist_t: - node_t *head - node_t **tmp_chain - int *tmp_steps - int size - int maxlevels - - skiplist_t* skiplist_init(int) nogil - void skiplist_destroy(skiplist_t*) nogil - double skiplist_get(skiplist_t*, int, int*) nogil - int skiplist_insert(skiplist_t*, double) nogil - int skiplist_remove(skiplist_t*, double) nogil - diff --git a/pandas/_libs/window.pyx b/pandas/_libs/window.pyx index 95df5a07a390b..ecce45742afa7 100644 --- a/pandas/_libs/window.pyx +++ b/pandas/_libs/window.pyx @@ -14,9 +14,13 @@ cimport util from libc.stdlib cimport malloc, free - from numpy cimport ndarray, double_t, int64_t, float64_t +from skiplist cimport (IndexableSkiplist, + node_t, skiplist_t, + skiplist_init, skiplist_destroy, + skiplist_get, skiplist_insert, skiplist_remove) + cdef np.float32_t MINfloat32 = np.NINF cdef np.float64_t MINfloat64 = np.NINF @@ -30,19 +34,10 @@ cdef inline int int_min(int a, int b): return a if a <= b else b from util cimport numeric -from skiplist cimport ( - skiplist_t, - skiplist_init, - skiplist_destroy, - skiplist_get, - skiplist_insert, - skiplist_remove) - cdef extern from "../src/headers/math.h": - double sqrt(double x) nogil int signbit(double) nogil + double sqrt(double x) nogil -include "skiplist.pyx" # Cython implementations of rolling sum, mean, variance, skewness, # other statistical moment functions diff --git a/setup.py b/setup.py index 7e56298d1b20b..37be0b696503d 100755 --- a/setup.py +++ b/setup.py @@ -341,6 +341,7 @@ class CheckSDist(sdist_class): 'pandas/_libs/missing.pyx', 'pandas/_libs/testing.pyx', 'pandas/_libs/window.pyx', + 'pandas/_libs/skiplist.pyx', 'pandas/_libs/sparse.pyx', 'pandas/_libs/parsers.pyx', 'pandas/_libs/tslibs/strptime.pyx', @@ -544,6 +545,9 @@ def pxd(name): '_libs.reshape': { 'pyxfile': '_libs/reshape', 'depends': _pxi_dep['reshape']}, + '_libs.skiplist': { + 'pyxfile': '_libs/skiplist', + 'depends': ['pandas/_libs/src/skiplist.h']}, '_libs.sparse': { 'pyxfile': '_libs/sparse', 'depends': _pxi_dep['sparse']}, @@ -629,9 +633,7 @@ def pxd(name): 'pyxfile': '_libs/testing'}, '_libs.window': { 'pyxfile': '_libs/window', - 'pxdfiles': ['_libs/src/skiplist', '_libs/src/util'], - 'depends': ['pandas/_libs/src/skiplist.pyx', - 'pandas/_libs/src/skiplist.h']}, + 'pxdfiles': ['_libs/skiplist', '_libs/src/util']}, 'io.sas._sas': { 'pyxfile': 'io/sas/sas'}}