示例#1
0
 public void testPurge3() {
   Table<Integer> table = new Table<Integer>(3, 10, 0);
   for (int i = 1; i <= 100; i++) table.add(i, i);
   System.out.println("table = " + table);
   table.removeMany(true, 53);
   for (int i = 54; i <= 100; i++) assert table.get(i) == i;
 }
示例#2
0
 public void testAdd() {
   Table<Integer> buf = new Table<Integer>(3, 10, 0);
   buf.add(1, 322649);
   buf.add(2, 100000);
   System.out.println("buf = " + buf);
   assert buf.size() == 2;
 }
示例#3
0
  protected void handleAckReceived(Address sender, long seqno, short conn_id) {
    if (log.isTraceEnabled())
      log.trace(
          new StringBuilder()
              .append(local_addr)
              .append(" <-- ACK(")
              .append(sender)
              .append(": #")
              .append(seqno)
              .append(", conn-id=")
              .append(conn_id)
              .append(')'));
    SenderEntry entry = send_table.get(sender);

    if (entry != null && entry.send_conn_id != conn_id) {
      if (log.isTraceEnabled())
        log.trace(
            local_addr
                + ": my conn_id ("
                + entry.send_conn_id
                + ") != received conn_id ("
                + conn_id
                + "); discarding ACK");
      return;
    }

    Table<Message> win = entry != null ? entry.sent_msgs : null;
    if (win != null) {
      win.purge(seqno, true); // removes all messages <= seqno (forced purge)
      num_acks_received++;
    }
  }
