First commit for needed_fragments interface change in liberasurecode.

Still needed:

Test 'exclude_fragments' usage
This commit is contained in:
Kevin Greenan 2014-08-20 09:13:50 -07:00
parent ec3329cf64
commit 3cf0830725
4 changed files with 41 additions and 20 deletions

View File

@ -378,7 +378,8 @@ pyeclib_c_encode(PyObject *self, PyObject *args)
* and a list of missing indexes. * and a list of missing indexes.
* *
* @param pyeclib_obj_handle * @param pyeclib_obj_handle
* @param missing_list indexes of missing fragments * @param reconstruct_list list of missing fragments to reconstruct
* @param exclude_list list of fragments to exclude from reconstruction
* @return a list of lists of indexes to rebuild data from * @return a list of lists of indexes to rebuild data from
*/ */
static PyObject * static PyObject *
@ -386,17 +387,20 @@ pyeclib_c_get_required_fragments(PyObject *self, PyObject *args)
{ {
PyObject *pyeclib_obj_handle = NULL; PyObject *pyeclib_obj_handle = NULL;
pyeclib_t *pyeclib_handle = NULL; pyeclib_t *pyeclib_handle = NULL;
PyObject *missing_list = NULL; /* param, */ PyObject *reconstruct_list = NULL; /* list of missing fragments to reconstruct */
PyObject *exclude_list = NULL; /* list of fragments to exclude from reconstruction */
PyObject *fragment_idx_list = NULL; /* list of req'd indexes to return */ PyObject *fragment_idx_list = NULL; /* list of req'd indexes to return */
int *c_missing_list = NULL; /* c-array of missing indexes */ int *c_reconstruct_list = NULL; /* c-array of missing indexes */
int *c_exclude_list = NULL; /* c-array of missing indexes */
int num_missing; /* size of passed in missing list */ int num_missing; /* size of passed in missing list */
int num_exclude; /* size of passed in exclude list */
int i = 0; /* counters */ int i = 0; /* counters */
int k, m; /* EC algorithm parameters */ int k, m; /* EC algorithm parameters */
int *fragments_needed = NULL; /* indexes of xor code fragments */ int *fragments_needed = NULL; /* indexes of xor code fragments */
int ret; /* return value for xor code */ int ret; /* return value for xor code */
/* Obtain and validate the method parameters */ /* Obtain and validate the method parameters */
if (!PyArg_ParseTuple(args, "OO", &pyeclib_obj_handle, &missing_list)) { if (!PyArg_ParseTuple(args, "OOO", &pyeclib_obj_handle, &reconstruct_list, &exclude_list)) {
PyErr_SetString(PyECLibError, "Invalid arguments passed to pyeclib.get_required_fragments"); PyErr_SetString(PyECLibError, "Invalid arguments passed to pyeclib.get_required_fragments");
return NULL; return NULL;
} }
@ -409,16 +413,28 @@ pyeclib_c_get_required_fragments(PyObject *self, PyObject *args)
m = pyeclib_handle->ec_args.m; m = pyeclib_handle->ec_args.m;
/* Generate -1 terminated c-array and bitmap of missing indexes */ /* Generate -1 terminated c-array and bitmap of missing indexes */
num_missing = (int) PyList_Size(missing_list); num_missing = (int) PyList_Size(reconstruct_list);
c_missing_list = (int *) alloc_zeroed_buffer((num_missing + 1) * sizeof(int)); c_reconstruct_list = (int *) alloc_zeroed_buffer((num_missing + 1) * sizeof(int));
if (NULL == c_missing_list) { if (NULL == c_reconstruct_list) {
return NULL; return NULL;
} }
c_missing_list[num_missing] = -1; c_reconstruct_list[num_missing] = -1;
for (i = 0; i < num_missing; i++) { for (i = 0; i < num_missing; i++) {
PyObject *obj_idx = PyList_GetItem(missing_list, i); PyObject *obj_idx = PyList_GetItem(reconstruct_list, i);
long idx = PyLong_AsLong(obj_idx); long idx = PyLong_AsLong(obj_idx);
c_missing_list[i] = (int) idx; c_reconstruct_list[i] = (int) idx;
}
num_exclude = (int) PyList_Size(exclude_list);
c_exclude_list = (int *) alloc_zeroed_buffer((num_exclude + 1) * sizeof(int));
if (NULL == c_exclude_list) {
goto exit;
}
c_exclude_list[num_exclude] = -1;
for (i = 0; i < num_exclude; i++) {
PyObject *obj_idx = PyList_GetItem(exclude_list, i);
long idx = PyLong_AsLong(obj_idx);
c_exclude_list[i] = (int) idx;
} }
fragments_needed = alloc_zeroed_buffer(sizeof(int) * (k + m)); fragments_needed = alloc_zeroed_buffer(sizeof(int) * (k + m));
@ -426,7 +442,8 @@ pyeclib_c_get_required_fragments(PyObject *self, PyObject *args)
goto exit; goto exit;
} }
ret = liberasurecode_fragments_needed(pyeclib_handle->ec_desc, c_missing_list, fragments_needed); ret = liberasurecode_fragments_needed(pyeclib_handle->ec_desc, c_reconstruct_list,
c_exclude_list, fragments_needed);
if (ret < 0) { if (ret < 0) {
PyErr_Format(PyECLibError, "Not enough fragments for pyeclib.get_required_fragments!"); PyErr_Format(PyECLibError, "Not enough fragments for pyeclib.get_required_fragments!");
goto exit; goto exit;
@ -443,7 +460,8 @@ pyeclib_c_get_required_fragments(PyObject *self, PyObject *args)
} }
exit: exit:
check_and_free_buffer(c_missing_list); check_and_free_buffer(c_reconstruct_list);
check_and_free_buffer(c_exclude_list);
check_and_free_buffer(fragments_needed); check_and_free_buffer(fragments_needed);
return fragment_idx_list; return fragment_idx_list;

