summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKevin Greenan <kmgreen2@gmail.com>2014-07-23 12:39:41 -0700
committerKevin Greenan <kmgreen2@gmail.com>2014-07-23 12:47:52 -0700
commit5c54419755558d43ca346e5af9024ee11077fb95 (patch)
tree0f745691ef9cd2c032966fcf41b27d0efa2c1d50 /src
parent7cc67fee9c2c9074af6eb7903f54322053482759 (diff)
downloadliberasurecode-5c54419755558d43ca346e5af9024ee11077fb95.tar.gz
Plugged-in Cauchy RS.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am3
-rw-r--r--src/backends/jerasure/jerasure_rs_cauchy.c302
-rw-r--r--src/erasurecode.c3
3 files changed, 306 insertions, 2 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 9d844f8..2e64f95 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -16,7 +16,8 @@ liberasurecode_la_SOURCES = \
utils/chksum/alg_sig.c \
backends/null/null.c \
backends/xor/flat_xor_hd.c \
- backends/jerasure/jerasure_rs_vand.c
+ backends/jerasure/jerasure_rs_vand.c \
+ backends/jerasure/jerasure_rs_cauchy.c
liberasurecode_la_CPPFLAGS = -Werror
liberasurecode_la_LIBADD = \
diff --git a/src/backends/jerasure/jerasure_rs_cauchy.c b/src/backends/jerasure/jerasure_rs_cauchy.c
new file mode 100644
index 0000000..5707a6d
--- /dev/null
+++ b/src/backends/jerasure/jerasure_rs_cauchy.c
@@ -0,0 +1,302 @@
+/*
+ * <Copyright>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY
+ * THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * jerasure_rs_cauchy backend implementation
+ *
+ * vi: set noai tw=79 ts=4 sw=4:
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "erasurecode.h"
+#include "erasurecode_backend.h"
+#include "erasurecode_helpers.h"
+
+/* Forward declarations */
+struct ec_backend_op_stubs jerasure_rs_cauchy_ops;
+struct ec_backend jerasure_rs_cauchy;
+
+/*
+ * ToDo (KMG): Should we make this a parameter, or is that
+ * exposing too much b.s. to the client?
+ */
+#define PYECC_CAUCHY_PACKETSIZE sizeof(long) * 128
+
+struct jerasure_rs_cauchy_descriptor {
+ /* calls required for init */
+ int * (*cauchy_original_coding_matrix)(int, int, int);
+ int * (*jerasure_matrix_to_bitmatrix)(int, int, int, int*);
+ int ** (*jerasure_smart_bitmatrix_to_schedule)(int, int, int, int*);
+
+ /* calls required for encode */
+ void (*jerasure_bitmatrix_encode)(int, int, int, int *, char **, char **, int, int);
+
+
+ /* calls required for decode */
+ int (*jerasure_bitmatrix_decode)(int, int, int, int *, int, int *,char **, char **, int, int);
+
+
+ /* calls required for reconstruct */
+ int * (*jerasure_erasures_to_erased)(int, int, int *);
+ int (*jerasure_make_decoding_bitmatrix)(int, int, int, int *, int *, int *, int *);
+ void (*jerasure_bitmatrix_dotprod)(int, int, int *, int *, int,char **, char **, int, int);
+
+ /* fields needed to hold state */
+ int *matrix;
+ int *bitmatrix;
+ int **schedule;
+ int k;
+ int m;
+ int w;
+};
+
+static int jerasure_rs_cauchy_encode(void *desc, char **data, char **parity,
+ int blocksize)
+{
+ struct jerasure_rs_cauchy_descriptor *jerasure_desc =
+ (struct jerasure_rs_cauchy_descriptor*) desc;
+
+ /* FIXME - make jerasure_bitmatrix_encode return a value */
+ jerasure_desc->jerasure_bitmatrix_encode(jerasure_desc->k, jerasure_desc->m,
+ jerasure_desc->w, jerasure_desc->bitmatrix,
+ data, parity, blocksize,
+ PYECC_CAUCHY_PACKETSIZE);
+
+ return 0;
+}
+
+static int jerasure_rs_cauchy_decode(void *desc, char **data, char **parity,
+ int *missing_idxs, int blocksize)
+{
+ struct jerasure_rs_cauchy_descriptor *jerasure_desc =
+ (struct jerasure_rs_cauchy_descriptor*)desc;
+
+ /* FIXME - make jerasure_matrix_decode return a value */
+ jerasure_desc->jerasure_bitmatrix_decode(jerasure_desc->k,
+ jerasure_desc->m,
+ jerasure_desc->w,
+ jerasure_desc->bitmatrix,
+ 0,
+ missing_idxs,
+ data,
+ parity,
+ blocksize,
+ PYECC_CAUCHY_PACKETSIZE);
+}
+
+static int jerasure_rs_cauchy_reconstruct(void *desc, char **data, char **parity,
+ int *missing_idxs, int destination_idx, int blocksize)
+{
+ int ret = 1;
+ int *decoding_row = NULL;
+ int *erased = NULL;
+
+ struct jerasure_rs_cauchy_descriptor *jerasure_desc =
+ (struct jerasure_rs_cauchy_descriptor*) desc;
+ int *dm_ids = (int *)
+ alloc_zeroed_buffer(sizeof(int) * jerasure_desc->k);
+ int *decoding_matrix = (int *)
+ (int *) alloc_zeroed_buffer(sizeof(int*) * jerasure_desc->k * jerasure_desc->k * jerasure_desc->w * jerasure_desc->w);
+
+ if (NULL == decoding_matrix || NULL == dm_ids) {
+ goto out;
+ }
+
+ if (destination_idx < jerasure_desc->k) {
+
+ erased = jerasure_desc->jerasure_erasures_to_erased(jerasure_desc->k,
+ jerasure_desc->m, missing_idxs);
+
+ ret = jerasure_make_decoding_bitmatrix(jerasure_desc->k, jerasure_desc->m, jerasure_desc->w, jerasure_desc->bitmatrix,
+ erased, decoding_matrix, dm_ids);
+ decoding_row = decoding_matrix + (destination_idx * jerasure_desc->k * jerasure_desc->w * jerasure_desc->w);
+
+ } else {
+ ret = 0;
+ decoding_row = jerasure_desc->bitmatrix + ((destination_idx - jerasure_desc->k) * jerasure_desc->k * jerasure_desc->w * jerasure_desc->w);
+ }
+
+ if (ret == 0) {
+ jerasure_bitmatrix_dotprod(jerasure_desc->k, jerasure_desc->w, decoding_row, dm_ids, destination_idx,
+ data, parity, blocksize,
+ PYECC_CAUCHY_PACKETSIZE);
+ }
+
+out:
+ if (NULL != decoding_matrix) {
+ free(decoding_matrix);
+ }
+ if (NULL != dm_ids) {
+ free(dm_ids);
+ }
+
+}
+
+static int jerasure_rs_cauchy_min_fragments(void *desc, int *missing_idxs,
+ int *fragments_needed)
+{
+ struct jerasure_rs_cauchy_descriptor *jerasure_desc =
+ (struct jerasure_rs_cauchy_descriptor*)desc;
+ //ToDo (KMG): We need to move over the bitmap helper functions before we
+ // can implement this.
+}
+
+#define DEFAULT_W 4
+static void * jerasure_rs_cauchy_init(struct ec_backend_args *args,
+ void *backend_sohandle)
+{
+ struct jerasure_rs_cauchy_descriptor *desc =
+ (struct jerasure_rs_cauchy_descriptor *) malloc(
+ sizeof(struct jerasure_rs_cauchy_descriptor));
+
+ if (NULL == desc) {
+ return NULL;
+ }
+
+ desc->k = args->uargs.k;
+ desc->m = args->uargs.m;
+
+ if (args->uargs.w <= 0)
+ args->uargs.w = DEFAULT_W;
+
+ /* store w back in args so upper layer can get to it */
+ desc->w = args->uargs.w;
+
+ /* validate EC arguments */
+ {
+ long long max_symbols;
+ max_symbols = 1LL << desc->w;
+ if ((desc->k + desc->m) > max_symbols) {
+ goto error;
+ }
+ }
+
+ /* fill in function addresses */
+ desc->jerasure_bitmatrix_encode = dlsym(
+ backend_sohandle, "jerasure_bitmatrix_encode");
+ if (NULL == desc->jerasure_bitmatrix_encode) {
+ goto error;
+ }
+
+ desc->jerasure_bitmatrix_decode = dlsym(
+ backend_sohandle, "jerasure_bitmatrix_decode");
+ if (NULL == desc->jerasure_bitmatrix_decode) {
+ goto error;
+ }
+
+ desc->cauchy_original_coding_matrix = dlsym(
+ backend_sohandle, "cauchy_original_coding_matrix");
+ if (NULL == desc->cauchy_original_coding_matrix) {
+ goto error;
+ }
+
+ desc->jerasure_matrix_to_bitmatrix = dlsym(
+ backend_sohandle, "jerasure_matrix_to_bitmatrix");
+ if (NULL == desc->jerasure_matrix_to_bitmatrix) {
+ goto error;
+ }
+
+ desc->jerasure_smart_bitmatrix_to_schedule = dlsym(
+ backend_sohandle, "jerasure_smart_bitmatrix_to_schedule");
+ if (NULL == desc->jerasure_smart_bitmatrix_to_schedule) {
+ goto error;
+ }
+
+ desc->jerasure_make_decoding_bitmatrix = dlsym(
+ backend_sohandle, "jerasure_make_decoding_bitmatrix");
+ if (NULL == desc->jerasure_make_decoding_bitmatrix) {
+ goto error;
+ }
+
+ desc->jerasure_bitmatrix_dotprod = dlsym(
+ backend_sohandle, "jerasure_bitmatrix_dotprod");
+ if (NULL == desc->jerasure_bitmatrix_dotprod) {
+ goto error;
+ }
+
+ desc->jerasure_erasures_to_erased = dlsym(
+ backend_sohandle, "jerasure_erasures_to_erased");
+ if (NULL == desc->jerasure_erasures_to_erased) {
+ goto error;
+ }
+
+ desc->matrix = desc->cauchy_original_coding_matrix(desc->k, desc->m, desc->w);
+ desc->bitmatrix = desc->jerasure_matrix_to_bitmatrix(desc->k, desc->m, desc->w, desc->matrix);
+ desc->schedule = desc->jerasure_smart_bitmatrix_to_schedule(desc->k, desc->m, desc->w, desc->bitmatrix);
+
+ return desc;
+
+error:
+ if (NULL != desc) {
+ free(desc);
+ }
+ return NULL;
+}
+
+/**
+ * Return the element-size, which is the number of bits stored
+ * on a given device, per codeword.
+ *
+ * Returns the size in bits!
+ */
+static int
+jerasure_rs_cauchy_element_size(void* desc)
+{
+ struct jerasure_rs_cauchy_descriptor *jerasure_desc =
+ (struct jerasure_rs_cauchy_descriptor*)desc;
+
+ return jerasure_desc->w * PYECC_CAUCHY_PACKETSIZE * 8;
+}
+
+static int jerasure_rs_cauchy_exit(void *desc)
+{
+ struct jerasure_rs_cauchy_descriptor *jerasure_desc =
+ (struct jerasure_rs_cauchy_descriptor*)desc;
+
+ if (NULL != desc) {
+ free(desc);
+ }
+}
+
+struct ec_backend_op_stubs jerasure_rs_cauchy_op_stubs = {
+ .INIT = jerasure_rs_cauchy_init,
+ .EXIT = jerasure_rs_cauchy_exit,
+ .ENCODE = jerasure_rs_cauchy_encode,
+ .DECODE = jerasure_rs_cauchy_decode,
+ .FRAGSNEEDED = jerasure_rs_cauchy_min_fragments,
+ .RECONSTRUCT = jerasure_rs_cauchy_reconstruct,
+ .ELEMENTSIZE = jerasure_rs_cauchy_element_size,
+};
+
+struct ec_backend_common backend_jerasure_rs_cauchy = {
+ .id = EC_BACKEND_JERASURE_RS_CAUCHY,
+ .name = "jerasure_rs_cauchy",
+#if defined(__MACOS__) || defined(__MACOSX__) || defined(__OSX__) || defined(__APPLE__)
+ .soname = "libJerasure.dylib",
+#else
+ .soname = "libJerasure.so",
+#endif
+ .soversion = "2.0",
+ .ops = &jerasure_rs_cauchy_op_stubs,
+};
diff --git a/src/erasurecode.c b/src/erasurecode.c
index 5f5c422..b987031 100644
--- a/src/erasurecode.c
+++ b/src/erasurecode.c
@@ -51,11 +51,12 @@ liberasurecode_exit(void) {
extern struct ec_backend_common backend_null;
extern struct ec_backend_common backend_flat_xor_hd;
extern struct ec_backend_common backend_jerasure_rs_vand;
+extern struct ec_backend_common backend_jerasure_rs_cauchy;
ec_backend_t ec_backends_supported[EC_BACKENDS_MAX] = {
(ec_backend_t) &backend_null,
(ec_backend_t) &backend_jerasure_rs_vand,
- /* backend_rs_cauchy_orig */ NULL,
+ (ec_backend_t) &backend_jerasure_rs_cauchy,
(ec_backend_t) &backend_flat_xor_hd,
};