[Avida-SVN] r2961 - development/source/main

mmcgill at myxo.css.msu.edu mmcgill at myxo.css.msu.edu
Fri Nov 21 13:57:42 PST 2008


Author: mmcgill
Date: 2008-11-21 16:57:42 -0500 (Fri, 21 Nov 2008)
New Revision: 2961

Modified:
   development/source/main/cAvidaConfig.h
   development/source/main/cOrganism.cc
   development/source/main/cOrganism.h
Log:
Added configuration variables offering more control over
the behavior of message passing.

ORGANISMS_REMEMBER_MESSAGES
* Setting to 1 (the default) preserves the current behavior; the "sent" and
"received" message lists in each organism track every message sent or received
in that organism's lifetime.
* Setting to 0 has the effect that (a) no messages are stored in "sent", and
"received" stores only those messages that have not yet been retrieved; retrieved
messages are discarded.

MESSAGE_QUEUE_SIZE
* Setting to -1 (the default) preserves the current behavior; an unbounded
number of messages can queue up	in an organism's "received" message list.
* Setting to a non-negative value caps the number of unretrieved messages
that can queue up in an organism's "receives" list. When one organism
sends a message to another organism whose message queue is full, the
behavior is determined by the variable:

MESSAGE_QUEUE_BEHAVIOR_WHEN_FULL
* Setting to 0 (the default) causes incoming messages to be dropped when
an organism's message queue is full.
* Setting to 1 causes the oldest unretrieved message to be dropped and the
incoming message placed at the end of the message queue, when a message
is received and the message queue is full.


Modified: development/source/main/cAvidaConfig.h
===================================================================
--- development/source/main/cAvidaConfig.h	2008-11-21 21:45:48 UTC (rev 2960)
+++ development/source/main/cAvidaConfig.h	2008-11-21 21:57:42 UTC (rev 2961)
@@ -469,6 +469,9 @@
   CONFIG_ADD_GROUP(ORGANISM_MESSAGING_GROUP, "Organism Message-Based Communication");
   CONFIG_ADD_VAR(MESSAGE_TYPE, int, 0, "Messaging Style. 0=Receiver Facing, 1=Broadcast");
   CONFIG_ADD_VAR(MESSAGE_BCAST_RADIUS, int, 1, "Broadcast message radius (cells)");
+  CONFIG_ADD_VAR(ORGANISMS_REMEMBER_MESSAGES, bool, 1, "Does an organism remember all messages it has sent or received? 0=false, 1=true (default)");
+  CONFIG_ADD_VAR(MESSAGE_QUEUE_SIZE, int, -1, "Maximum number of unretrieved messages an organism can store (-1 for no limit is the default)");
+  CONFIG_ADD_VAR(MESSAGE_QUEUE_BEHAVIOR_WHEN_FULL, int, 0, "0 = Drop incoming message (default), 1 = Drop oldest unretrieved message");
 
   CONFIG_ADD_GROUP(BUY_SELL_GROUP, "Buying and Selling Parameters");
   CONFIG_ADD_VAR(SAVE_RECEIVED, bool, 0, "Enable storage of all inputs bought from other orgs");

Modified: development/source/main/cOrganism.cc
===================================================================
--- development/source/main/cOrganism.cc	2008-11-21 21:45:48 UTC (rev 2960)
+++ development/source/main/cOrganism.cc	2008-11-21 21:57:42 UTC (rev 2961)
@@ -711,16 +711,19 @@
 	m_interface->GetDeme()->IncMessageSent();
   // If we're able to succesfully send the message...
   if(m_interface->SendMessage(msg)) {
-    // save it...
-    m_msg->sent.push_back(msg);
+    // If we're remembering messages
+    if (m_world->GetConfig().ORGANISMS_REMEMBER_MESSAGES.Get()) {
+      // save it...
+      m_msg->sent.push_back(msg);
+      // and set the receiver-pointer of this message to NULL.  We don't want to
+      // walk this list later thinking that the receivers are still around.
+      m_msg->sent.back().SetReceiver(0);
+    }
     // stat-tracking...
     m_world->GetStats().SentMessage(msg);
 		m_interface->GetDeme()->MessageSuccessfullySent();
     // check to see if we've performed any tasks...
     DoOutput(ctx);
-    // and set the receiver-pointer of this message to NULL.  We don't want to
-    // walk this list later thinking that the receivers are still around.
-    m_msg->sent.back().SetReceiver(0);
     return true;
   }
 	m_interface->GetDeme()->messageSendFailed();
