Skip to content

Commit

Permalink
CFFI version added #10
Browse files Browse the repository at this point in the history
  • Loading branch information
ifduyue committed Feb 5, 2017
1 parent 388978f commit f5e56ef
Show file tree
Hide file tree
Showing 12 changed files with 155 additions and 24 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
*.pyc
*.py[co]
*.so
*.o
__pycache__/
build
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "xxhash"]
path = xxhash
path = c-xxhash
url = https://github.com/Cyan4973/xxHash.git
9 changes: 9 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
language: python

python:
- 2.6
- 2.7
Expand All @@ -7,8 +8,16 @@ python:
- 3.4
- 3.5
- 3.6
- pypy

install:
- pip install cffi
- gcc --version

env:
- XXHASH_FORCE_CFFI=1
- XXHASH_FORCE_CFFI=0

script: python setup.py test
deploy:
provider: pypi
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2014-2016, Yue Du
Copyright (c) 2014-2017, Yue Du
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
Expand Down
7 changes: 5 additions & 2 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
include README.rst
include LICENSE
include xxhash/xxhash.h
include xxhash/xxhash.c
include c-xxhash/xxhash.h
include c-xxhash/xxhash.c
graft tests
global-exclude __pycache__
global-exclude *.py[co]
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ functions are required.
Copyright and License
---------------------

Copyright (c) 2014-2016 Yue Du - https://github.com/ifduyue
Copyright (c) 2014-2017 Yue Du - https://github.com/ifduyue

Licensed under `BSD 2-Clause License <http://opensource.org/licenses/BSD-2-Clause>`_

32 changes: 23 additions & 9 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@
from setuptools import setup, Extension
import os

VERSION = "0.6.1"
with open('xxhash/__init__.py', 'rb') as f:
for line in f:
if line.startswith('VERSION = '):
VERSION = eval(line.rsplit(None, 1)[-1])

USE_CPYTHON = os.getenv('XXHASH_FORCE_CFFI') in (None, '0')

if os.name == 'posix':
extra_compile_args = [
Expand All @@ -23,6 +28,20 @@
('VERSION', VERSION),
]

if USE_CPYTHON:
ext_modules = [
Extension(
'xxhash_cpython',
['xxhash/cpython.c', 'c-xxhash/xxhash.c'],
extra_compile_args=extra_compile_args,
define_macros=define_macros,
include_dirs=['c-xxhash']
)
]
else:
import xxhash.cffi
ext_modules = [xxhash.cffi.ffibuilder.verifier.get_extension()]

