##// END OF EJS Templates
sidedatacopies: only fetch information once for merge...
sidedatacopies: only fetch information once for merge Before this change, merge would result in reading the data from revlog twice. With this change, we keep the information in memory until we encounter the other parent. When looking at pypy, I see about 1/3 of the changesets with copy information being merge. Not doing duplicated fetch for them provide a significant speedup. revision: large amount; added files: large amount; rename small amount; c3b14617fbd7 9ba6ab77fd29 before: ! wall 0.767042 comb 0.760000 user 0.750000 sys 0.010000 (median of 11) after: ! wall 0.671162 comb 0.670000 user 0.650000 sys 0.020000 (median of 13) revision: large amount; added files: small amount; rename small amount; c3b14617fbd7 f650a9b140d2 before: ! wall 1.170169 comb 1.170000 user 1.130000 sys 0.040000 (median of 10) after: ! wall 1.030596 comb 1.040000 user 1.010000 sys 0.030000 (median of 10) revision: large amount; added files: large amount; rename large amount; 08ea3258278e d9fa043f30c0 before: ! wall 0.209846 comb 0.200000 user 0.200000 sys 0.000000 (median of 46) after: ! wall 0.170981 comb 0.170000 user 0.170000 sys 0.000000 (median of 56) revision: small amount; added files: large amount; rename large amount; df6f7a526b60 a83dc6a2d56f before: ! wall 0.013248 comb 0.010000 user 0.010000 sys 0.000000 (median of 223) after: ! wall 0.013295 comb 0.020000 user 0.020000 sys 0.000000 (median of 222) revision: small amount; added files: large amount; rename small amount; 4aa4e1f8e19a 169138063d63 before: ! wall 0.001672 comb 0.000000 user 0.000000 sys 0.000000 (median of 1000) after: ! wall 0.001666 comb 0.000000 user 0.000000 sys 0.000000 (median of 1000) revision: small amount; added files: small amount; rename small amount; 4bc173b045a6 964879152e2e before: ! wall 0.000119 comb 0.000000 user 0.000000 sys 0.000000 (median of 8010) after: ! wall 0.000119 comb 0.000000 user 0.000000 sys 0.000000 (median of 8007) revision: medium amount; added files: large amount; rename medium amount; c95f1ced15f2 2c68e87c3efe before: ! wall 0.168599 comb 0.160000 user 0.160000 sys 0.000000 (median of 58) after: ! wall 0.133316 comb 0.140000 user 0.140000 sys 0.000000 (median of 73) revision: medium amount; added files: medium amount; rename small amount; d343da0c55a8 d7746d32bf9d before: ! wall 0.036052 comb 0.030000 user 0.030000 sys 0.000000 (median of 100) after: ! wall 0.032558 comb 0.030000 user 0.030000 sys 0.000000 (median of 100) Differential Revision: https://phab.mercurial-scm.org/D7127

File last commit:

