/** * Creates a new entry if not yet present. Adds the fragment. If all fragements for a given * message have been received, an entire message is reassembled and returned. Otherwise null is * returned. * * @param id - the message ID, unique for a sender * @param frag_id the index of this fragmentation (0..tot_frags-1) * @param tot_frags the total number of fragmentations expected * @param fragment - the byte buffer for this fragment */ public synchronized byte[] add(long id, int frag_id, int tot_frags, byte[] fragment) { byte[] retval = null; // initialize the return value to default not complete FragEntry e = table.get(id); if (e == null) { // Create new entry if not yet present e = new FragEntry(id, tot_frags); table.put(id, e); } e.set(frag_id, fragment); if (e.isComplete()) { retval = e.assembleBuffer(); table.remove(id); } return retval; }
/** * 1. Get all the fragment buffers 2. When all are received -> Assemble them into one big buffer * 3. Read headers and byte buffer from big buffer 4. Set headers and buffer in msg 5. Pass msg up * the stack */ private void unfragment(Message msg, FragHeader hdr) { Address sender = msg.getSrc(); Message assembled_msg = null; ConcurrentMap<Long, FragEntry> frag_table = fragment_list.get(sender); if (frag_table == null) { frag_table = Util.createConcurrentMap(16, .075f, 16); ConcurrentMap<Long, FragEntry> tmp = fragment_list.putIfAbsent(sender, frag_table); if (tmp != null) // value was already present frag_table = tmp; } num_received_frags.incrementAndGet(); FragEntry entry = frag_table.get(hdr.id); if (entry == null) { entry = new FragEntry(hdr.num_frags); FragEntry tmp = frag_table.putIfAbsent(hdr.id, entry); if (tmp != null) entry = tmp; } entry.lock(); try { entry.set(hdr.frag_id, msg); if (entry.isComplete()) { assembled_msg = entry.assembleMessage(); frag_table.remove(hdr.id); } } finally { entry.unlock(); } // assembled_msg=frag_table.add(hdr.id, hdr.frag_id, hdr.num_frags, msg); if (assembled_msg != null) { try { if (log.isTraceEnabled()) log.trace("assembled_msg is " + assembled_msg); assembled_msg.setSrc(sender); // needed ? YES, because fragments have a null src !! num_received_msgs.incrementAndGet(); up_prot.up(new Event(Event.MSG, assembled_msg)); } catch (Exception e) { if (log.isErrorEnabled()) log.error("unfragmentation failed", e); } } }