setup(
name='xxhash',
version=VERSION,
Expand All @@ -32,14 +51,9 @@
author_email='[email protected]',
url='https://github.com/ifduyue/python-xxhash',
license='BSD',
ext_modules=[
Extension('xxhash', [
'python-xxhash.c',
'xxhash/xxhash.c',
],
extra_compile_args=extra_compile_args,
define_macros=define_macros)
],
packages=['xxhash'],
ext_package='xxhash',
ext_modules=ext_modules,
setup_requires=["nose>=1.3.0"],
test_suite='nose.collector',
classifiers=[
Expand Down
1 change: 1 addition & 0 deletions tests/test.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#from __future__ import absolute_import
import os
import unittest
import random
Expand Down
10 changes: 10 additions & 0 deletions xxhash/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from __future__ import absolute_import

try:
from xxhash.xxhash_cpython import xxh32, xxh64, XXHASH_VERSION
except ImportError:
from xxhash.cffi import xxh32, xxh64, XXHASH_VERSION


VERSION = '1.0.dev0'
__all__ = ['xxh32', 'xxh64', 'VERSION', 'XXHASH_VERSION']
92 changes: 92 additions & 0 deletions xxhash/cffi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
from __future__ import absolute_import

import cffi
import struct
import binascii

ffibuilder = cffi.FFI()
ffibuilder.cdef('''
#define XXH_VERSION_MAJOR ...
#define XXH_VERSION_MINOR ...
#define XXH_VERSION_RELEASE ...
typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
typedef unsigned int XXH32_hash_t;
typedef struct XXH32_state_s XXH32_state_t; /* incomplete type */
XXH32_state_t* XXH32_createState(void);
XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr);
void XXH32_copyState(XXH32_state_t* restrict dst_state, const XXH32_state_t* restrict src_state);
XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned int seed);
XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);
XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr);
typedef unsigned long long XXH64_hash_t;
typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */
XXH64_state_t* XXH64_createState(void);
XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr);
void XXH64_copyState(XXH64_state_t* restrict dst_state, const XXH64_state_t* restrict src_state);
XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed);
XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);
XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr);
''')


lib = ffibuilder.verify(
'''#include "xxhash.h"''',
modulename='xxhash_cffi',
ext_package='xxhash',
sources=['c-xxhash/xxhash.c'],
include_dirs=['c-xxhash']
)


XXHASH_VERSION = "{}.{}.{}".format(lib.XXH_VERSION_MAJOR,
lib.XXH_VERSION_MINOR,
lib.XXH_VERSION_RELEASE)


class xxh32(object):
def __init__(self, input=None, seed=0):
self.xxhash_state = ffibuilder.gc(lib.XXH32_createState(), lib.XXH32_freeState)
lib.XXH32_reset(self.xxhash_state, seed)
if input:
lib.XXH32_update(self.xxhash_state, input, len(input))

def update(self, input):
lib.XXH32_update(self.xxhash_state, input, len(input))

def intdigest(self):
return lib.XXH32_digest(self.xxhash_state)

def digest(self):
return struct.pack('>I', self.intdigest())

def hexdigest(self):
return binascii.hexlify(self.digest())


class xxh64(object):
def __init__(self, input=None, seed=0):
self.xxhash_state = ffibuilder.gc(lib.XXH64_createState(), lib.XXH64_freeState)
lib.XXH64_reset(self.xxhash_state, seed)
if input:
lib.XXH64_update(self.xxhash_state, input, len(input))

def update(self, input):
lib.XXH64_update(self.xxhash_state, input, len(input))

def intdigest(self):
return lib.XXH64_digest(self.xxhash_state)

def digest(self):
return struct.pack('>Q', self.intdigest())

def hexdigest(self):
return binascii.hexlify(self.digest())
17 changes: 8 additions & 9 deletions python-xxhash.c → xxhash/cpython.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2016, Yue Du
* Copyright (c) 2014-2017, Yue Du
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
Expand Down Expand Up @@ -30,12 +30,12 @@

#include <Python.h>

#include "xxhash/xxhash.h"
#include "xxhash.h"

#define TOSTRING(x) #x
#define VALUE_TO_STRING(x) TOSTRING(x)

#define XXHASH_VERSION XXH_VERSION_MAJOR.XXH_VERSION_MINOR.XXH_VERSION_RELEASE

#define XXH32_DIGESTSIZE 4
#define XXH32_BLOCKSIZE 16
#define XXH64_DIGESTSIZE 8
Expand Down Expand Up @@ -810,7 +810,7 @@ static int myextension_clear(PyObject *m)

static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
"xxhash",
"xxhash_cpython",
NULL,
sizeof(struct module_state),
methods,
Expand All @@ -822,12 +822,12 @@ static struct PyModuleDef moduledef = {

#define INITERROR return NULL

PyObject *PyInit_xxhash(void)
PyObject *PyInit_xxhash_cpython(void)

#else
#define INITERROR return

void initxxhash(void)
void initxxhash_cpython(void)
#endif
{
PyObject *module;
Expand All @@ -836,7 +836,7 @@ void initxxhash(void)
#if PY_MAJOR_VERSION >= 3
module = PyModule_Create(&moduledef);
#else
module = Py_InitModule("xxhash", methods);
module = Py_InitModule("xxhash_cpython", methods);
#endif

if (module == NULL) {
Expand All @@ -845,7 +845,7 @@ void initxxhash(void)

st = GETSTATE(module);

st->error = PyErr_NewException("xxhash.Error", NULL, NULL);
st->error = PyErr_NewException("xxhash_cpython.Error", NULL, NULL);

if (st->error == NULL) {
Py_DECREF(module);
Expand All @@ -867,7 +867,6 @@ void initxxhash(void)
Py_INCREF(&PYXXH64Type);
PyModule_AddObject(module, "xxh64", (PyObject *)&PYXXH64Type);

PyModule_AddStringConstant(module, "VERSION", VALUE_TO_STRING(VERSION));
PyModule_AddStringConstant(module, "XXHASH_VERSION", VALUE_TO_STRING(XXHASH_VERSION));

#if PY_MAJOR_VERSION >= 3
Expand Down

0 comments on commit f5e56ef

Please sign in to comment.