r42237:675775c3 default
r43595:90213d02 default
Show More
compressobj.c
256 lines | 6.6 KiB | text/x-c | CLexer
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 /**
* Copyright (c) 2016-present, Gregory Szorc
* All rights reserved.
*
* This software may be modified and distributed under the terms
* of the BSD license. See the LICENSE file for details.
*/
#include "python-zstandard.h"
extern PyObject* ZstdError;
PyDoc_STRVAR(ZstdCompressionObj__doc__,
"Perform compression using a standard library compatible API.\n"
);
static void ZstdCompressionObj_dealloc(ZstdCompressionObj* self) {
PyMem_Free(self->output.dst);
self->output.dst = NULL;
Py_XDECREF(self->compressor);
PyObject_Del(self);
}
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 static PyObject* ZstdCompressionObj_compress(ZstdCompressionObj* self, PyObject* args, PyObject* kwargs) {
static char* kwlist[] = {
"data",
NULL
};
Py_buffer source;
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 ZSTD_inBuffer input;
size_t zresult;
PyObject* result = NULL;
Py_ssize_t resultSize = 0;
Gregory Szorc
zstd: vendor python-zstandard 0.6.0...
r30822 if (self->finished) {
PyErr_SetString(ZstdError, "cannot call compress() after compressor finished");
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 return NULL;
}
#if PY_MAJOR_VERSION >= 3
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*:compress",
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 #else
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s*:compress",
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 #endif
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 kwlist, &source)) {
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 return NULL;
}
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 if (!PyBuffer_IsContiguous(&source, 'C') || source.ndim > 1) {
PyErr_SetString(PyExc_ValueError,
"data buffer should be contiguous and have at most one dimension");
goto finally;
}
input.src = source.buf;
input.size = source.len;
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 input.pos = 0;
Gregory Szorc
zstandard: vendor python-zstandard 0.11...
r42237 while (input.pos < (size_t)source.len) {
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 Py_BEGIN_ALLOW_THREADS
Gregory Szorc
zstandard: vendor python-zstandard 0.11...
r42237 zresult = ZSTD_compressStream2(self->compressor->cctx, &self->output,
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 &input, ZSTD_e_continue);
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 Py_END_ALLOW_THREADS
if (ZSTD_isError(zresult)) {
PyErr_Format(ZstdError, "zstd compress error: %s", ZSTD_getErrorName(zresult));
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 Py_CLEAR(result);
goto finally;
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 }
if (self->output.pos) {
if (result) {
resultSize = PyBytes_GET_SIZE(result);
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513
if (safe_pybytes_resize(&result, resultSize + self->output.pos)) {
Py_CLEAR(result);
goto finally;
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 }
memcpy(PyBytes_AS_STRING(result) + resultSize,
self->output.dst, self->output.pos);
}
else {
result = PyBytes_FromStringAndSize(self->output.dst, self->output.pos);
if (!result) {
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 goto finally;
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 }
}
self->output.pos = 0;
}
}
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 if (NULL == result) {
result = PyBytes_FromString("");
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 }
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513
finally:
PyBuffer_Release(&source);
return result;
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 }
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 static PyObject* ZstdCompressionObj_flush(ZstdCompressionObj* self, PyObject* args, PyObject* kwargs) {
static char* kwlist[] = {
"flush_mode",
NULL
};
Gregory Szorc
zstd: vendor python-zstandard 0.6.0...
r30822 int flushMode = compressorobj_flush_finish;
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 size_t zresult;
PyObject* result = NULL;
Py_ssize_t resultSize = 0;
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 ZSTD_inBuffer input;
Gregory Szorc
zstandard: vendor python-zstandard 0.10.1...
r40157 ZSTD_EndDirective zFlushMode;
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:flush", kwlist, &flushMode)) {
Gregory Szorc
zstd: vendor python-zstandard 0.6.0...
r30822 return NULL;
}
if (flushMode != compressorobj_flush_finish && flushMode != compressorobj_flush_block) {
PyErr_SetString(PyExc_ValueError, "flush mode not recognized");
return NULL;
}
if (self->finished) {
PyErr_SetString(ZstdError, "compressor object already finished");
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 return NULL;
}
Gregory Szorc
zstandard: vendor python-zstandard 0.10.1...
r40157 switch (flushMode) {
case compressorobj_flush_block:
zFlushMode = ZSTD_e_flush;
break;
case compressorobj_flush_finish:
zFlushMode = ZSTD_e_end;
self->finished = 1;
break;
default:
PyErr_SetString(ZstdError, "unhandled flush mode");
return NULL;
}
Gregory Szorc
zstd: vendor python-zstandard 0.6.0...
r30822 assert(self->output.pos == 0);
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 input.src = NULL;
input.size = 0;
input.pos = 0;
Gregory Szorc
zstandard: vendor python-zstandard 0.10.1...
r40157 while (1) {
Gregory Szorc
zstd: vendor python-zstandard 0.6.0...
r30822 Py_BEGIN_ALLOW_THREADS
Gregory Szorc
zstandard: vendor python-zstandard 0.11...
r42237 zresult = ZSTD_compressStream2(self->compressor->cctx, &self->output,
Gregory Szorc
zstandard: vendor python-zstandard 0.10.1...
r40157 &input, zFlushMode);
Gregory Szorc
zstd: vendor python-zstandard 0.6.0...
r30822 Py_END_ALLOW_THREADS
if (ZSTD_isError(zresult)) {
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 PyErr_Format(ZstdError, "error ending compression stream: %s",
ZSTD_getErrorName(zresult));
return NULL;
}
if (self->output.pos) {
if (result) {
resultSize = PyBytes_GET_SIZE(result);
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513
if (safe_pybytes_resize(&result, resultSize + self->output.pos)) {
Py_XDECREF(result);
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 return NULL;
}
memcpy(PyBytes_AS_STRING(result) + resultSize,
self->output.dst, self->output.pos);
}
else {
result = PyBytes_FromStringAndSize(self->output.dst, self->output.pos);
if (!result) {
return NULL;
}
}
self->output.pos = 0;
}
if (!zresult) {
break;
}
}
if (result) {
return result;
}
else {
return PyBytes_FromString("");
}
}
static PyMethodDef ZstdCompressionObj_methods[] = {
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 { "compress", (PyCFunction)ZstdCompressionObj_compress, METH_VARARGS | METH_KEYWORDS,
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 PyDoc_STR("compress data") },
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 { "flush", (PyCFunction)ZstdCompressionObj_flush, METH_VARARGS | METH_KEYWORDS,
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 PyDoc_STR("finish compression operation") },
{ NULL, NULL }
};
PyTypeObject ZstdCompressionObjType = {
PyVarObject_HEAD_INIT(NULL, 0)
"zstd.ZstdCompressionObj", /* tp_name */
sizeof(ZstdCompressionObj), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)ZstdCompressionObj_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
ZstdCompressionObj__doc__, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
ZstdCompressionObj_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
PyType_GenericNew, /* tp_new */
};
void compressobj_module_init(PyObject* module) {
Py_TYPE(&ZstdCompressionObjType) = &PyType_Type;
if (PyType_Ready(&ZstdCompressionObjType) < 0) {
return;
}
}