tahoe-lafs/pyfec/fec/test/test_pyfec.py
Zooko O'Whielacronx 37ede96167 pyfec v0.9
Here is the change history from the first darcs era, in reverse chronological
order:

Mon Jan 22 16:12:56 MST 2007  "Zooko O'Whielacronx <zooko@zooko.com>"
  * move everything into a subdirectory so that I can merge this darcs repo with the tahoe darcs repo
  

     ./fec -> ./pyfec/fec
     ./setup.py -> ./pyfec/setup.py
    A ./pyfec/

Mon Jan 22 16:10:17 MST 2007  "Zooko O'Whielacronx <zooko@zooko.com>"
  * clean up and minimize fec.c
   * strip out unused code
   * hard-code GF_BITS to 8
   * reindent and reformat curly bracket placement
  

    M ./fec/fec.c -655 +324
    M ./fec/fec.h -25

Mon Jan 22 14:24:32 MST 2007  "Zooko O'Whielacronx <zooko@zooko.com>"
  * change API to allow a subset of the shares to be produced, and to just pass back pointers to primary shares instead of copying them

    M ./fec/fec.c -24 +40
    M ./fec/fec.h -5 +17
    M ./fec/fecmodule.c -63 +144
    M ./fec/test/test_pyfec.py -16 +25
    M ./setup.py -2 +27

Tue Jan 16 23:01:44 MST 2007  "Zooko O'Whielacronx <zooko@zooko.com>"
  * split encoder from decoder

    M ./fec/fecmodule.c -48 +161
    M ./fec/test/test_pyfec.py -3 +4

Tue Jan 16 14:35:25 MST 2007  "Zooko O'Whielacronx <zooko@zooko.com>"
  * it compiles now!

     ./fec.c -> ./pyfec/fec.c
     ./fec.h -> ./pyfec/fec.h
     ./fecmodule.c -> ./pyfec/fecmodule.c
     ./pyfec -> ./fec
    M ./fec/fec.c -109 +85 r13
    M ./fec/fec.h -3 +2 r13
    M ./fec/fecmodule.c -23 +241 r13
    A ./fec/test/
    A ./fec/test/test_pyfec.py
    A ./pyfec/
    A ./setup.py

Tue Jan  9 10:47:58 MST 2007  zooko@zooko.com
  * start of new fecmodule.c

    A ./fecmodule.c

Mon Jan  1 15:00:04 MST 2007  zooko@zooko.com
  * tidy up error handling

    M ./fec.c -26 +16

Mon Jan  1 14:06:30 MST 2007  zooko@zooko.com
  * remove the on-the-fly encoding option
  We don't currently need it.

    M ./fec.c -68
    M ./fec.h -22

Mon Jan  1 13:53:28 MST 2007  zooko@zooko.com
  * original import from Mnet project

    A ./fec.c
    A ./fec.h
2007-01-22 17:17:31 -07:00

83 lines
2.7 KiB
Python

#!/usr/bin/env python
from pyutil.assertutil import _assert, precondition
import random
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)
# sys.stdout.write("constructed.\n") ; sys.stdout.flush()
nums_and_shares = list(enumerate(encer.encode(ss)))
# sys.stdout.write("encoded.\n") ; sys.stdout.flush()
_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()
decer = fec.Decoder(k, m)
# sys.stdout.write("about to decode.\n") ; sys.stdout.flush()
decoded = decer.decode(shares, nums)
# sys.stdout.write("decoded.\n") ; sys.stdout.flush()
_assert(len(decoded) == len(ss), len(decoded), len(ss))
_assert(tuple([str(s) for s in decoded]) == tuple([str(s) for s in ss]), tuple([str(s) for s in decoded]), tuple([str(s) for s in ss]))
def randstr(n):
return ''.join(map(chr, map(random.randrange, [0]*n, [256]*n)))
def div_ceil(n, d):
"""
The smallest integer k such that k*d >= n.
"""
return (n/d) + (n%d != 0)
def next_multiple(n, k):
"""
The smallest multiple of k which is >= n.
"""
return div_ceil(n, k) * k
def pad_size(n, k):
"""
The smallest number that has to be added to n so that n is a multiple of k.
"""
if n%k:
return k - n%k
else:
return 0
def _test_random():
# m = random.randrange(1, 255)
m = 99
# k = random.randrange(1, m+1)
k = 33
# l = random.randrange(0, 2**16)
l = 2**12
ss = [ randstr(l/k) + '\x00' * pad_size(l/k, k) for x in range(k) ]
_h(k, m, ss)
def test_random():
for i in range(2**9):
sys.stdout.write(",")
_test_random()
sys.stdout.write(".")
test_random()