From 36c3742929ee18191510240bc79131131021bac0 Mon Sep 17 00:00:00 2001
From: "Zooko O'Whielacronx zooko@zooko.com" <zooko@zooko.com>
Date: Thu, 25 Jan 2007 02:50:53 +0530
Subject: [PATCH] nicer API -- you don't have to shuffle the shares into place
 before calling decode_all()

Instead it does that shuffling in C inside fecmodule.

darcs-hash:ea6a582d227615043c682aac3647560ac0da2125
---
 pyfec/fec/fecmodule.c        | 16 ++++++++++++++++
 pyfec/fec/test/test_pyfec.py | 13 -------------
 2 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/pyfec/fec/fecmodule.c b/pyfec/fec/fecmodule.c
index 50dc695..7758ee7 100644
--- a/pyfec/fec/fecmodule.c
+++ b/pyfec/fec/fecmodule.c
@@ -322,6 +322,8 @@ Decoder_init(Encoder *self, PyObject *args, PyObject *kwdict) {
     return 0;
 }
 
+#define SWAP(a,b,t) {t tmp; tmp=a; a=b; b=tmp;}
+
 static char Decoder_decode__doc__[] = "\
 Decode a list shares into a list of segments.\n\
 @param shares a sequence of buffers containing share data (for best performance, make it a tuple instead of a list)\n\
@@ -394,6 +396,20 @@ Decoder_decode(Decoder *self, PyObject *args) {
         oldsz = sz;
     }
 
+    /* move src packets into position */
+    for (i=0; i<self->kk;) {
+        if (csharenums[i] >= self->kk || csharenums[i] == i)
+            i++;
+        else {
+            /* put pkt in the right position. */
+            unsigned char c = csharenums[i];
+
+            SWAP (csharenums[i], csharenums[c], int);
+            SWAP (cshares[i], cshares[c], gf*);
+            SWAP (fastsharesitems[i], fastsharesitems[c], PyObject*);
+        }
+    }
+
     /* Allocate space for all of the recovered shares. */
     for (i=0; i<needtorecover; i++) {
         recoveredpystrs[i] = PyString_FromStringAndSize(NULL, sz);
diff --git a/pyfec/fec/test/test_pyfec.py b/pyfec/fec/test/test_pyfec.py
index c84d0b2..b135d95 100755
--- a/pyfec/fec/test/test_pyfec.py
+++ b/pyfec/fec/test/test_pyfec.py
@@ -7,18 +7,6 @@ import sys
 
 import fec
 
-def shuffle(nums_and_shares):
-    """ Make sure that if nums_and_shares[i][0] < len(nums_and_shares), that i == nums_and_shares[i][0]. """
-    i = 0
-    while i < len(nums_and_shares):
-        num, share = nums_and_shares[i]
-        if num >= len(nums_and_shares) or num == i:
-            i += 1
-        else:
-            nums_and_shares[i] = nums_and_shares[num]
-            nums_and_shares[num] = (num, share,)
-    _assert([ (i, (num, share,),) for (i, (num, share,),) in enumerate(nums_and_shares) if num < len(nums_and_shares) and num != i ] == [], [ (i, (num, share,),) for (i, (num, share,),) in enumerate(nums_and_shares) if num < len(nums_and_shares) and num != i ])
-
 def _h(k, m, ss):
     # sys.stdout.write("k: %s, m: %s,  len(ss): %r, len(ss[0]): %r" % (k, m, len(ss), len(ss[0]),)) ; sys.stdout.flush()
     encer = fec.Encoder(k, m)
@@ -28,7 +16,6 @@ def _h(k, m, ss):
     _assert(isinstance(nums_and_shares, list), nums_and_shares)
     _assert(len(nums_and_shares) == m, len(nums_and_shares), m)
     nums_and_shares = random.sample(nums_and_shares, k)
-    shuffle(nums_and_shares)
     shares = [ x[1] for x in nums_and_shares ]
     nums = [ x[0] for x in nums_and_shares ]
     # sys.stdout.write("about to construct Decoder.\n") ; sys.stdout.flush()
-- 
2.45.2