2016-04-08 21:48:31 +03:00
|
|
|
// Copyright 2016-present Facebook. All Rights Reserved.
|
|
|
|
//
|
2016-05-26 21:34:56 +03:00
|
|
|
// cfastmanifest.c: CPython interface for fastmanifest
|
2016-04-08 21:48:31 +03:00
|
|
|
//
|
|
|
|
// no-check-code
|
|
|
|
|
|
|
|
#include <Python.h>
|
|
|
|
|
|
|
|
#if defined(_MSC_VER) || __STDC_VERSION__ < 199901L
|
|
|
|
#define true 1
|
|
|
|
#define false 0
|
|
|
|
typedef unsigned char bool;
|
|
|
|
#else
|
|
|
|
#include <stdbool.h>
|
|
|
|
#endif
|
|
|
|
|
2016-04-19 01:40:42 +03:00
|
|
|
#include "tree.h"
|
|
|
|
|
2016-04-08 21:48:31 +03:00
|
|
|
typedef struct {
|
|
|
|
PyObject_HEAD;
|
2016-04-19 01:40:42 +03:00
|
|
|
tree_t *tree;
|
2016-04-08 21:48:31 +03:00
|
|
|
} fastmanifest;
|
|
|
|
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
typedef struct {
|
|
|
|
PyObject_HEAD;
|
|
|
|
iterator_t *iterator;
|
|
|
|
} fmIter;
|
|
|
|
|
2016-04-08 21:48:31 +03:00
|
|
|
|
|
|
|
static PyTypeObject fastmanifestType;
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
static PyTypeObject fastmanifestKeysIterator;
|
|
|
|
static PyTypeObject fastmanifestEntriesIterator;
|
2016-04-08 21:48:31 +03:00
|
|
|
|
|
|
|
/* Fastmanifest: CPython helpers */
|
|
|
|
|
|
|
|
static bool fastmanifest_is_valid_manifest_key(PyObject *key) {
|
2016-05-17 21:47:28 +03:00
|
|
|
return PyString_Check(key);
|
2016-04-08 21:48:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static bool fastmanifest_is_valid_manifest_value(PyObject *value) {
|
|
|
|
if (!PyTuple_Check(value) || PyTuple_Size(value) != 2) {
|
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"Manifest values must be a tuple of (node, flags).");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-04-19 01:40:42 +03:00
|
|
|
static PyObject *fastmanifest_formatfile(
|
|
|
|
const uint8_t *checksum, const uint8_t checksum_sz, const uint8_t flags) {
|
2016-04-27 01:45:45 +03:00
|
|
|
PyObject *py_checksum = PyString_FromStringAndSize(
|
|
|
|
(const char *) checksum, checksum_sz);
|
2016-04-19 01:40:42 +03:00
|
|
|
|
|
|
|
if (!py_checksum) {
|
2016-04-08 21:48:31 +03:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2016-04-19 01:40:42 +03:00
|
|
|
PyObject *py_flags;
|
2016-04-08 21:48:31 +03:00
|
|
|
PyObject *tup;
|
|
|
|
|
2016-04-27 01:45:45 +03:00
|
|
|
py_flags = PyString_FromStringAndSize(
|
|
|
|
(const char *) &flags, (flags == 0) ? 0 : 1);
|
2016-04-19 01:40:42 +03:00
|
|
|
if (!py_flags) {
|
|
|
|
Py_DECREF(py_checksum);
|
2016-04-08 21:48:31 +03:00
|
|
|
return NULL;
|
|
|
|
}
|
2016-04-19 01:40:42 +03:00
|
|
|
tup = PyTuple_Pack(2, py_checksum, py_flags);
|
|
|
|
Py_DECREF(py_flags);
|
|
|
|
Py_DECREF(py_checksum);
|
2016-04-08 21:48:31 +03:00
|
|
|
return tup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ================================== */
|
|
|
|
/* Fastmanifest: CPython Interface */
|
|
|
|
/* ================================== */
|
|
|
|
|
|
|
|
static int fastmanifest_init(fastmanifest *self, PyObject *args) {
|
|
|
|
PyObject *pydata = NULL;
|
|
|
|
char *data;
|
|
|
|
ssize_t len;
|
2016-05-16 22:41:26 +03:00
|
|
|
|
|
|
|
if (!PyArg_ParseTuple(args, "|S", &pydata)) {
|
2016-04-08 21:48:31 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2016-05-16 22:41:26 +03:00
|
|
|
|
|
|
|
if (pydata == NULL) {
|
|
|
|
// no string. initialize it to an empty tree.
|
|
|
|
self->tree = alloc_tree();
|
|
|
|
if (self->tree == NULL) {
|
|
|
|
PyErr_NoMemory();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2016-04-08 21:48:31 +03:00
|
|
|
int err = PyString_AsStringAndSize(pydata, &data, &len);
|
|
|
|
if (err == -1)
|
|
|
|
return -1;
|
2016-08-09 09:28:18 +03:00
|
|
|
|
|
|
|
convert_from_flat_result_t from_result = convert_from_flat(
|
|
|
|
data, len);
|
|
|
|
|
|
|
|
if (from_result.code == CONVERT_FROM_FLAT_OK) {
|
|
|
|
tree_t *tree = from_result.tree;
|
|
|
|
self->tree = tree;
|
|
|
|
} else {
|
|
|
|
self->tree = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (from_result.code) {
|
|
|
|
case CONVERT_FROM_FLAT_OOM:
|
|
|
|
PyErr_NoMemory();
|
|
|
|
return -1;
|
|
|
|
case CONVERT_FROM_FLAT_WTF:
|
|
|
|
PyErr_Format(PyExc_ValueError,
|
|
|
|
"Manifest did not end in a newline.");
|
|
|
|
return -1;
|
|
|
|
default:
|
|
|
|
return 0;
|
2016-04-08 21:48:31 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void fastmanifest_dealloc(fastmanifest *self) {
|
2016-08-09 09:28:18 +03:00
|
|
|
destroy_tree(self->tree);
|
2016-08-09 23:47:49 +03:00
|
|
|
PyObject_Del(self);
|
2016-04-08 21:48:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *fastmanifest_getkeysiter(fastmanifest *self) {
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
fmIter *i = NULL;
|
|
|
|
iterator_t *iterator = create_iterator(self->tree, true);
|
|
|
|
if (!iterator) {
|
|
|
|
PyErr_NoMemory();
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
i = PyObject_New(fmIter, &fastmanifestKeysIterator);
|
|
|
|
if (i) {
|
|
|
|
i->iterator = iterator;
|
|
|
|
} else {
|
|
|
|
destroy_iterator(iterator);
|
|
|
|
PyErr_NoMemory();
|
|
|
|
}
|
|
|
|
return (PyObject *)i;
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *fastmanifest_getentriesiter(fastmanifest *self) {
|
|
|
|
fmIter *i = NULL;
|
|
|
|
iterator_t *iterator = create_iterator(self->tree, true);
|
|
|
|
if (!iterator) {
|
|
|
|
PyErr_NoMemory();
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
i = PyObject_New(fmIter, &fastmanifestEntriesIterator);
|
|
|
|
if (i) {
|
|
|
|
i->iterator = iterator;
|
|
|
|
} else {
|
|
|
|
destroy_iterator(iterator);
|
|
|
|
PyErr_NoMemory();
|
|
|
|
}
|
|
|
|
return (PyObject *)i;
|
2016-04-08 21:48:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject * fastmanifest_save(fastmanifest *self, PyObject *args){
|
|
|
|
PyObject *pydata = NULL;
|
|
|
|
char *data;
|
|
|
|
ssize_t len;
|
|
|
|
if (!PyArg_ParseTuple(args, "S", &pydata)) {
|
2016-04-27 01:45:45 +03:00
|
|
|
return NULL;
|
2016-04-08 21:48:31 +03:00
|
|
|
}
|
|
|
|
int err = PyString_AsStringAndSize(pydata, &data, &len);
|
2016-05-09 21:35:53 +03:00
|
|
|
if (err == -1 || len < 0) {
|
|
|
|
PyErr_Format(PyExc_ValueError, "Illegal filepath");
|
2016-04-27 01:45:45 +03:00
|
|
|
return NULL;
|
2016-05-09 21:35:53 +03:00
|
|
|
}
|
|
|
|
write_to_file_result_t result =
|
2016-08-09 09:28:18 +03:00
|
|
|
write_to_file(self->tree, data, (size_t) len);
|
2016-05-09 21:35:53 +03:00
|
|
|
|
|
|
|
switch (result) {
|
|
|
|
case WRITE_TO_FILE_OK:
|
2016-07-08 02:49:44 +03:00
|
|
|
Py_RETURN_NONE;
|
2016-05-09 21:35:53 +03:00
|
|
|
|
|
|
|
case WRITE_TO_FILE_OOM:
|
|
|
|
PyErr_NoMemory();
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
default:
|
|
|
|
PyErr_Format(PyExc_ValueError, "Unexpected error saving manifest");
|
|
|
|
return NULL;
|
|
|
|
}
|
2016-04-08 21:48:31 +03:00
|
|
|
}
|
|
|
|
|
2016-05-09 21:35:53 +03:00
|
|
|
static PyObject *fastmanifest_load(PyObject *cls, PyObject *args) {
|
2016-04-08 21:48:31 +03:00
|
|
|
PyObject *pydata = NULL;
|
|
|
|
char *data;
|
|
|
|
ssize_t len;
|
|
|
|
if (!PyArg_ParseTuple(args, "S", &pydata)) {
|
2016-04-27 01:45:45 +03:00
|
|
|
return NULL;
|
2016-04-08 21:48:31 +03:00
|
|
|
}
|
|
|
|
int err = PyString_AsStringAndSize(pydata, &data, &len);
|
2016-05-09 21:35:53 +03:00
|
|
|
if (err == -1 || len < 0) {
|
|
|
|
PyErr_Format(PyExc_ValueError, "Illegal filepath");
|
2016-04-27 01:45:45 +03:00
|
|
|
return NULL;
|
2016-05-09 21:35:53 +03:00
|
|
|
}
|
2016-08-09 09:28:18 +03:00
|
|
|
read_from_file_result_t result = read_from_file(data, (size_t) len);
|
2016-05-09 21:35:53 +03:00
|
|
|
|
|
|
|
switch (result.code) {
|
|
|
|
case READ_FROM_FILE_OK: {
|
|
|
|
fastmanifest *read_manifest = PyObject_New(
|
|
|
|
fastmanifest, &fastmanifestType);
|
|
|
|
read_manifest->tree = result.tree;
|
|
|
|
return (PyObject *) read_manifest;
|
|
|
|
}
|
|
|
|
|
|
|
|
case READ_FROM_FILE_OOM:
|
|
|
|
PyErr_NoMemory();
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
case READ_FROM_FILE_NOT_READABLE:
|
|
|
|
errno = result.err;
|
|
|
|
PyErr_SetFromErrno(PyExc_IOError);
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
default:
|
|
|
|
PyErr_Format(PyExc_ValueError, "Unexpected error loading manifest");
|
|
|
|
return NULL;
|
|
|
|
}
|
2016-04-08 21:48:31 +03:00
|
|
|
}
|
|
|
|
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
static fastmanifest *fastmanifest_copy(fastmanifest *self) {
|
2016-04-08 21:48:31 +03:00
|
|
|
fastmanifest *copy = PyObject_New(fastmanifest, &fastmanifestType);
|
2016-08-09 09:28:18 +03:00
|
|
|
if (copy) {
|
|
|
|
copy->tree = copy_tree(self->tree);
|
|
|
|
}
|
2016-04-08 21:48:31 +03:00
|
|
|
|
|
|
|
if (!copy)
|
|
|
|
PyErr_NoMemory();
|
|
|
|
return copy;
|
|
|
|
}
|
|
|
|
|
2016-05-20 01:24:10 +03:00
|
|
|
typedef struct {
|
|
|
|
PyObject *matchfn;
|
|
|
|
bool filter_error_occurred;
|
|
|
|
} filter_copy_context_t;
|
|
|
|
|
|
|
|
bool filter_callback(char *path, size_t path_sz, void *callback_context) {
|
|
|
|
filter_copy_context_t *context = (filter_copy_context_t *) callback_context;
|
|
|
|
|
|
|
|
PyObject *arglist = NULL, *result = NULL;
|
|
|
|
arglist = Py_BuildValue("(s#)", path, (int) path_sz);
|
|
|
|
if (!arglist) {
|
|
|
|
context->filter_error_occurred = true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = PyObject_CallObject(context->matchfn, arglist);
|
|
|
|
Py_DECREF(arglist);
|
|
|
|
if (!result) {
|
|
|
|
context->filter_error_occurred = true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool bool_result = PyObject_IsTrue(result);
|
|
|
|
Py_DECREF(result);
|
|
|
|
return bool_result;
|
|
|
|
}
|
|
|
|
|
|
|
|
static fastmanifest *fastmanifest_filtercopy(
|
|
|
|
fastmanifest *self,
|
|
|
|
PyObject *matchfn) {
|
|
|
|
fastmanifest *py_copy = PyObject_New(fastmanifest, &fastmanifestType);
|
|
|
|
tree_t *copy = NULL;
|
|
|
|
if (py_copy) {
|
|
|
|
filter_copy_context_t context;
|
|
|
|
|
|
|
|
context.matchfn = matchfn;
|
|
|
|
context.filter_error_occurred = false;
|
|
|
|
|
|
|
|
copy = filter_copy(self->tree, filter_callback, &context);
|
|
|
|
|
|
|
|
if (copy == NULL) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
py_copy->tree = copy;
|
|
|
|
return py_copy;
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (copy != NULL) {
|
|
|
|
destroy_tree(copy);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (py_copy != NULL) {
|
|
|
|
Py_DECREF(py_copy);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PyErr_NoMemory();
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
static PyObject *hashflags(
|
|
|
|
const uint8_t *checksum,
|
|
|
|
const uint8_t checksum_sz,
|
|
|
|
const uint8_t flags) {
|
|
|
|
PyObject *ret = NULL, *py_hash, *py_flags;
|
|
|
|
py_hash = PyString_FromStringAndSize((const char *)checksum, checksum_sz);
|
|
|
|
py_flags = PyString_FromStringAndSize(
|
|
|
|
(const char *) &flags,
|
|
|
|
flags == 0 ? 0 : 1);
|
|
|
|
if (!py_hash || !py_flags) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
ret = PyTuple_Pack(2, py_hash, py_flags);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
Py_XDECREF(py_hash);
|
|
|
|
Py_XDECREF(py_flags);
|
|
|
|
return ret;
|
2016-04-08 21:48:31 +03:00
|
|
|
}
|
|
|
|
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
typedef struct _fastmanifest_diff_context_t {
|
|
|
|
PyObject *result;
|
|
|
|
PyObject *emptyTuple;
|
|
|
|
bool error_occurred;
|
2016-05-23 21:10:33 +03:00
|
|
|
bool listclean;
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
} fastmanifest_diff_context_t;
|
|
|
|
|
|
|
|
static void fastmanifest_diff_callback(
|
|
|
|
const char *path,
|
|
|
|
const size_t path_sz,
|
|
|
|
const bool left_present,
|
|
|
|
const uint8_t *left_checksum,
|
|
|
|
const uint8_t left_checksum_sz,
|
|
|
|
const uint8_t left_flags,
|
|
|
|
const bool right_present,
|
|
|
|
const uint8_t *right_checksum,
|
|
|
|
const uint8_t right_checksum_sz,
|
|
|
|
const uint8_t right_flags,
|
|
|
|
void *context) {
|
|
|
|
fastmanifest_diff_context_t *diff_context =
|
|
|
|
(fastmanifest_diff_context_t *) context;
|
2016-05-23 21:10:33 +03:00
|
|
|
PyObject *key, *outer = NULL, *py_left = NULL, *py_right = NULL;
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
|
2016-05-23 21:10:33 +03:00
|
|
|
key = PyString_FromStringAndSize(path, path_sz);
|
|
|
|
if (!key) {
|
|
|
|
diff_context->error_occurred = true;
|
|
|
|
goto cleanup;
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
}
|
|
|
|
|
2016-05-23 21:10:33 +03:00
|
|
|
if (left_present &&
|
|
|
|
right_present &&
|
|
|
|
left_flags == right_flags &&
|
|
|
|
left_checksum_sz == right_checksum_sz &&
|
|
|
|
memcmp(left_checksum, right_checksum, left_checksum_sz) == 0) {
|
2016-07-06 01:26:13 +03:00
|
|
|
Py_INCREF(Py_None);
|
2016-05-23 21:10:33 +03:00
|
|
|
outer = Py_None;
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
} else {
|
2016-05-23 21:10:33 +03:00
|
|
|
if (left_present) {
|
|
|
|
py_left = hashflags(left_checksum, left_checksum_sz, left_flags);
|
|
|
|
} else {
|
|
|
|
py_left = diff_context->emptyTuple;
|
|
|
|
}
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
|
2016-05-23 21:10:33 +03:00
|
|
|
if (right_present) {
|
|
|
|
py_right = hashflags(right_checksum, right_checksum_sz, right_flags);
|
|
|
|
} else {
|
|
|
|
py_right = diff_context->emptyTuple;
|
|
|
|
}
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
|
2016-05-23 21:10:33 +03:00
|
|
|
if (!py_left || !py_right) {
|
|
|
|
diff_context->error_occurred = true;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
|
2016-05-23 21:10:33 +03:00
|
|
|
outer = PyTuple_Pack(2, py_left, py_right);
|
|
|
|
if (outer == NULL) {
|
|
|
|
diff_context->error_occurred = true;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (PyDict_SetItem(diff_context->result, key, outer) != 0) {
|
|
|
|
diff_context->error_occurred = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
Py_XDECREF(outer);
|
|
|
|
Py_XDECREF(key);
|
2016-05-16 22:39:39 +03:00
|
|
|
if (left_present) {
|
|
|
|
Py_XDECREF(py_left);
|
|
|
|
}
|
|
|
|
if (right_present) {
|
|
|
|
Py_XDECREF(py_right);
|
|
|
|
}
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *fastmanifest_diff(fastmanifest *self, PyObject *args) {
|
|
|
|
fastmanifest *other;
|
|
|
|
PyObject *pyclean = NULL;
|
|
|
|
PyObject *emptyTuple = NULL, *ret = NULL;
|
|
|
|
PyObject *es;
|
|
|
|
fastmanifest_diff_context_t context;
|
2016-05-09 21:37:43 +03:00
|
|
|
context.error_occurred = false;
|
2016-04-08 21:48:31 +03:00
|
|
|
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
if (!PyArg_ParseTuple(args, "O!|O", &fastmanifestType, &other, &pyclean)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2016-05-23 21:10:33 +03:00
|
|
|
context.listclean = (!pyclean) ? false : PyObject_IsTrue(pyclean);
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
es = PyString_FromString("");
|
|
|
|
if (!es) {
|
|
|
|
goto nomem;
|
|
|
|
}
|
|
|
|
emptyTuple = PyTuple_Pack(2, Py_None, es);
|
2016-05-16 22:39:39 +03:00
|
|
|
Py_CLEAR(es);
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
if (!emptyTuple) {
|
|
|
|
goto nomem;
|
|
|
|
}
|
|
|
|
ret = PyDict_New();
|
|
|
|
if (!ret) {
|
|
|
|
goto nomem;
|
|
|
|
}
|
|
|
|
|
|
|
|
context.result = ret;
|
|
|
|
context.emptyTuple = emptyTuple;
|
|
|
|
|
2016-05-23 21:10:33 +03:00
|
|
|
diff_result_t diff_result = diff_trees(
|
|
|
|
self->tree, other->tree,
|
|
|
|
context.listclean,
|
|
|
|
&fastmanifest_diff_callback,
|
|
|
|
&context);
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
|
|
|
|
Py_CLEAR(emptyTuple);
|
|
|
|
|
|
|
|
switch (diff_result) {
|
|
|
|
case DIFF_OK:
|
|
|
|
if (context.error_occurred) {
|
|
|
|
// error occurred in the callback, i.e., our code.
|
|
|
|
Py_XDECREF(ret);
|
|
|
|
if (PyErr_Occurred() == NULL) {
|
|
|
|
PyErr_Format(PyExc_ValueError,
|
|
|
|
"ignore_fastmanifest_errcode set but no exception detected.");
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
case DIFF_OOM:
|
|
|
|
goto nomem;
|
|
|
|
|
|
|
|
case DIFF_WTF:
|
|
|
|
PyErr_Format(PyExc_ValueError,
|
|
|
|
"Unexpected error diffing manifests.");
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
nomem:
|
|
|
|
PyErr_NoMemory();
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
Py_XDECREF(ret);
|
|
|
|
Py_XDECREF(emptyTuple);
|
|
|
|
Py_XDECREF(es);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *fastmanifest_text(fastmanifest *self) {
|
|
|
|
convert_to_flat_result_t to_flat = convert_to_flat(self->tree);
|
|
|
|
switch (to_flat.code) {
|
|
|
|
case CONVERT_TO_FLAT_OK:
|
|
|
|
return PyString_FromStringAndSize(
|
|
|
|
to_flat.flat_manifest, to_flat.flat_manifest_sz);
|
|
|
|
|
|
|
|
case CONVERT_TO_FLAT_OOM:
|
|
|
|
PyErr_NoMemory();
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
case CONVERT_TO_FLAT_WTF:
|
|
|
|
PyErr_Format(PyExc_ValueError,
|
|
|
|
"Error converting manifest");
|
|
|
|
return NULL;
|
2016-04-28 21:38:07 +03:00
|
|
|
|
|
|
|
default:
|
|
|
|
PyErr_Format(PyExc_ValueError, "Unknown result code");
|
|
|
|
return NULL;
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Py_ssize_t fastmanifest_size(fastmanifest *self) {
|
2016-08-09 09:28:18 +03:00
|
|
|
return self->tree->num_leaf_nodes;
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
}
|
|
|
|
|
2016-07-12 00:09:02 +03:00
|
|
|
static PyObject *fastmanifest_bytes(fastmanifest *self) {
|
|
|
|
return PyInt_FromSize_t(self->tree->consumed_memory);
|
|
|
|
}
|
|
|
|
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
static PyObject *fastmanifest_getitem(fastmanifest *self, PyObject *key) {
|
2016-04-08 21:48:31 +03:00
|
|
|
if (!fastmanifest_is_valid_manifest_key(key)) {
|
2016-05-17 21:47:28 +03:00
|
|
|
PyErr_Format(PyExc_TypeError, "Manifest keys must be strings.");
|
2016-04-08 21:48:31 +03:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *ckey;
|
|
|
|
ssize_t clen;
|
|
|
|
int err = PyString_AsStringAndSize(key, &ckey, &clen);
|
|
|
|
if (err == -1) {
|
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"Error decoding path");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2016-08-09 09:28:18 +03:00
|
|
|
get_path_result_t query = get_path(self->tree, ckey, clen);
|
2016-04-19 01:40:42 +03:00
|
|
|
switch (query.code) {
|
|
|
|
case GET_PATH_NOT_FOUND:
|
|
|
|
PyErr_Format(PyExc_KeyError,
|
|
|
|
"File not found");
|
|
|
|
return NULL;
|
2016-04-08 21:48:31 +03:00
|
|
|
|
2016-04-19 01:40:42 +03:00
|
|
|
case GET_PATH_WTF:
|
2016-04-08 21:48:31 +03:00
|
|
|
PyErr_Format(PyExc_ValueError,
|
2016-04-19 01:40:42 +03:00
|
|
|
"tree corrupt");
|
|
|
|
return NULL;
|
2016-04-08 21:48:31 +03:00
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-04-19 01:40:42 +03:00
|
|
|
PyObject *ret = fastmanifest_formatfile(
|
|
|
|
query.checksum, query.checksum_sz, query.flags);
|
2016-04-08 21:48:31 +03:00
|
|
|
if (ret == NULL) {
|
|
|
|
PyErr_Format(PyExc_ValueError,
|
|
|
|
"Error formatting file");
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int fastmanifest_setitem(fastmanifest *self, PyObject *key,
|
|
|
|
PyObject *value)
|
|
|
|
{
|
|
|
|
char *path, *hash, *flags;
|
|
|
|
ssize_t plen, hlen, flen;
|
|
|
|
int err;
|
|
|
|
/* Decode path */
|
|
|
|
if (!fastmanifest_is_valid_manifest_key(key)) {
|
2016-05-17 21:47:28 +03:00
|
|
|
PyErr_Format(PyExc_TypeError, "Manifest keys must be strings.");
|
2016-04-08 21:48:31 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
err = PyString_AsStringAndSize(key, &path, &plen);
|
2016-04-27 01:45:45 +03:00
|
|
|
if (err == -1 || plen < 0) {
|
2016-04-08 21:48:31 +03:00
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"Error decoding path");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!value) {
|
2016-04-19 01:40:42 +03:00
|
|
|
remove_path_result_t remove_path_result =
|
2016-08-09 09:28:18 +03:00
|
|
|
remove_path(self->tree, path, (size_t) plen);
|
2016-04-08 21:48:31 +03:00
|
|
|
|
2016-04-19 01:40:42 +03:00
|
|
|
switch(remove_path_result) {
|
2016-04-08 21:48:31 +03:00
|
|
|
|
2016-04-19 01:40:42 +03:00
|
|
|
case REMOVE_PATH_OK:
|
2016-04-08 21:48:31 +03:00
|
|
|
return 0;
|
|
|
|
|
2016-04-19 01:40:42 +03:00
|
|
|
case REMOVE_PATH_NOT_FOUND:
|
2016-04-08 21:48:31 +03:00
|
|
|
PyErr_Format(PyExc_KeyError,
|
2016-04-19 01:40:42 +03:00
|
|
|
"Not found");
|
2016-04-08 21:48:31 +03:00
|
|
|
return -1;
|
|
|
|
|
2016-04-19 01:40:42 +03:00
|
|
|
case REMOVE_PATH_WTF:
|
2016-04-08 21:48:31 +03:00
|
|
|
PyErr_Format(PyExc_KeyError,
|
2016-04-19 01:40:42 +03:00
|
|
|
"tree corrupt");
|
2016-04-08 21:48:31 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Decode node and flags*/
|
|
|
|
if (!fastmanifest_is_valid_manifest_value(value)) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
PyObject *pyhash = PyTuple_GetItem(value, 0);
|
|
|
|
|
|
|
|
err = PyString_AsStringAndSize(pyhash, &hash, &hlen);
|
|
|
|
if (err == -1) {
|
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"Error decoding hash");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *pyflags = PyTuple_GetItem(value, 1);
|
|
|
|
|
|
|
|
err = PyString_AsStringAndSize(pyflags, &flags, &flen);
|
|
|
|
if (err == -1) {
|
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"Error decoding flags");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-08-09 09:28:18 +03:00
|
|
|
add_update_path_result_t add_update_path_result = add_or_update_path(
|
|
|
|
self->tree,
|
|
|
|
path, plen,
|
|
|
|
(unsigned char *) hash, hlen,
|
|
|
|
*flags);
|
2016-04-19 01:40:42 +03:00
|
|
|
switch (add_update_path_result) {
|
|
|
|
case ADD_UPDATE_PATH_OOM:
|
|
|
|
{
|
|
|
|
PyErr_NoMemory();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-04-27 01:45:45 +03:00
|
|
|
case ADD_UPDATE_PATH_OK:
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
default:
|
2016-04-19 01:40:42 +03:00
|
|
|
{
|
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"unexpected stuff happened");
|
|
|
|
return -1;
|
|
|
|
}
|
2016-04-08 21:48:31 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyMappingMethods fastmanifest_mapping_methods = {
|
|
|
|
(lenfunc)fastmanifest_size, /* mp_length */
|
|
|
|
(binaryfunc)fastmanifest_getitem, /* mp_subscript */
|
|
|
|
(objobjargproc)fastmanifest_setitem, /* mp_ass_subscript */
|
|
|
|
};
|
|
|
|
|
2016-04-19 01:40:42 +03:00
|
|
|
/* sequence methods (important or __contains__ builds an iterator) */
|
|
|
|
|
|
|
|
static int fastmanifest_contains(fastmanifest *self, PyObject *key)
|
|
|
|
{
|
|
|
|
if (!fastmanifest_is_valid_manifest_key(key)) {
|
|
|
|
/* Our keys are always strings, so if the contains
|
|
|
|
* check is for a non-string, just return false. */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
char *path;
|
|
|
|
ssize_t plen;
|
|
|
|
int err = PyString_AsStringAndSize(key, &path, &plen);
|
|
|
|
if (err == -1) {
|
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"Error decoding path");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return contains_path(self->tree, path, plen) ? 1 : 0;
|
|
|
|
}
|
|
|
|
|
2016-04-08 21:48:31 +03:00
|
|
|
static PySequenceMethods fastmanifest_seq_meths = {
|
|
|
|
(lenfunc)fastmanifest_size, /* sq_length */
|
|
|
|
0, /* sq_concat */
|
|
|
|
0, /* sq_repeat */
|
|
|
|
0, /* sq_item */
|
|
|
|
0, /* sq_slice */
|
|
|
|
0, /* sq_ass_item */
|
|
|
|
0, /* sq_ass_slice */
|
2016-04-19 01:40:42 +03:00
|
|
|
(objobjproc)fastmanifest_contains, /* sq_contains */
|
2016-04-08 21:48:31 +03:00
|
|
|
0, /* sq_inplace_concat */
|
|
|
|
0, /* sq_inplace_repeat */
|
|
|
|
};
|
|
|
|
|
|
|
|
static PyMethodDef fastmanifest_methods[] = {
|
|
|
|
{"iterkeys", (PyCFunction)fastmanifest_getkeysiter, METH_NOARGS,
|
|
|
|
"Iterate over file names in this fastmanifest."},
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
{"iterentries", (PyCFunction)fastmanifest_getentriesiter, METH_NOARGS,
|
|
|
|
"Iterate over (path, nodeid, flags) tuples in this fastmanifest."},
|
2016-04-08 21:48:31 +03:00
|
|
|
{"copy", (PyCFunction)fastmanifest_copy, METH_NOARGS,
|
|
|
|
"Make a copy of this fastmanifest."},
|
2016-05-20 01:24:10 +03:00
|
|
|
{"filtercopy", (PyCFunction)fastmanifest_filtercopy, METH_O,
|
|
|
|
"Make a copy of this manifest filtered by matchfn."},
|
2016-06-23 23:42:24 +03:00
|
|
|
{"_save", (PyCFunction)fastmanifest_save, METH_VARARGS,
|
2016-04-08 21:48:31 +03:00
|
|
|
"Save a fastmanifest to a file"},
|
2016-05-09 21:35:53 +03:00
|
|
|
{"load", (PyCFunction)fastmanifest_load, METH_VARARGS | METH_CLASS,
|
2016-04-08 21:48:31 +03:00
|
|
|
"Load a tree manifest from a file"},
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
{"diff", (PyCFunction)fastmanifest_diff, METH_VARARGS,
|
|
|
|
"Compare this fastmanifest to another one."},
|
|
|
|
{"text", (PyCFunction)fastmanifest_text, METH_NOARGS,
|
|
|
|
"Encode this manifest to text."},
|
2016-07-12 00:09:02 +03:00
|
|
|
{"bytes", (PyCFunction)fastmanifest_bytes, METH_NOARGS,
|
|
|
|
"Returns an upper bound on the number of bytes required "
|
|
|
|
"to represent this manifest."},
|
2016-04-08 21:48:31 +03:00
|
|
|
{NULL},
|
|
|
|
};
|
|
|
|
|
|
|
|
static PyTypeObject fastmanifestType = {
|
|
|
|
PyObject_HEAD_INIT(NULL)
|
|
|
|
0, /* ob_size */
|
|
|
|
"parsers.fastmanifest", /* tp_name */
|
|
|
|
sizeof(fastmanifest), /* tp_basicsize */
|
|
|
|
0, /* tp_itemsize */
|
|
|
|
(destructor)fastmanifest_dealloc, /* tp_dealloc */
|
|
|
|
0, /* tp_print */
|
|
|
|
0, /* tp_getattr */
|
|
|
|
0, /* tp_setattr */
|
|
|
|
0, /* tp_compare */
|
|
|
|
0, /* tp_repr */
|
|
|
|
0, /* tp_as_number */
|
|
|
|
&fastmanifest_seq_meths, /* tp_as_sequence */
|
|
|
|
&fastmanifest_mapping_methods, /* 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_HAVE_SEQUENCE_IN, /* tp_flags */
|
|
|
|
"TODO(augie)", /* tp_doc */
|
|
|
|
0, /* tp_traverse */
|
|
|
|
0, /* tp_clear */
|
|
|
|
0, /* tp_richcompare */
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
0, /* tp_weaklistoffset */
|
|
|
|
(getiterfunc)fastmanifest_getkeysiter, /* tp_iter */
|
2016-04-08 21:48:31 +03:00
|
|
|
0, /* tp_iternext */
|
|
|
|
fastmanifest_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 */
|
|
|
|
(initproc)fastmanifest_init, /* tp_init */
|
|
|
|
0, /* tp_alloc */
|
|
|
|
};
|
2016-04-18 23:18:04 +03:00
|
|
|
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
/* iteration support */
|
|
|
|
|
|
|
|
static void fmiter_dealloc(PyObject *o) {
|
2016-08-03 01:36:14 +03:00
|
|
|
fmIter *self = (fmIter *)o;
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
destroy_iterator(self->iterator);
|
|
|
|
PyObject_Del(self);
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *fmiter_iterkeysnext(PyObject *o) {
|
2016-08-03 01:36:14 +03:00
|
|
|
fmIter *self = (fmIter *)o;
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
iterator_result_t iterator_result = iterator_next(self->iterator);
|
|
|
|
if (!iterator_result.valid) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return PyString_FromStringAndSize(
|
|
|
|
iterator_result.path, iterator_result.path_sz);
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *fmiter_iterentriesnext(PyObject *o) {
|
2016-08-03 01:36:14 +03:00
|
|
|
fmIter *self = (fmIter *)o;
|
[fastmanifest] integration for tree_diff and tree_iterate
Summary: Python->C bindings.
Test Plan:
```
[andromeda]:~/work/mercurial/facebook-hg-rpms/fb-hgext:integration> PYTHONPATH=build/lib.macosx-10.11-intel-2.7/ python2.7
Python 2.7.11 (default, Mar 1 2016, 18:40:10)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastmanifest_wrapper
>>> m = fastmanifest_wrapper.fastManifest("")
>>> m['abc']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'File not found'
>>> m['abc'] = ('a' * 20, '')
>>> m['abc']
('aaaaaaaaaaaaaaaaaaaa', '')
>>> for k in m:
... print k
...
abc
>>> for k in m.iterentries():
... print k
...
('abc', 'aaaaaaaaaaaaaaaaaaaa', '')
>>>
```
Reviewers: lcharignon
Reviewed By: lcharignon
Subscribers: mitrandir, mjpieters, #sourcecontrol
Differential Revision: https://phabricator.intern.facebook.com/D3226735
Signature: t1:3226735:1461780626:680d0ea5eaf4c848b009bd00bea3e8c16893174d
2016-04-28 00:40:31 +03:00
|
|
|
iterator_result_t iterator_result = iterator_next(self->iterator);
|
|
|
|
if (!iterator_result.valid) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *ret = NULL, *path, *hash, *flags;
|
|
|
|
path = PyString_FromStringAndSize(
|
|
|
|
iterator_result.path, iterator_result.path_sz);
|
|
|
|
hash = PyString_FromStringAndSize(
|
|
|
|
(const char *) iterator_result.checksum, iterator_result.checksum_sz);
|
|
|
|
flags = PyString_FromStringAndSize(
|
|
|
|
(const char *) &iterator_result.flags,
|
|
|
|
iterator_result.flags == 0 ? 0 : 1);
|
|
|
|
if (!path || !hash || !flags) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
ret = PyTuple_Pack(3, path, hash, flags);
|
|
|
|
done:
|
|
|
|
Py_XDECREF(path);
|
|
|
|
Py_XDECREF(hash);
|
|
|
|
Py_XDECREF(flags);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyTypeObject fastmanifestKeysIterator = {
|
|
|
|
PyObject_HEAD_INIT(NULL)
|
|
|
|
0, /*ob_size */
|
|
|
|
"parsers.fastmanifest.keysiterator", /*tp_name */
|
|
|
|
sizeof(fmIter), /*tp_basicsize */
|
|
|
|
0, /*tp_itemsize */
|
|
|
|
fmiter_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 */
|
|
|
|
/* tp_flags: Py_TPFLAGS_HAVE_ITER tells python to
|
|
|
|
use tp_iter and tp_iternext fields. */
|
|
|
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,
|
|
|
|
"Keys iterator for a fastmanifest.", /* tp_doc */
|
|
|
|
0, /* tp_traverse */
|
|
|
|
0, /* tp_clear */
|
|
|
|
0, /* tp_richcompare */
|
|
|
|
0, /* tp_weaklistoffset */
|
|
|
|
PyObject_SelfIter, /* tp_iter: __iter__() method */
|
|
|
|
fmiter_iterkeysnext, /* tp_iternext: next() method */
|
|
|
|
};
|
|
|
|
|
|
|
|
static PyTypeObject fastmanifestEntriesIterator = {
|
|
|
|
PyObject_HEAD_INIT(NULL)
|
|
|
|
0, /*ob_size */
|
|
|
|
"parsers.fastmanifest.entriesiterator", /*tp_name */
|
|
|
|
sizeof(fmIter), /*tp_basicsize */
|
|
|
|
0, /*tp_itemsize */
|
|
|
|
fmiter_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 */
|
|
|
|
/* tp_flags: Py_TPFLAGS_HAVE_ITER tells python to
|
|
|
|
use tp_iter and tp_iternext fields. */
|
|
|
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,
|
|
|
|
"Iterator for 3-tuples in a fastmanifest.", /* tp_doc */
|
|
|
|
0, /* tp_traverse */
|
|
|
|
0, /* tp_clear */
|
|
|
|
0, /* tp_richcompare */
|
|
|
|
0, /* tp_weaklistoffset */
|
|
|
|
PyObject_SelfIter, /* tp_iter: __iter__() method */
|
|
|
|
fmiter_iterentriesnext, /* tp_iternext: next() method */
|
|
|
|
};
|
|
|
|
|
2016-04-18 23:18:04 +03:00
|
|
|
static PyMethodDef methods[] = {
|
|
|
|
{NULL, NULL, 0, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
PyMODINIT_FUNC
|
2016-05-26 21:34:56 +03:00
|
|
|
initcfastmanifest(void)
|
2016-04-18 23:18:04 +03:00
|
|
|
{
|
|
|
|
PyObject* m;
|
|
|
|
|
|
|
|
fastmanifestType.tp_new = PyType_GenericNew;
|
|
|
|
if (PyType_Ready(&fastmanifestType) < 0)
|
|
|
|
return;
|
|
|
|
|
2016-05-26 21:34:56 +03:00
|
|
|
m = Py_InitModule3("cfastmanifest", methods,
|
2016-04-18 23:18:04 +03:00
|
|
|
"Wrapper around fast_manifest");
|
|
|
|
|
|
|
|
Py_INCREF(&fastmanifestType);
|
2016-05-26 21:34:56 +03:00
|
|
|
PyModule_AddObject(m, "fastmanifest", (PyObject *)&fastmanifestType);
|
2016-04-18 23:18:04 +03:00
|
|
|
}
|