示例#4
0
  /**
   * Runs NUM adder threads, each adder adds 1 (unique) seqno. When all adders are done, we should
   * have NUM elements in the table.
   */
  public void testConcurrentAdd() {
    final int NUM = 100;
    final Table<Integer> buf = new Table<Integer>(3, 10, 0);

    CountDownLatch latch = new CountDownLatch(1);
    Adder[] adders = new Adder[NUM];
    for (int i = 0; i < adders.length; i++) {
      adders[i] = new Adder(latch, i + 1, buf);
      adders[i].start();
    }

    System.out.println("starting threads");
    latch.countDown();
    System.out.print("waiting for threads to be done: ");
    for (Adder adder : adders) {
      try {
        adder.join();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    System.out.println("OK");
    System.out.println("buf = " + buf);
    assert buf.size() == NUM;
  }
示例#5
0
  @ManagedOperation(
      description =
          "Sends a STABLE message to all senders. This causes message purging and potential"
              + " retransmissions from senders")
  public void sendStableMessages() {
    for (Map.Entry<Address, ReceiverEntry> entry : recv_table.entrySet()) {
      Address dest = entry.getKey();
      ReceiverEntry val = entry.getValue();
      Table<Message> win = val != null ? val.received_msgs : null;
      if (win != null) {
        long[] tmp = win.getDigest();
        long low = tmp[0], high = tmp[1];

        if (val.last_highest == high) {
          if (val.num_stable_msgs >= max_stable_msgs) {
            continue;
          } else val.num_stable_msgs++;
        } else {
          val.last_highest = high;
          val.num_stable_msgs = 1;
        }
        sendStableMessage(dest, val.recv_conn_id, low, high);
      }
    }
  }
示例#6
0
  public static void testForEach() {
    class MyVisitor<T> implements Table.Visitor<T> {
      List<int[]> list = new ArrayList<int[]>(20);

      public boolean visit(long seqno, T element, int row, int column) {
        System.out.println("#" + seqno + ": " + element + ", row=" + row + ", column=" + column);
        list.add(new int[] {row, column});
        return true;
      }
    }
    MyVisitor<Integer> visitor = new MyVisitor<Integer>();

    Table<Integer> table = new Table<Integer>(3, 10, 0);
    for (int i = 1; i <= 20; i++) table.add(i, i);
    System.out.println("table = " + table);
    table.forEach(table.getLow() + 1, table.getHighestReceived() - 1, visitor);
    int count = 1;
    for (int[] pair : visitor.list) {
      int row = pair[0], column = pair[1];
      if (count < Util.getNextHigherPowerOfTwo(10)) {
        assert row == 0;
        assert column == count;
      } else {
        assert row == 1;
        assert column == count - Util.getNextHigherPowerOfTwo(10);
      }
      count++;
    }
  }
示例#7
0
  /**
   * We need to resend our first message with our conn_id
   *
   * @param sender
   * @param seqno Resend the non null messages in the range [lowest .. seqno]
   */
  protected void handleResendingOfFirstMessage(Address sender, long seqno) {
    if (log.isTraceEnabled())
      log.trace(local_addr + " <-- SEND_FIRST_SEQNO(" + sender + "," + seqno + ")");
    SenderEntry entry = send_table.get(sender);
    Table<Message> win = entry != null ? entry.sent_msgs : null;
    if (win == null) {
      if (log.isErrorEnabled())
        log.error(local_addr + ": sender window for " + sender + " not found");
      return;
    }

    boolean first_sent = false;
    for (long i = win.getLow() + 1; i <= seqno; i++) {
      Message rsp = win.get(i);
      if (rsp == null) continue;
      if (first_sent) {
        down_prot.down(new Event(Event.MSG, rsp));
      } else {
        first_sent = true;
        // We need to copy the UnicastHeader and put it back into the message because Message.copy()
        // doesn't copy
        // the headers and therefore we'd modify the original message in the sender retransmission
        // window
        // (https://jira.jboss.org/jira/browse/JGRP-965)
        Message copy = rsp.copy();
        Unicast2Header hdr = (Unicast2Header) copy.getHeader(this.id);
        Unicast2Header newhdr = hdr.copy();
        newhdr.first = true;
        copy.putHeader(this.id, newhdr);
        down_prot.down(new Event(Event.MSG, copy));
      }
    }
  }
示例#8
0
 public void testAddList() {
   Table<Integer> buf = new Table<Integer>(3, 10, 0);
   List<Tuple<Long, Integer>> msgs = createList(1, 2);
   boolean rc = buf.add(msgs);
   System.out.println("buf = " + buf);
   assert rc;
   assert buf.size() == 2;
 }
示例#9
0
 public static void testDuplicateAddition() {
   Table<Integer> table = new Table<Integer>(3, 10, 0);
   addAndGet(table, 1, 5, 9, 10);
   assert !table.add(5, 5);
   assert table.get(5) == 5;
   assert table.size() == 4;
   assertIndices(table, 0, 0, 10);
 }
示例#10
0
 public static void testCreation() {
   Table<Integer> table = new Table<Integer>(3, 10, 0);
   System.out.println("table = " + table);
   int size = table.size();
   assert size == 0;
   assert table.get(15) == null;
   assertIndices(table, 0, 0, 0);
 }
示例#11
0
 public static void testAdditionWithOffset() {
   Table<Integer> table = new Table<Integer>(3, 10, 100);
   addAndGet(table, 101, 105, 109, 110, 111, 119, 120, 129);
   System.out.println("table: " + table.dump());
   assert table.size() == 8;
   assertCapacity(table.capacity(), 3, 10);
   assertIndices(table, 100, 100, 129);
 }
示例#12
0
 protected static void addAndGet(Table<Integer> table, int... seqnos) {
   for (int seqno : seqnos) {
     boolean added = table.add((long) seqno, seqno);
     assert added;
     Integer val = table.get(seqno);
     assert val != null && val == seqno;
   }
 }
示例#13
0
  public void testAddWithInvalidSeqno() {
    Table<Integer> buf = new Table<Integer>(3, 10, 20);
    boolean success = buf.add(10, 0);
    assert !success;

    success = buf.add(20, 0);
    assert !success;
    assert buf.isEmpty();
  }
示例#14
0
 public static void testAdditionWithOffset2() {
   Table<Integer> table = new Table<Integer>(3, 10, 2);
   addAndGet(table, 1000, 1001);
   table.compact();
   addAndGet(table, 1005, 1009, 1010, 1011, 1019, 1020, 1029);
   System.out.println("table: " + table.dump());
   assert table.size() == 9;
   assertIndices(table, 2, 2, 1029);
 }
示例#15
0
 public void testGet() {
   final Table<Integer> buf = new Table<Integer>(3, 10, 0);
   for (int i : Arrays.asList(1, 2, 3, 4, 5)) buf.add(i, i);
   assert buf.get(0) == null;
   assert buf.get(1) == 1;
   assert buf.get(10) == null;
   assert buf.get(5) == 5;
   assert buf.get(6) == null;
 }
示例#16
0
 public static void testGetMissingFirst() {
   Table<Integer> table = new Table<Integer>(3, 10, 0);
   for (int num : Arrays.asList(2, 3, 4, 5)) table.add(num, num);
   System.out.println("table = " + table);
   SeqnoList missing = table.getMissing();
   System.out.println("missing=" + missing);
   assert missing.size() == 1;
   assert table.getNumMissing() == 1;
 }
示例#17
0
 public static void testMove3() {
   Table<Integer> table = new Table<Integer>(3, 10, 0);
   for (int i = 1; i < 30; i++) table.add(i, i);
   table.removeMany(true, 23);
   System.out.println("table = " + table);
   table.add(30, 30); // triggers a resize() --> move()
   for (int i = 1; i <= 23; i++) assert table._get(i) == null;
   for (int i = 24; i < 30; i++) assert table._get(i) != null;
 }
示例#18
0
 public void removeReceiveConnection(Address mbr) {
   ReceiverEntry entry2 = recv_table.remove(mbr);
   if (entry2 != null) {
     Table<Message> win = entry2.received_msgs;
     if (win != null)
       sendStableMessage(
           mbr, entry2.recv_conn_id, win.getHighestDelivered(), win.getHighestReceived());
     entry2.reset();
   }
 }
示例#19
0
 public static void testAddListWithResizing2() {
   Table<Integer> table = new Table<Integer>(3, 500, 0);
   List<Tuple<Long, Integer>> msgs = new ArrayList<Tuple<Long, Integer>>();
   for (int i = 1; i < 100; i++) msgs.add(new Tuple<Long, Integer>((long) i, i));
   table.add(msgs, false);
   System.out.println("table = " + table);
   int num_resizes = table.getNumResizes();
   System.out.println("num_resizes = " + num_resizes);
   assert num_resizes == 0 : "number of resizings=" + num_resizes + " (expected 0)";
 }
示例#20
0
 @ManagedOperation(description = "Prints the contents of the send windows for all members")
 public String printSendWindowMessages() {
   StringBuilder ret = new StringBuilder(local_addr + ":\n");
   for (Map.Entry<Address, SenderEntry> entry : send_table.entrySet()) {
     Address addr = entry.getKey();
     Table<Message> buf = entry.getValue().sent_msgs;
     ret.append(addr).append(": ").append(buf.toString()).append('\n');
   }
   return ret.toString();
 }
示例#21
0
 public void run() {
   for (Map.Entry<Address, ReceiverEntry> entry : recv_table.entrySet()) {
     Address target = entry.getKey(); // target to send retransmit requests to
     ReceiverEntry val = entry.getValue();
     Table<Message> buf = val != null ? val.received_msgs : null;
     if (buf != null && buf.getNumMissing() > 0) {
       SeqnoList missing = buf.getMissing();
       if (missing != null) retransmit(missing, target);
     }
   }
 }
示例#22
0
 public void testGetMissing4() {
   Table<Integer> buf = new Table<Integer>(3, 30, 0);
   for (int i : Arrays.asList(2, 5, 10, 11, 12, 13, 15, 20, 28, 30)) buf.add(i, i);
   System.out.println("buf = " + buf);
   int missing = buf.getNumMissing();
   assert missing == 20;
   System.out.println("missing=" + missing);
   SeqnoList missing_list = buf.getMissing();
   System.out.println("missing_list = " + missing_list);
   assert missing_list.size() == missing;
 }
示例#23
0
  /**
   * Check whether the hashtable contains an entry e for <code>sender</code> (create if not). If
   * e.received_msgs is null and <code>first</code> is true: create a new AckReceiverWindow(seqno)
   * and add message. Set e.received_msgs to the new window. Else just add the message.
   */
  protected void handleDataReceived(
      Address sender, long seqno, short conn_id, boolean first, Message msg, Event evt) {
    if (log.isTraceEnabled()) {
      StringBuilder sb = new StringBuilder();
      sb.append(local_addr).append(" <-- DATA(").append(sender).append(": #").append(seqno);
      if (conn_id != 0) sb.append(", conn_id=").append(conn_id);
      if (first) sb.append(", first");
      sb.append(')');
      log.trace(sb);
    }

    ReceiverEntry entry = getReceiverEntry(sender, seqno, first, conn_id);
    if (entry == null) return;
    if (conn_expiry_timeout > 0) entry.update();
    Table<Message> win = entry.received_msgs;
    boolean added = win.add(seqno, msg); // win is guaranteed to be non-null if we get here
    num_msgs_received++;

    // An OOB message is passed up immediately. Later, when remove() is called, we discard it. This
    // affects ordering !
    // http://jira.jboss.com/jira/browse/JGRP-377
    if (msg.isFlagSet(Message.OOB) && added) {
      try {
        up_prot.up(evt);
      } catch (Throwable t) {
        log.error("couldn't deliver OOB message " + msg, t);
      }
    }

    final AtomicBoolean processing = win.getProcessing();
    if (!processing.compareAndSet(false, true)) {
      return;
    }

    // try to remove (from the AckReceiverWindow) as many messages as possible as pass them up

    // Prevents concurrent passing up of messages by different threads
    // (http://jira.jboss.com/jira/browse/JGRP-198);
    // this is all the more important once we have a concurrent stack
    // (http://jira.jboss.com/jira/browse/JGRP-181),
    // where lots of threads can come up to this point concurrently, but only 1 is allowed to pass
    // at a time
    // We *can* deliver messages from *different* senders concurrently, e.g. reception of P1, Q1,
    // P2, Q2 can result in
    // delivery of P1, Q1, Q2, P2: FIFO (implemented by UNICAST) says messages need to be delivered
    // only in the
    // order in which they were sent by their senders
    int num_msgs = removeAndDeliver(processing, win);
    if (num_msgs > 0) {
      long hd = win.getHighestDelivered();
      sendAck(sender, hd);
    }
  }
示例#24
0
 public static void testRemoveMany() {
   Table<Integer> table = new Table<Integer>(3, 10, 0);
   for (int seqno : Arrays.asList(1, 2, 3, 4, 5, 7, 8, 9, 10)) table.add(seqno, seqno);
   System.out.println("table = " + table);
   assertIndices(table, 0, 0, 10);
   List<Integer> list = table.removeMany(true, 4);
   System.out.println("list=" + list + ", table=" + table);
   assert table.size() == 5 && table.getNumMissing() == 1;
   assert list != null && list.size() == 4;
   for (int num : Arrays.asList(1, 2, 3, 4)) assert list.contains(num);
   assertIndices(table, 4, 4, 10);
 }
示例#25
0
  protected void handleBatchReceived(Address sender, Map<Short, List<Message>> map) {
    for (Map.Entry<Short, List<Message>> element : map.entrySet()) {
      final List<Message> msg_list = element.getValue();
      if (log.isTraceEnabled()) {
        StringBuilder sb = new StringBuilder();
        sb.append(local_addr)
            .append(" <-- DATA(")
            .append(sender)
            .append(": " + printMessageList(msg_list))
            .append(')');
        log.trace(sb);
      }

      short conn_id = element.getKey();
      ReceiverEntry entry = null;
      for (Message msg : msg_list) {
        UnicastHeader hdr = (UnicastHeader) msg.getHeader(id);
        entry = getReceiverEntry(sender, hdr.seqno, hdr.first, conn_id);
        if (entry == null) continue;
        Table<Message> win = entry.received_msgs;
        boolean msg_added =
            win.add(hdr.seqno, msg); // win is guaranteed to be non-null if we get here
        num_msgs_received++;

        if (hdr.first && msg_added)
          sendAck(
              sender, hdr.seqno,
              conn_id); // send an ack immediately when we received the first message of a conn

        // An OOB message is passed up immediately. Later, when remove() is called, we discard it.
        // This affects ordering !
        // http://jira.jboss.com/jira/browse/JGRP-377
        if (msg.isFlagSet(Message.Flag.OOB) && msg_added) {
          try {
            up_prot.up(new Event(Event.MSG, msg));
          } catch (Throwable t) {
            log.error("couldn't deliver OOB message " + msg, t);
          }
        }
      }
      if (entry != null && conn_expiry_timeout > 0) entry.update();
    }

    ReceiverEntry entry = recv_table.get(sender);
    Table<Message> win = entry != null ? entry.received_msgs : null;
    if (win != null) {
      final AtomicBoolean processing = win.getProcessing();
      if (processing.compareAndSet(false, true)) {
        removeAndDeliver(processing, win, sender);
        sendAck(sender, win.getHighestDeliverable(), entry.recv_conn_id);
      }
    }
  }
示例#26
0
 public void run() {
   for (SenderEntry val : send_table.values()) {
     Table<Message> buf = val != null ? val.sent_msgs : null;
     if (buf != null && !buf.isEmpty()) {
       long from = buf.getHighestDelivered() + 1, to = buf.getHighestReceived();
       List<Message> list = buf.get(from, to);
       if (list != null) {
         for (Message msg : list) retransmit(msg);
       }
     }
   }
 }
示例#27
0
 public static void testRemoveManyWithWrapping2() {
   Table<Integer> table = new Table<Integer>(3, 10, 0);
   for (int seqno : Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 17, 18, 19, 20))
     table.add(seqno, seqno);
   System.out.println("table = " + table);
   assertIndices(table, 0, 0, 20);
   assert table.size() == 18 && table.getNumMissing() == 2;
   List<Integer> list = table.removeMany(false, 0);
   assert list.size() == 12;
   assertIndices(table, 0, 12, 20);
   assert table.size() == 6 && table.getNumMissing() == 2;
   table.purge(12);
   assertIndices(table, 12, 12, 20);
   assert table.size() == 6 && table.getNumMissing() == 2;
 }
示例#28
0
  public static void testResize() {
    Table<Integer> table = new Table<Integer>(3, 10, 0);
    assertCapacity(table.capacity(), table.getNumRows(), 10);
    addAndGet(table, 30);
    addAndGet(table, 35);
    assertCapacity(table.capacity(), table.getNumRows(), 10);
    addAndGet(table, 500);
    assertCapacity(table.capacity(), table.getNumRows(), 10);

    addAndGet(table, 515);
    assertCapacity(table.capacity(), table.getNumRows(), 10);
  }
示例#29
0
  public void testResizeWithPurge() {
    Table<Integer> table = new Table<Integer>(3, 10, 0);
    for (int i = 1; i <= 100; i++) addAndGet(table, i);
    System.out.println("table: " + table);

    // now remove 60 messages
    for (int i = 1; i <= 60; i++) {
      Integer num = table.remove();
      assert num != null && num == i;
    }
    System.out.println("table after removal of seqno 60: " + table);

    table.purge(50);
    System.out.println("now triggering a resize() by addition of seqno=120");
    addAndGet(table, 120);
  }
示例#30
0
  public void testGetList() {
    final Table<Integer> buf = new Table<Integer>(3, 10, 0);
    for (int i : Arrays.asList(1, 2, 3, 4, 5)) buf.add(i, i);
    List<Integer> elements = buf.get(3, 5);
    System.out.println("elements = " + elements);
    assert elements != null && elements.size() == 3;
    assert elements.contains(3) && elements.contains(4) && elements.contains(5);

    elements = buf.get(4, 10);
    System.out.println("elements = " + elements);
    assert elements != null && elements.size() == 2;
    assert elements.contains(4) && elements.contains(5);

    elements = buf.get(10, 20);
    assert elements == null;
  }