View File

@ -122,9 +122,9 @@ class ECPyECLibDriver(object):
return reconstructed_data return reconstructed_data
def fragments_needed(self, missing_fragment_indexes): def fragments_needed(self, reconstruct_indexes, exclude_indexes):
return pyeclib_c.get_required_fragments( return pyeclib_c.get_required_fragments(
self.handle, missing_fragment_indexes) self.handle, reconstruct_indexes, exclude_indexes)
def get_metadata(self, fragment): def get_metadata(self, fragment):
return pyeclib_c.get_metadata(self.handle, fragment) return pyeclib_c.get_metadata(self.handle, fragment)

View File

@ -234,21 +234,24 @@ class ECDriver(object):
return self.ec_lib_reference.reconstruct( return self.ec_lib_reference.reconstruct(
available_fragment_payloads, missing_fragment_indexes) available_fragment_payloads, missing_fragment_indexes)
def fragments_needed(self, missing_fragment_indexes): def fragments_needed(self, reconstruction_indexes, exclude_indexes = []):
""" """
Determine which fragments are needed to reconstruct some subset of Determine which fragments are needed to reconstruct some subset of
missing fragments. missing fragments.
:param missing_fragment_indexes: a list of integers representing the :param reconstruction_indexes: a list of integers representing the
indexes of the fragments to be indexes of the fragments to be
reconstructed. reconstructed.
:returns: a list of lists containing fragment indexes. Each sub-list :param exclude_indexes: a list of integers representing the
contains a combination of fragments that can be used to indexes of the fragments to be
excluded from the reconstruction
equations.
:returns: a list containing fragment indexes that can be used to
reconstruct the missing fragments. reconstruct the missing fragments.
:raises: ECDriverError if there is an error during decoding or there :raises: ECDriverError if there is an error during decoding or there
are not sufficient fragments to decode are not sufficient fragments to decode
""" """
return self.ec_lib_reference.fragments_needed(missing_fragment_indexes) return self.ec_lib_reference.fragments_needed(reconstruction_indexes, exclude_indexes)
def get_metadata(self, fragment): def get_metadata(self, fragment):
""" """

View File

@ -274,7 +274,7 @@ class TestPyECLib(unittest.TestCase):
expected_fragments = expected_fragments[:num_data] expected_fragments = expected_fragments[:num_data]
required_fragments = pyeclib_c.get_required_fragments( required_fragments = pyeclib_c.get_required_fragments(
handle, handle,
missing_fragments) missing_fragments, [])
if expected_fragments != required_fragments: if expected_fragments != required_fragments:
success = False success = False