All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jgroups.BatchMessage Maven / Gradle / Ivy


package org.jgroups;


import org.jgroups.util.ByteArray;
import org.jgroups.util.Util;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.function.Supplier;

/**
 * A message that contains a batch of messages for use with BATCH protocol.  This message will wrap several
 * sequential messages so lower protocol layers only have to process them once.  This increases throughput for cases
 * such as when average message size is small, or there is a heavy processing cost (e.g. SEQUENCER).
 * 
* Similar to CompositeMessage but with some optimisations made for the specific use case. *
* This class is unsynchronized; the envisaged use case is that an BatchMessage is created with a number of messages, * or messages are added, but then the instance is not modified anymore and sent. * @author Bela Ban, Chris Johnson * @since 5.x */ public class BatchMessage extends BaseMessage implements Iterable { protected Message[] msgs; protected int index; // index of the next message to be added protected Address orig_src; protected static final MessageFactory mf=new DefaultMessageFactory(); public BatchMessage() { } public BatchMessage(Address dest, int capacity) { super(dest); msgs=new Message[capacity]; } public BatchMessage(Address dest, Address src, Message[] msgs, int index) { super(dest); this.orig_src = src; this.msgs = msgs; this.index = index; } public Supplier create() {return BatchMessage::new;} public short getType() {return Message.EARLYBATCH_MSG;} public boolean hasPayload() {return msgs != null && index > 0;} public boolean hasArray() {return false;} public int getNumberOfMessages() {return index;} public int getOffset() {throw new UnsupportedOperationException();} public byte[] getArray() {throw new UnsupportedOperationException();} public BatchMessage setArray(byte[] b, int o, int l) {throw new UnsupportedOperationException();} public BatchMessage setArray(ByteArray buf) {throw new UnsupportedOperationException();} public BatchMessage setObject(Object obj) {throw new UnsupportedOperationException();} public T getObject() {throw new UnsupportedOperationException();} public Message[] getMessages() {return msgs;} public Address getOrigSender() {return orig_src;} public BatchMessage setOrigSender(Address s) {orig_src=s; return this;} public int getLength() { int total=0; for(int i=0; i < index && msgs != null; i++) total+=msgs[i].getLength(); return total; } /** Adds the message at the end of the array. Increases the array if needed */ public BatchMessage add(Message msg) { ensureSameDest(msg); ensureCapacity(index); msgs[index++]=Objects.requireNonNull(msg); return this; } public BatchMessage add(Message ... messages) { ensureCapacity(index + messages.length); for(Message msg: messages) { if (msg == null) break; msgs[index++] = Objects.requireNonNull(ensureSameDest(msg)); } return this; } public T get(int index) { return (T)msgs[index]; } /** Create a shallow copy of this {@link BatchMessage}. */ public BatchMessage copy(boolean copy_payload, boolean copy_headers) { BatchMessage retval=(BatchMessage)super.copy(copy_payload, copy_headers); if(copy_payload && msgs != null) { Message[] copy=new Message[msgs.length]; for(int i=0; i < msgs.length; i++) { if(msgs[i] != null) copy[i]=msgs[i]; } retval.msgs=copy; retval.index=index; retval.orig_src=orig_src; } return retval; } public String toString() { return String.format("%s, %d message(s)", super.toString(), getNumberOfMessages()); } public int size() { int retval=super.size() + Global.INT_SIZE + orig_src.serializedSize(); // length + src if(msgs != null) { for(int i=0; i < index; i++) retval+=msgs[i].size() + Global.SHORT_SIZE; // type } return retval; } public Iterator iterator() { return new BatchMessageIterator(); } public void writePayload(DataOutput out) throws IOException { out.writeInt(index); Util.writeAddress(orig_src, out); if(msgs != null) { for(int i=0; i < index; i++) { Message msg=msgs[i]; out.writeShort(msg.getType()); msg.writeToNoAddrs(this.src(), out); } } } public void readPayload(DataInput in) throws IOException, ClassNotFoundException { index=in.readInt(); orig_src=Util.readAddress(in); if(index > 0) { msgs=new Message[index]; // a bit of additional space should we add byte arrays for(int i=0; i < index; i++) { short type=in.readShort(); msgs[i]=mf.create(type).setDest(dest()).setSrc(orig_src); msgs[i].readFrom(in); } } } /* --------------------------------- End of Interface Streamable ----------------------------- */ protected void ensureCapacity(int size) { if(msgs == null) msgs=new Message[size+1]; else if(size >= msgs.length) msgs=Arrays.copyOf(msgs, size+1); } protected Message ensureSameDest(Message msg) { if(!Objects.equals(dest, msg.dest())) throw new IllegalStateException(String.format("message dest (%s) does not match dest of BatchMessage (%s)", msg.dest(), dest)); return msg; } protected class BatchMessageIterator implements Iterator { protected int current_index; public boolean hasNext() { return current_index < index; } public Message next() { if(current_index >= msgs.length) throw new NoSuchElementException(); return msgs[current_index++]; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy