@@ -8,12 +8,11 @@ import multiprocessing
8
8
import os
9
9
10
10
11
- from cpython.buffer cimport PyBUF_ANY_CONTIGUOUS, PyBUF_WRITEABLE
11
+ from cpython.buffer cimport PyBuffer_IsContiguous
12
12
from cpython.bytes cimport PyBytes_FromStringAndSize, PyBytes_AS_STRING
13
+ from cpython.memoryview cimport PyMemoryView_GET_BUFFER
13
14
14
15
15
- from .compat_ext cimport Buffer
16
- from .compat_ext import Buffer
17
16
from .compat import ensure_contiguous_ndarray
18
17
from .abc import Codec
19
18
@@ -146,34 +145,36 @@ def cbuffer_sizes(source):
146
145
147
146
"""
148
147
cdef:
149
- Buffer buffer
148
+ memoryview source_mv
149
+ const Py_buffer* source_pb
150
150
size_t nbytes, cbytes, blocksize
151
151
152
- # obtain buffer
153
- buffer = Buffer(source, PyBUF_ANY_CONTIGUOUS)
152
+ # obtain source memoryview
153
+ source_mv = memoryview(source)
154
+ source_pb = PyMemoryView_GET_BUFFER(source_mv)
155
+ if not PyBuffer_IsContiguous(source_pb, b' A' ):
156
+ raise BufferError(" `source` must contain contiguous memory" )
154
157
155
158
# determine buffer size
156
- blosc_cbuffer_sizes(buffer .ptr, & nbytes, & cbytes, & blocksize)
157
-
158
- # release buffers
159
- buffer .release()
159
+ blosc_cbuffer_sizes(source_pb.buf, & nbytes, & cbytes, & blocksize)
160
160
161
161
return nbytes, cbytes, blocksize
162
162
163
163
164
164
def cbuffer_complib (source ):
165
165
""" Return the name of the compression library used to compress `source`."""
166
166
cdef:
167
- Buffer buffer
167
+ memoryview source_mv
168
+ const Py_buffer* source_pb
168
169
169
- # obtain buffer
170
- buffer = Buffer(source, PyBUF_ANY_CONTIGUOUS)
170
+ # obtain source memoryview
171
+ source_mv = memoryview(source)
172
+ source_pb = PyMemoryView_GET_BUFFER(source_mv)
173
+ if not PyBuffer_IsContiguous(source_pb, b' A' ):
174
+ raise BufferError(" `source` must contain contiguous memory" )
171
175
172
176
# determine buffer size
173
- complib = blosc_cbuffer_complib(buffer .ptr)
174
-
175
- # release buffers
176
- buffer .release()
177
+ complib = blosc_cbuffer_complib(source_pb.buf)
177
178
178
179
complib = complib.decode(' ascii' )
179
180
@@ -193,18 +194,19 @@ def cbuffer_metainfo(source):
193
194
194
195
"""
195
196
cdef:
196
- Buffer buffer
197
+ memoryview source_mv
198
+ const Py_buffer* source_pb
197
199
size_t typesize
198
200
int flags
199
201
200
- # obtain buffer
201
- buffer = Buffer(source, PyBUF_ANY_CONTIGUOUS)
202
+ # obtain source memoryview
203
+ source_mv = memoryview(source)
204
+ source_pb = PyMemoryView_GET_BUFFER(source_mv)
205
+ if not PyBuffer_IsContiguous(source_pb, b' A' ):
206
+ raise BufferError(" `source` must contain contiguous memory" )
202
207
203
208
# determine buffer size
204
- blosc_cbuffer_metainfo(buffer .ptr, & typesize, & flags)
205
-
206
- # release buffers
207
- buffer .release()
209
+ blosc_cbuffer_metainfo(source_pb.buf, & typesize, & flags)
208
210
209
211
# decompose flags
210
212
if flags & BLOSC_DOSHUFFLE:
@@ -252,9 +254,10 @@ def compress(source, char* cname, int clevel, int shuffle=SHUFFLE,
252
254
"""
253
255
254
256
cdef:
255
- char * source_ptr
256
- char * dest_ptr
257
- Buffer source_buffer
257
+ memoryview source_mv
258
+ const Py_buffer* source_pb
259
+ const char * source_ptr
260
+ char * dest_ptr
258
261
size_t nbytes, itemsize
259
262
int cbytes
260
263
bytes dest
@@ -264,11 +267,16 @@ def compress(source, char* cname, int clevel, int shuffle=SHUFFLE,
264
267
if cname_str not in list_compressors():
265
268
err_bad_cname(cname_str)
266
269
267
- # setup source buffer
268
- source_buffer = Buffer(source, PyBUF_ANY_CONTIGUOUS)
269
- source_ptr = source_buffer.ptr
270
- nbytes = source_buffer.nbytes
271
- itemsize = source_buffer.itemsize
270
+ # obtain source memoryview
271
+ source_mv = memoryview(source)
272
+ source_pb = PyMemoryView_GET_BUFFER(source_mv)
273
+ if not PyBuffer_IsContiguous(source_pb, b' A' ):
274
+ raise BufferError(" `source` must contain contiguous memory" )
275
+
276
+ # extract metadata
277
+ source_ptr = < const char * > source_pb.buf
278
+ nbytes = source_pb.len
279
+ itemsize = source_pb.itemsize
272
280
273
281
# determine shuffle
274
282
if shuffle == AUTOSHUFFLE:
@@ -280,46 +288,40 @@ def compress(source, char* cname, int clevel, int shuffle=SHUFFLE,
280
288
raise ValueError (' invalid shuffle argument; expected -1, 0, 1 or 2, found %r ' %
281
289
shuffle)
282
290
283
- try :
284
-
285
- # setup destination
286
- dest = PyBytes_FromStringAndSize(NULL , nbytes + BLOSC_MAX_OVERHEAD)
287
- dest_ptr = PyBytes_AS_STRING(dest)
288
-
289
- # perform compression
290
- if _get_use_threads():
291
- # allow blosc to use threads internally
291
+ # setup destination
292
+ dest = PyBytes_FromStringAndSize(NULL , nbytes + BLOSC_MAX_OVERHEAD)
293
+ dest_ptr = PyBytes_AS_STRING(dest)
292
294
293
- # N.B., we are using blosc's global context, and so we need to use a lock
294
- # to ensure no-one else can modify the global context while we're setting it
295
- # up and using it.
296
- with get_mutex():
295
+ # perform compression
296
+ if _get_use_threads():
297
+ # allow blosc to use threads internally
297
298
298
- # set compressor
299
- compressor_set = blosc_set_compressor(cname)
300
- if compressor_set < 0 :
301
- # shouldn't happen if we checked against list of compressors
302
- # already, but just in case
303
- err_bad_cname(cname_str)
299
+ # N.B., we are using blosc's global context, and so we need to use a lock
300
+ # to ensure no-one else can modify the global context while we're setting it
301
+ # up and using it.
302
+ with get_mutex():
304
303
305
- # set blocksize
306
- blosc_set_blocksize(blocksize)
304
+ # set compressor
305
+ compressor_set = blosc_set_compressor(cname)
306
+ if compressor_set < 0 :
307
+ # shouldn't happen if we checked against list of compressors
308
+ # already, but just in case
309
+ err_bad_cname(cname_str)
307
310
308
- # perform compression
309
- with nogil:
310
- cbytes = blosc_compress(clevel, shuffle, itemsize, nbytes, source_ptr,
311
- dest_ptr, nbytes + BLOSC_MAX_OVERHEAD)
311
+ # set blocksize
312
+ blosc_set_blocksize(blocksize)
312
313
313
- else :
314
+ # perform compression
314
315
with nogil:
315
- cbytes = blosc_compress_ctx(clevel, shuffle, itemsize, nbytes, source_ptr,
316
- dest_ptr, nbytes + BLOSC_MAX_OVERHEAD,
317
- cname, blocksize, 1 )
316
+ cbytes = blosc_compress(clevel, shuffle, itemsize, nbytes, source_ptr,
317
+ dest_ptr, nbytes + BLOSC_MAX_OVERHEAD)
318
318
319
- finally :
319
+ else :
320
+ with nogil:
321
+ cbytes = blosc_compress_ctx(clevel, shuffle, itemsize, nbytes, source_ptr,
322
+ dest_ptr, nbytes + BLOSC_MAX_OVERHEAD,
323
+ cname, blocksize, 1 )
320
324
321
- # release buffers
322
- source_buffer.release()
323
325
324
326
# check compression was successful
325
327
if cbytes <= 0 :
@@ -350,15 +352,22 @@ def decompress(source, dest=None):
350
352
"""
351
353
cdef:
352
354
int ret
353
- char * source_ptr
354
- char * dest_ptr
355
- Buffer source_buffer
356
- Buffer dest_buffer = None
355
+ memoryview source_mv
356
+ const Py_buffer* source_pb
357
+ const char * source_ptr
358
+ memoryview dest_mv
359
+ Py_buffer* dest_pb
360
+ char * dest_ptr
357
361
size_t nbytes, cbytes, blocksize
358
362
359
- # setup source buffer
360
- source_buffer = Buffer(source, PyBUF_ANY_CONTIGUOUS)
361
- source_ptr = source_buffer.ptr
363
+ # obtain source memoryview
364
+ source_mv = memoryview(source)
365
+ source_pb = PyMemoryView_GET_BUFFER(source_mv)
366
+ if not PyBuffer_IsContiguous(source_pb, b' A' ):
367
+ raise BufferError(" `source` must contain contiguous memory" )
368
+
369
+ # get source pointer
370
+ source_ptr = < const char * > source_pb.buf
362
371
363
372
# determine buffer size
364
373
blosc_cbuffer_sizes(source_ptr, & nbytes, & cbytes, & blocksize)
@@ -367,36 +376,28 @@ def decompress(source, dest=None):
367
376
if dest is None :
368
377
# allocate memory
369
378
dest = PyBytes_FromStringAndSize(NULL , nbytes)
370
- dest_ptr = PyBytes_AS_STRING(dest)
371
- dest_nbytes = nbytes
372
379
else :
373
- arr = ensure_contiguous_ndarray(dest)
374
- dest_buffer = Buffer(arr, PyBUF_ANY_CONTIGUOUS | PyBUF_WRITEABLE)
375
- dest_ptr = dest_buffer.ptr
376
- dest_nbytes = dest_buffer.nbytes
377
-
378
- try :
379
-
380
- # guard condition
381
- if dest_nbytes < nbytes:
382
- raise ValueError (' destination buffer too small; expected at least %s , '
383
- ' got %s ' % (nbytes, dest_nbytes))
384
-
385
- # perform decompression
386
- if _get_use_threads():
387
- # allow blosc to use threads internally
388
- with nogil:
389
- ret = blosc_decompress(source_ptr, dest_ptr, nbytes)
390
- else :
391
- with nogil:
392
- ret = blosc_decompress_ctx(source_ptr, dest_ptr, nbytes, 1 )
393
-
394
- finally :
395
-
396
- # release buffers
397
- source_buffer.release()
398
- if dest_buffer is not None :
399
- dest_buffer.release()
380
+ dest = ensure_contiguous_ndarray(dest)
381
+
382
+ # obtain dest memoryview
383
+ dest_mv = memoryview(dest)
384
+ dest_pb = PyMemoryView_GET_BUFFER(dest_mv)
385
+ dest_ptr = < char * > dest_pb.buf
386
+ dest_nbytes = dest_pb.len
387
+
388
+ # guard condition
389
+ if dest_nbytes < nbytes:
390
+ raise ValueError (' destination buffer too small; expected at least %s , '
391
+ ' got %s ' % (nbytes, dest_nbytes))
392
+
393
+ # perform decompression
394
+ if _get_use_threads():
395
+ # allow blosc to use threads internally
396
+ with nogil:
397
+ ret = blosc_decompress(source_ptr, dest_ptr, nbytes)
398
+ else :
399
+ with nogil:
400
+ ret = blosc_decompress_ctx(source_ptr, dest_ptr, nbytes, 1 )
400
401
401
402
# handle errors
402
403
if ret <= 0 :
@@ -433,14 +434,22 @@ def decompress_partial(source, start, nitems, dest=None):
433
434
int encoding_size
434
435
int nitems_bytes
435
436
int start_bytes
436
- char * source_ptr
437
- char * dest_ptr
438
- Buffer source_buffer
439
- Buffer dest_buffer = None
440
-
441
- # setup source buffer
442
- source_buffer = Buffer(source, PyBUF_ANY_CONTIGUOUS)
443
- source_ptr = source_buffer.ptr
437
+ const char * source_ptr
438
+ memoryview source_mv
439
+ const Py_buffer* source_pb
440
+ memoryview dest_mv
441
+ Py_buffer* dest_pb
442
+ char * dest_ptr
443
+ size_t dest_nbytes
444
+
445
+ # obtain source memoryview
446
+ source_mv = memoryview(source)
447
+ source_pb = PyMemoryView_GET_BUFFER(source_mv)
448
+ if not PyBuffer_IsContiguous(source_pb, b" A" ):
449
+ raise BufferError(" `source` must contain contiguous memory" )
450
+
451
+ # setup source pointer
452
+ source_ptr = < const char * > source_pb.buf
444
453
445
454
# get encoding size from source buffer header
446
455
encoding_size = source[3 ]
@@ -451,26 +460,22 @@ def decompress_partial(source, start, nitems, dest=None):
451
460
452
461
# setup destination buffer
453
462
if dest is None :
463
+ # allocate memory
454
464
dest = PyBytes_FromStringAndSize(NULL , nitems_bytes)
455
- dest_ptr = PyBytes_AS_STRING(dest)
456
- dest_nbytes = nitems_bytes
457
465
else :
458
- arr = ensure_contiguous_ndarray(dest)
459
- dest_buffer = Buffer(arr, PyBUF_ANY_CONTIGUOUS | PyBUF_WRITEABLE)
460
- dest_ptr = dest_buffer.ptr
461
- dest_nbytes = dest_buffer.nbytes
466
+ dest = ensure_contiguous_ndarray(dest)
467
+
468
+ # obtain dest memoryview
469
+ dest_mv = memoryview(dest)
470
+ dest_pb = PyMemoryView_GET_BUFFER(dest_mv)
471
+ dest_ptr = < char * > dest_pb.buf
472
+ dest_nbytes = dest_pb.len
462
473
463
474
# try decompression
464
- try :
465
- if dest_nbytes < nitems_bytes:
466
- raise ValueError (' destination buffer too small; expected at least %s , '
467
- ' got %s ' % (nitems_bytes, dest_nbytes))
468
- ret = blosc_getitem(source_ptr, start, nitems, dest_ptr)
469
-
470
- finally :
471
- source_buffer.release()
472
- if dest_buffer is not None :
473
- dest_buffer.release()
475
+ if dest_nbytes < nitems_bytes:
476
+ raise ValueError (' destination buffer too small; expected at least %s , '
477
+ ' got %s ' % (nitems_bytes, dest_nbytes))
478
+ ret = blosc_getitem(source_ptr, start, nitems, dest_ptr)
474
479
475
480
# ret refers to the number of bytes returned from blosc_getitem.
476
481
if ret <= 0 :
0 commit comments