package freenet.client; import freenet.client.InsertContext.CompatibilityMode; import freenet.client.Metadata.SplitfileAlgorithm; /** Simple in-memory-only API for FEC encoding/decoding. Does not queue or throttle; see * MemoryLimitedJobRunner for how to deal with that. Caches and creates individual codec engines * as needed. */ public abstract class FECCodec { public static final long MIN_MEMORY_ALLOCATION = 8*1024*1024+256*1024; public static final int MAX_TOTAL_BLOCKS_PER_SEGMENT = 256; /** Maximum memory usage with the given number of data blocks and check blocks, not including * the blocks themselves. */ public abstract long maxMemoryOverheadDecode(int dataBlocks, int checkBlocks); /** Maximum memory usage with the given number of data blocks and check blocks, not including * the blocks themselves. */ public abstract long maxMemoryOverheadEncode(int dataBlocks, int checkBlocks); /** Execute a FEC decode. On exiting the function we will have all the data blocks. * @param dataBlocks The byte[]'s for storing the data blocks. Must all be non-null. Which * have valid contents is indicated by dataBlocksPresent. When exit this function, they will * be filled with the data blocks in the correct order. * @param checkBlocks The byte[]'s for storing the check blocks. Which have valid contents is * indicated by checkBlocksPresent. * @param dataBlocksPresent Indicates which data blocks were present before decoding. (Will * not be changed by this function). * @param checkBlocksPresent Indicates which check blocks are present before decoding. (Will * not be changed by this function). * @param blockLength The length of any and all blocks. Padding must be handled by the caller * if it is necessary. */ public abstract void decode(byte[][] dataBlocks, byte[][] checkBlocks, boolean[] dataBlocksPresent, boolean[] checkBlocksPresent, int blockLength); /** Execute a FEC encode. On entering, we must have all the data blocks. On exiting, we will * have all the check blocks as well. * @param dataBlocks All the data blocks, which all have valid contents. * @param checkBlocks The byte[]'s for storing the encoded check blocks. Must all be non-null. * @param checkBlocksPresent Indicates which check blocks have already been encoded. */ public abstract void encode(byte[][] dataBlocks, byte[][] checkBlocks, boolean[] checkBlocksPresent, int blockLength); public static FECCodec getInstance(SplitfileAlgorithm splitfileType) { switch(splitfileType) { case NONREDUNDANT: return null; case ONION_STANDARD: return new OnionFECCodec(); default: throw new IllegalArgumentException(); } } /** Get the recommended number of check blocks per segment for a given number of data blocks * for a given compatibility mode. * @param dataBlocks The number of data blocks per segment. * @param cmode The compatibility mode (so we can exactly mimic the behaviour of older builds * when reinserting files). */ public abstract int getCheckBlocks(int dataBlocks, CompatibilityMode cmode); }