@@ -736,12 +739,14 @@
  
   // If we're able to succesfully send the message...
   if(m_interface->BroadcastMessage(msg)) {
-    // save it...
-    m_msg->sent.push_back(msg);
-    // and set the receiver-pointer of this message to NULL.  We don't want to
-    // walk this list later thinking that the receivers are still around.
-    // Also, a broadcast message may have >1 receiver
-    m_msg->sent.back().SetReceiver(0);
+    // If we're remembering messages
+    if (m_world->GetConfig().ORGANISMS_REMEMBER_MESSAGES.Get()) {
+      // save it...
+      m_msg->sent.push_back(msg);
+      // and set the receiver-pointer of this message to NULL.  We don't want to
+      // walk this list later thinking that the receivers are still around.
+      m_msg->sent.back().SetReceiver(0);
+    }
     // stat-tracking...  NOTE: this has receiver not specified, so may be a problem for predicates
     m_world->GetStats().SentMessage(msg);
     // check to see if we've performed any tasks...NOTE: this has receiver not specified, so may be a problem for tasks that care
@@ -756,8 +761,42 @@
 void cOrganism::ReceiveMessage(cOrgMessage& msg)
 {
   InitMessaging();
-  msg.SetReceiver(this);    
-  m_msg->received.push_back(msg);
+  msg.SetReceiver(this);
+  int msg_queue_size = m_world->GetConfig().MESSAGE_QUEUE_SIZE.Get();
+  // are message queues unbounded?
+  if (msg_queue_size >= 0) {
+    // if the message queue size is zero, the incoming message is always dropped
+    if (msg_queue_size == 0) {
+      return;
+    }
+
+    // how many messages in the queue?
+    int num_unretrieved_msgs = m_msg->received.size()-m_msg->retrieve_index;
+    if (num_unretrieved_msgs == msg_queue_size) {
+      // look up message queue behavior
+      int bhvr = m_world->GetConfig().MESSAGE_QUEUE_BEHAVIOR_WHEN_FULL.Get();
+      if (bhvr == 0) {
+        // drop incoming message
+        return;
+      } else if (bhvr == 1 ) {
+        // drop the oldest unretrieved message
+        m_msg->received.erase(m_msg->received.begin()+m_msg->retrieve_index);
+      } else {
+        assert(false);
+        cerr << "ERROR: MESSAGE_QUEUE_BEHAVIOR_WHEN_FULL was set to " << bhvr << "," << endl;
+        cerr << "legal values are:" << endl;
+        cerr << "\t0: drop incoming message if message queue is full (default)" << endl;
+        cerr << "\t1: drop oldest unretrieved message if message queue is full" << endl;
+
+        // TODO: is there a more gracefull way to fail?
+        exit(1);
+      }
+    } // end if message queue is full
+    m_msg->received.push_back(msg);
+  } else {
+    // unbounded message queues
+    m_msg->received.push_back(msg);
+  }
 }
 
 
@@ -765,11 +804,23 @@
 {
   InitMessaging();
 
-  if(m_msg->retrieve_index < m_msg->received.size()) {
+  assert(m_msg->retrieve_index <= m_msg->received.size());
+
+  // Return null if no new messages have been received
+  if (m_msg->retrieve_index == m_msg->received.size())
+    return 0;
+
+  if (m_world->GetConfig().ORGANISMS_REMEMBER_MESSAGES.Get()) {
+    // Return the next unretrieved message and incrememt retrieve_index
     return &m_msg->received.at(m_msg->retrieve_index++);
+  } else {
+    // Not remembering messages, return the front of the message queue.
+    // Notice that retrieve_index will always equal 0 if
+    // ORGANISMS_REMEMBER_MESSAGES is false.
+    const cOrgMessage* msg = &m_msg->received.front();
+    m_msg->received.pop_front();
+    return msg;
   }
-  
-  return 0;
 }
 
 

Modified: development/source/main/cOrganism.h
===================================================================
--- development/source/main/cOrganism.h	2008-11-21 21:45:48 UTC (rev 2960)
+++ development/source/main/cOrganism.h	2008-11-21 21:57:42 UTC (rev 2961)
@@ -29,6 +29,7 @@
 #include <iostream>
 #include <string>
 #include <vector>
+#include <deque>
 
 #ifndef cCPUMemory_h
 #include "cCPUMemory.h"
@@ -349,7 +350,10 @@
 
   // -------- Messaging support --------
 public:
-  typedef std::vector<cOrgMessage> message_list_type; //!< Container-type for cOrgMessages.
+  // Use a deque instead of vector for amortized constant-time removal
+  // from the front of the list, to efficiently support message list
+  // size caps
+  typedef std::deque<cOrgMessage> message_list_type; //!< Container-type for cOrgMessages.
   
   //! Called when this organism attempts to send a message.
   bool SendMessage(cAvidaContext& ctx, cOrgMessage& msg);
@@ -370,6 +374,7 @@
   struct cMessagingSupport
   {
     cMessagingSupport() : retrieve_index(0) { }
+
     message_list_type sent; //!< List of all messages sent by this organism.
     message_list_type received; //!< List of all messages received by this organism.
     message_list_type::size_type retrieve_index; //!< Index of next message that can be retrieved.




More information about the Avida-cvs mailing list