@Test
  public void testTooManyPackets() {

    byte[] segment = new byte[20000];

    new Random().nextBytes(segment);

    Decoder decoder = createDecoder(segment.length, 20);

    Encoder encoder = createEncoder(segment, 0, segment.length, 20);

    while (!decoder.isDecoded()) {
      byte[] packet = new byte[20 + segment.length / 20];

      encoder.getPacket(packet, 0);

      decoder.addPacket(packet, 0);
    }

    for (int i = 0; i < 1000; i++) {
      byte[] packet = new byte[20 + segment.length / 20];

      encoder.getPacket(packet, 0);

      decoder.addPacket(packet, 0);
    }
  }
  @Test
  public void testLinearDependance() {

    byte[] segment = new byte[1000];

    new Random().nextBytes(segment);

    Decoder decoder = createDecoder(segment.length, 10);

    byte[] packet = new byte[10 + segment.length / 10];

    Encoder encoder = createEncoder(segment, 0, segment.length, 10);

    encoder.getPacket(packet, 0);

    decoder.addPacket(packet, 0);

    decoder.addPacket(packet, 0);

    assertEquals(1, decoder.getRank());

    while (!decoder.isDecoded()) {
      byte[] packet2 = new byte[10 + segment.length / 10];

      encoder.getPacket(packet2, 0);

      decoder.addPacket(packet2, 0);
    }

    byte[] decodedSegment = new byte[segment.length];

    decoder.getSegment(decodedSegment, 0);

    assertArrayEquals(segment, decodedSegment);
  }
  @Test
  public void test() {

    byte[] segment = new byte[20000];

    new Random().nextBytes(segment);

    Decoder decoder = createDecoder(segment.length, 20);

    Encoder encoder = createEncoder(segment, 0, segment.length, 20);

    while (!decoder.isDecoded()) {
      byte[] packet = new byte[20 + segment.length / 20];

      encoder.getPacket(packet, 0);

      decoder.addPacket(packet, 0);
    }

    byte[] decodedSegment = new byte[segment.length];

    decoder.getSegment(decodedSegment, 0);

    assertArrayEquals(segment, decodedSegment);
  }
  @Test
  public void testGB() {

    byte[] segment = new byte[22500];

    new Random().nextBytes(segment);

    byte[][] packets = new byte[25][25 + 900];

    long startTime = System.currentTimeMillis();

    Encoder encoder = createEncoder(segment, 0, segment.length, 25);

    for (int i = 0; i < 1000; i++) {

      for (int j = 0; j < 25; j++) {
        encoder.getPacket(packets[j], 0);
      }
    }

    System.out.println(
        "Rate:"
            + (8 * 1000.0 * segment.length) / (double) (System.currentTimeMillis() - startTime)
            + " kbps");

    startTime = System.currentTimeMillis();

    for (int i = 0; i < 1000; i++) {
      Decoder decoder = createDecoder(segment.length, 25);

      for (int j = 0; j < 25; j++) {
        decoder.addPacket(packets[j], 0);
      }

      byte[] decodedSegment = new byte[segment.length];

      decoder.getSegment(decodedSegment, 0);
    }

    System.out.println(
        "Rate:"
            + (8 * 1000.0 * segment.length) / (double) (System.currentTimeMillis() - startTime)
            + " kbps");
  }
  @Test
  public void testOnlineCoding() {

    byte[] segment = new byte[1000];

    new Random().nextBytes(segment);

    Decoder decoder = createDecoder(segment.length, 20);

    Decoder decoder2 = createDecoder(segment.length, 20);

    Encoder encoder = createEncoder(segment, 0, segment.length, 20);

    while (!decoder.isDecoded()) {

      byte[] packet = new byte[segment.length / 20 + 20];

      encoder.getPacket(packet, 0);

      int prevRank = decoder.getRank();

      decoder.addPacket(packet, 0);

      if (prevRank < decoder.getRank()) {
        prevRank = decoder2.getRank();
        while (decoder2.getRank() == prevRank) {
          byte[] packet2 = new byte[segment.length / 20 + 20];
          decoder.getPacket(packet2, 0);
          decoder2.addPacket(packet2, 0);
        }
      }
    }

    byte[] segmentDecoded = new byte[segment.length];

    decoder.getSegment(segmentDecoded, 0);
    assertArrayEquals(segment, segmentDecoded);

    decoder2.getSegment(segmentDecoded, 0);
    assertArrayEquals(segment, segmentDecoded);
  }