mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-19 04:57:54 +00:00
encoding: fix the last py_ecc problem, tests pass now
This commit is contained in:
parent
436409fa4d
commit
e1c6ee9dcf
@ -98,6 +98,17 @@ class PyRSEncoder(object):
|
|||||||
# the serialized parameters to strip this padding out on the receiving
|
# the serialized parameters to strip this padding out on the receiving
|
||||||
# end.
|
# end.
|
||||||
|
|
||||||
|
# TODO: this will write a 733kB file called 'ffield.lut.8' in the current
|
||||||
|
# directory the first time it is run, to cache the lookup table for later
|
||||||
|
# use. It appears to take about 15 seconds to create this the first time.
|
||||||
|
# Make sure this file winds up somewhere reasonable.
|
||||||
|
|
||||||
|
# TODO: the encoder/decoder RSCode object depends upon the number of
|
||||||
|
# required/total shares, but not upon the data. We could probably save a
|
||||||
|
# lot of initialization time by caching a single instance and using it
|
||||||
|
# any time we use the same required/total share numbers (which will
|
||||||
|
# probably be always).
|
||||||
|
|
||||||
def set_params(self, data_size, required_shares, total_shares):
|
def set_params(self, data_size, required_shares, total_shares):
|
||||||
assert required_shares <= total_shares
|
assert required_shares <= total_shares
|
||||||
self.data_size = data_size
|
self.data_size = data_size
|
||||||
@ -159,12 +170,13 @@ class PyRSDecoder(object):
|
|||||||
self.share_size = self.num_chunks
|
self.share_size = self.num_chunks
|
||||||
self.encoder = rs_code.RSCode(self.total_shares, self.required_shares,
|
self.encoder = rs_code.RSCode(self.total_shares, self.required_shares,
|
||||||
8)
|
8)
|
||||||
#print "chunk_size: %d" % self.chunk_size
|
if False:
|
||||||
#print "num_chunks: %d" % self.num_chunks
|
print "chunk_size: %d" % self.chunk_size
|
||||||
#print "last_chunk_padding: %d" % self.last_chunk_padding
|
print "num_chunks: %d" % self.num_chunks
|
||||||
#print "share_size: %d" % self.share_size
|
print "last_chunk_padding: %d" % self.last_chunk_padding
|
||||||
#print "total_shares: %d" % self.total_shares
|
print "share_size: %d" % self.share_size
|
||||||
#print "required_shares: %d" % self.required_shares
|
print "total_shares: %d" % self.total_shares
|
||||||
|
print "required_shares: %d" % self.required_shares
|
||||||
|
|
||||||
def decode(self, some_shares):
|
def decode(self, some_shares):
|
||||||
chunk_size = self.chunk_size
|
chunk_size = self.chunk_size
|
||||||
@ -176,7 +188,6 @@ class PyRSDecoder(object):
|
|||||||
for i in range(self.share_size):
|
for i in range(self.share_size):
|
||||||
# this takes one byte from each share, and turns the combination
|
# this takes one byte from each share, and turns the combination
|
||||||
# into a single chunk
|
# into a single chunk
|
||||||
#print "PULLING"
|
|
||||||
received_vector = []
|
received_vector = []
|
||||||
for j in range(self.total_shares):
|
for j in range(self.total_shares):
|
||||||
share = have_shares.get(j)
|
share = have_shares.get(j)
|
||||||
@ -186,16 +197,12 @@ class PyRSDecoder(object):
|
|||||||
received_vector.append(None)
|
received_vector.append(None)
|
||||||
decoded_vector = self.encoder.DecodeImmediate(received_vector)
|
decoded_vector = self.encoder.DecodeImmediate(received_vector)
|
||||||
assert len(decoded_vector) == self.chunk_size
|
assert len(decoded_vector) == self.chunk_size
|
||||||
#print "DECODED: %d" % len(decoded_vector)
|
|
||||||
chunk = "".join([chr(x) for x in decoded_vector])
|
chunk = "".join([chr(x) for x in decoded_vector])
|
||||||
#print "appending %d bytes" % len(chunk)
|
|
||||||
chunks.append(chunk)
|
chunks.append(chunk)
|
||||||
data = "".join(chunks)
|
data = "".join(chunks)
|
||||||
#print "pre-stripped length: %d" % len(data)
|
|
||||||
if self.last_chunk_padding:
|
if self.last_chunk_padding:
|
||||||
data = data[:-self.last_chunk_padding]
|
data = data[:-self.last_chunk_padding]
|
||||||
#print "post-stripped length: %d" % len(data)
|
assert len(data) == self.data_size
|
||||||
assert len(data) == chunk_size
|
|
||||||
return defer.succeed(data)
|
return defer.succeed(data)
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
import os
|
import os
|
||||||
from twisted.trial import unittest
|
from twisted.trial import unittest
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
from twisted.python import log
|
||||||
from allmydata.encode import PyRSEncoder, PyRSDecoder, ReplicatingEncoder, ReplicatingDecoder
|
from allmydata.encode import PyRSEncoder, PyRSDecoder, ReplicatingEncoder, ReplicatingDecoder
|
||||||
import random
|
import random
|
||||||
|
|
||||||
@ -14,6 +15,7 @@ class Tester:
|
|||||||
enc = self.enc_class()
|
enc = self.enc_class()
|
||||||
enc.set_params(size, required_shares, total_shares)
|
enc.set_params(size, required_shares, total_shares)
|
||||||
serialized_params = enc.get_serialized_params()
|
serialized_params = enc.get_serialized_params()
|
||||||
|
log.msg("serialized_params: %s" % serialized_params)
|
||||||
d = enc.encode(data0)
|
d = enc.encode(data0)
|
||||||
def _done(shares):
|
def _done(shares):
|
||||||
self.failUnlessEqual(len(shares), total_shares)
|
self.failUnlessEqual(len(shares), total_shares)
|
||||||
@ -31,20 +33,23 @@ class Tester:
|
|||||||
self.failUnless(data1 == data0)
|
self.failUnless(data1 == data0)
|
||||||
|
|
||||||
def _decode_all_ordered(res):
|
def _decode_all_ordered(res):
|
||||||
|
log.msg("_decode_all_ordered")
|
||||||
# can we decode using all of the shares?
|
# can we decode using all of the shares?
|
||||||
return _decode(self.shares)
|
return _decode(self.shares)
|
||||||
d.addCallback(_decode_all_ordered)
|
d.addCallback(_decode_all_ordered)
|
||||||
d.addCallback(_check_data)
|
d.addCallback(_check_data)
|
||||||
|
|
||||||
def _decode_all_shuffled(res):
|
def _decode_all_shuffled(res):
|
||||||
|
log.msg("_decode_all_shuffled")
|
||||||
# can we decode, using all the shares, but in random order?
|
# can we decode, using all the shares, but in random order?
|
||||||
shuffled_shares = self.shares[:]
|
shuffled_shares = self.shares[:]
|
||||||
random.shuffle(shuffled_shares)
|
random.shuffle(shuffled_shares)
|
||||||
return _decode(shuffled_shares)
|
return _decode(shuffled_shares)
|
||||||
d.addCallback(_decode_all_shuffled)
|
d.addCallback(_decode_all_shuffled)
|
||||||
d.addCallback(_check_data)
|
d.addCallback(_check_data)
|
||||||
|
|
||||||
def _decode_some(res):
|
def _decode_some(res):
|
||||||
|
log.msg("_decode_some")
|
||||||
# decode with a minimal subset of the shares
|
# decode with a minimal subset of the shares
|
||||||
some_shares = self.shares[:required_shares]
|
some_shares = self.shares[:required_shares]
|
||||||
return _decode(some_shares)
|
return _decode(some_shares)
|
||||||
@ -52,6 +57,7 @@ class Tester:
|
|||||||
d.addCallback(_check_data)
|
d.addCallback(_check_data)
|
||||||
|
|
||||||
def _decode_some_random(res):
|
def _decode_some_random(res):
|
||||||
|
log.msg("_decode_some_random")
|
||||||
# use a randomly-selected minimal subset
|
# use a randomly-selected minimal subset
|
||||||
some_shares = random.sample(self.shares, required_shares)
|
some_shares = random.sample(self.shares, required_shares)
|
||||||
return _decode(some_shares)
|
return _decode(some_shares)
|
||||||
@ -59,6 +65,7 @@ class Tester:
|
|||||||
d.addCallback(_check_data)
|
d.addCallback(_check_data)
|
||||||
|
|
||||||
def _decode_multiple(res):
|
def _decode_multiple(res):
|
||||||
|
log.msg("_decode_multiple")
|
||||||
# make sure we can re-use the decoder object
|
# make sure we can re-use the decoder object
|
||||||
shares1 = random.sample(self.shares, required_shares)
|
shares1 = random.sample(self.shares, required_shares)
|
||||||
shares2 = random.sample(self.shares, required_shares)
|
shares2 = random.sample(self.shares, required_shares)
|
||||||
@ -79,6 +86,9 @@ class Tester:
|
|||||||
def test_encode1(self):
|
def test_encode1(self):
|
||||||
return self.do_test(8, 8, 16)
|
return self.do_test(8, 8, 16)
|
||||||
|
|
||||||
|
def test_encode2(self):
|
||||||
|
return self.do_test(123, 25, 100)
|
||||||
|
|
||||||
def test_sizes(self):
|
def test_sizes(self):
|
||||||
raise unittest.SkipTest("omg this would take forever")
|
raise unittest.SkipTest("omg this would take forever")
|
||||||
d = defer.succeed(None)
|
d = defer.succeed(None)
|
||||||
|
Loading…
Reference in New Issue
Block a user