[Orxonox-commit 1732] r6450 - in code/branches/network2/src/libraries/network: . packet synchronisable

scheusso at orxonox.net scheusso at orxonox.net
Mon Jan 18 00:05:57 CET 2010


Author: scheusso
Date: 2010-01-18 00:05:57 +0100 (Mon, 18 Jan 2010)
New Revision: 6450

Modified:
   code/branches/network2/src/libraries/network/GamestateClient.cc
   code/branches/network2/src/libraries/network/GamestateManager.cc
   code/branches/network2/src/libraries/network/Host.h
   code/branches/network2/src/libraries/network/packet/Gamestate.cc
   code/branches/network2/src/libraries/network/packet/Gamestate.h
   code/branches/network2/src/libraries/network/packet/Packet.cc
   code/branches/network2/src/libraries/network/synchronisable/Synchronisable.cc
   code/branches/network2/src/libraries/network/synchronisable/Synchronisable.h
Log:
further traffic reduction:
- synchronisableheaders are now smaller( by 2 bytes per header )
- variableID of SynchronisableVariables are now uint8_t -> max 256 synchronised variables per Synchronisable


Modified: code/branches/network2/src/libraries/network/GamestateClient.cc
===================================================================
--- code/branches/network2/src/libraries/network/GamestateClient.cc	2010-01-17 10:49:48 UTC (rev 6449)
+++ code/branches/network2/src/libraries/network/GamestateClient.cc	2010-01-17 23:05:57 UTC (rev 6450)
@@ -160,24 +160,28 @@
       bool b = gs->decompressData();
       assert(b);
     }
-//     if(gs->isDiffed()){
+    if(gs->isDiffed())
+    {
+      assert(0);
 //       packet::Gamestate *base = gamestateMap_[gs->getBaseID()];
-//       if(!base){
-//         COUT(3) << "could not find base gamestate id: " << gs->getBaseID() << endl;
+//       if(!base)
+//       {
+//         COUT(0) << "could not find base gamestate id: " << gs->getBaseID() << endl;
+//         assert(0);
 //         delete gs;
 //         return 0;
 //       }
-// //       assert(base); //TODO: fix this
 //       packet::Gamestate *undiffed = gs->undiff(base);
 //       delete gs;
 //       gs=undiffed;
 //       COUT(5) << "successfully undiffed gamestate id: " << undiffed->getID() << std::endl;
-//     }
+    }
     if(gs->spreadData(0x2))
       return gs;
     else
     {
-      COUT(3) << "could not spread gamestate" << endl;
+      COUT(0) << "could not spread gamestate" << endl;
+      assert(0);
       return NULL;
     }
   }

Modified: code/branches/network2/src/libraries/network/GamestateManager.cc
===================================================================
--- code/branches/network2/src/libraries/network/GamestateManager.cc	2010-01-17 10:49:48 UTC (rev 6449)
+++ code/branches/network2/src/libraries/network/GamestateManager.cc	2010-01-17 23:05:57 UTC (rev 6450)
@@ -189,7 +189,7 @@
 //     packet::Gamestate *gs = gamestate->doSelection(clientID, 20000);
 //       packet::Gamestate* gs = new packet::Gamestate(*gamestate);
 //     packet::Gamestate* gs = gamestate;
-    packet::Gamestate *gs = new packet::Gamestate(*gamestate);
+    packet::Gamestate *gs = new packet::Gamestate(*gamestate); //TODO: is this neccessary ?
 //     packet::Gamestate *gs = new packet::Gamestate();
 //     gs->collectData( id_, 0x1 );
 //     this->threadMutex_->lock();
@@ -200,25 +200,17 @@
 
     if(base)
     {
-
-//       COUT(3) << "diffing" << std::endl;
-//       packet::Gamestate* gs1  = gs;
-      packet::Gamestate *diffed = gs->diff(base);
-      if( diffed->getDataSize() == 0 )
+      packet::Gamestate *diffed1 = gs->diffVariables(base);
+      if( diffed1->getDataSize() == 0 )
       {
-        delete diffed;
+        delete diffed1;
         destgamestate = 0;
         return;
       }
-      else
-        gs = diffed;
-      //packet::Gamestate *gs2 = diffed->undiff(gs);
-//       assert(*gs == *gs2);
-//       packet::Gamestate* gs2 = gs->undiff(client);
-//       gs = new packet::Gamestate(*gs);
-//       assert(*gs1==*gs2);
+      gs = diffed1;
     }
-    else{
+    else
+    {
       gs = new packet::Gamestate(*gs);
     }
 

Modified: code/branches/network2/src/libraries/network/Host.h
===================================================================
--- code/branches/network2/src/libraries/network/Host.h	2010-01-17 10:49:48 UTC (rev 6449)
+++ code/branches/network2/src/libraries/network/Host.h	2010-01-17 23:05:57 UTC (rev 6450)
@@ -35,7 +35,7 @@
 namespace orxonox {
 
   const unsigned int CLIENTID_SERVER = 0;
-  const unsigned int NETWORK_FREQUENCY = 30;
+  const unsigned int NETWORK_FREQUENCY = 25;
   const float NETWORK_PERIOD = 1.0f/NETWORK_FREQUENCY;
 
 /**

Modified: code/branches/network2/src/libraries/network/packet/Gamestate.cc
===================================================================
--- code/branches/network2/src/libraries/network/packet/Gamestate.cc	2010-01-17 10:49:48 UTC (rev 6449)
+++ code/branches/network2/src/libraries/network/packet/Gamestate.cc	2010-01-17 23:05:57 UTC (rev 6450)
@@ -180,7 +180,6 @@
   assert(data_);
   assert(!header_->isCompressed());
   uint8_t *mem=data_+GamestateHeader::getSize();
-  bool diffed = header_->isDiffed();
   Synchronisable *s;
 
   // update the data of the objects we received
@@ -193,11 +192,11 @@
     {
       if (!GameMode::isMaster())
       {
-        Synchronisable::fabricate(mem, diffed, mode);
+        Synchronisable::fabricate(mem, mode);
       }
       else
       {
-        mem += objectheader.getDataSize()+SynchronisableHeader::getSize();
+        mem += objectheader.getDataSize() + ( objectheader.isDiffed() ? SynchronisableHeaderLight::getSize() : SynchronisableHeader::getSize() );
       }
     }
     else
@@ -364,7 +363,7 @@
 }
 
 
-Gamestate *Gamestate::diff(Gamestate *base)
+Gamestate* Gamestate::diffVariables(Gamestate *base)
 {
   assert(this && base); assert(data_ && base->data_);
   assert(!header_->isCompressed() && !base->header_->isCompressed());
@@ -380,7 +379,6 @@
 
   assert( origLength && baseLength );
 
-  COUT(0) << "newSize: " << origLength + GamestateHeader::getSize() + sizeof(uint32_t)*this->nrOfVariables_ << endl;
   uint8_t *nData = new uint8_t[origLength + GamestateHeader::getSize() + sizeof(uint32_t)*this->nrOfVariables_]; // this is the maximum size needed in the worst case
   uint8_t *dest = GAMESTATE_START(nData);
 
@@ -447,10 +445,10 @@
       {
 //         COUT(4) << "diff " << h.getObjectID() << ":";
         // Now start to diff the Object
-        SynchronisableHeader h2(dest);
+        SynchronisableHeaderLight h2(dest);
         h2 = h; // copy over the objectheader
-        uint32_t variableID = 0;
-        uint32_t newObjectOffset = SynchronisableHeader::getSize();
+        VariableID variableID = 0;
+        uint32_t newObjectOffset = SynchronisableHeaderLight::getSize();
         // iterate through all variables
         while( objectOffset < h.getDataSize()+SynchronisableHeader::getSize() )
         {
@@ -464,8 +462,8 @@
             if ( memcmp(origData+origOffset+objectOffset, temp+objectOffset, varSize) != 0 )
             {
 //               COUT(4) << " c" << varSize;
-              *(uint32_t*)(dest+newObjectOffset) = variableID; // copy over the variableID
-              newObjectOffset += sizeof(uint32_t);
+              *(VariableID*)(dest+newObjectOffset) = variableID; // copy over the variableID
+              newObjectOffset += sizeof(VariableID);
               memcpy( dest+newObjectOffset, origData+origOffset+objectOffset, varSize );
               newObjectOffset += varSize;
               objectOffset += varSize;
@@ -484,7 +482,7 @@
           sizes += Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables() - variableID;
 //         COUT(4) << endl;
         h2.setDiffed(true);
-        h2.setDataSize(newObjectOffset-SynchronisableHeader::getSize());
+        h2.setDataSize(newObjectOffset-SynchronisableHeaderLight::getSize());
         assert(objectOffset == h.getDataSize()+SynchronisableHeader::getSize());
         origOffset += objectOffset;
         baseOffset += temp + h.getDataSize()+SynchronisableHeader::getSize() - baseData;
@@ -519,17 +517,109 @@
   Gamestate *g = new Gamestate(nData, getClientID());
   assert(g->header_);
   *(g->header_) = *header_;
-  g->header_->setDiffed( true );
   g->header_->setBaseID( base->getID() );
   g->header_->setDataSize(dest - nData - GamestateHeader::getSize());
   g->flags_=flags_;
   g->packetDirection_ = packetDirection_;
+  assert(!g->isCompressed());
+  return g;
+}
+
+
+Gamestate* Gamestate::diffData(Gamestate *base)
+{
+  assert(this && base); assert(data_ && base->data_);
+  assert(!header_->isCompressed() && !base->header_->isCompressed());
+  assert(!header_->isDiffed());
+
+  uint8_t *basep = GAMESTATE_START(base->data_);
+  uint8_t *gs = GAMESTATE_START(this->data_);
+  uint32_t dest_length = header_->getDataSize();
+
+  if(dest_length==0)
+    return NULL;
+
+  uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
+  uint8_t *dest = GAMESTATE_START(ndata);
+
+  rawDiff( dest, gs, basep, header_->getDataSize(), base->header_->getDataSize() );
+#ifndef NDEBUG
+  uint8_t *dest2 = new uint8_t[dest_length];
+  rawDiff( dest2, dest, basep, header_->getDataSize(), base->header_->getDataSize() );
+  assert( memcmp( dest2, gs, dest_length) == 0 );
+  delete dest2;
+#endif
+
+  Gamestate *g = new Gamestate(ndata, getClientID());
+  assert(g->header_);
+  *(g->header_) = *header_;
+  g->header_->setDiffed( true );
+  g->header_->setBaseID( base->getID() );
+  g->flags_=flags_;
+  g->packetDirection_ = packetDirection_;
   assert(g->isDiffed());
   assert(!g->isCompressed());
   return g;
 }
 
 
+Gamestate* Gamestate::undiff(Gamestate *base)
+{
+  assert(this && base); assert(data_ && base->data_);
+  assert(!header_->isCompressed() && !base->header_->isCompressed());
+  assert(header_->isDiffed());
+
+  uint8_t *basep = GAMESTATE_START(base->data_);
+  uint8_t *gs = GAMESTATE_START(this->data_);
+  uint32_t dest_length = header_->getDataSize();
+
+  if(dest_length==0)
+    return NULL;
+
+  uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
+  uint8_t *dest = ndata + GamestateHeader::getSize();
+
+  rawDiff( dest, gs, basep, header_->getDataSize(), base->header_->getDataSize() );
+
+  Gamestate *g = new Gamestate(ndata, getClientID());
+  assert(g->header_);
+  *(g->header_) = *header_;
+  g->header_->setDiffed( false );
+  g->flags_=flags_;
+  g->packetDirection_ = packetDirection_;
+  assert(!g->isDiffed());
+  assert(!g->isCompressed());
+  return g;
+}
+
+
+void Gamestate::rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength)
+{
+  uint64_t* gd = (uint64_t*)data;
+  uint64_t* bd = (uint64_t*)basedata;
+  uint64_t* nd = (uint64_t*)newdata;
+
+  unsigned int i;
+  for( i=0; i<datalength/8; i++ )
+  {
+    if( i<baselength/8 )
+      *(nd+i) = *(gd+i) ^ *(bd+i);  // xor the data
+    else
+      *(nd+i) = *(gd+i); // just copy over the data
+  }
+  unsigned int j;
+  // now process the rest (when datalength isn't a multiple of 4)
+  for( j = 8*(datalength/8); j<datalength; j++ )
+  {
+    if( j<baselength )
+      *(newdata+j) = *(data+j) ^ *(basedata+j); // xor
+    else
+      *(newdata+j) = *(data+j); // just copy
+  }
+  assert(j==datalength);
+}
+
+
 Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){
   assert(data_);
   std::list<obj>::iterator it;

Modified: code/branches/network2/src/libraries/network/packet/Gamestate.h
===================================================================
--- code/branches/network2/src/libraries/network/packet/Gamestate.h	2010-01-17 10:49:48 UTC (rev 6449)
+++ code/branches/network2/src/libraries/network/packet/Gamestate.h	2010-01-17 23:05:57 UTC (rev 6450)
@@ -114,7 +114,9 @@
     inline bool isCompressed() const { return header_->isCompressed(); }
     inline int32_t getBaseID() const { return header_->getBaseID(); }
     inline uint32_t getDataSize() const { return header_->getDataSize(); }
-    Gamestate *diff(Gamestate *base);
+    Gamestate* diffVariables(Gamestate *base);
+    Gamestate* diffData(Gamestate *base);
+    Gamestate *undiff(Gamestate *base);
     Gamestate* doSelection(unsigned int clientID, unsigned int targetSize);
     bool compressData();
     bool decompressData();

Modified: code/branches/network2/src/libraries/network/packet/Packet.cc
===================================================================
--- code/branches/network2/src/libraries/network/packet/Packet.cc	2010-01-17 10:49:48 UTC (rev 6449)
+++ code/branches/network2/src/libraries/network/packet/Packet.cc	2010-01-17 23:05:57 UTC (rev 6450)
@@ -70,10 +70,6 @@
   bDataENetAllocated_ = false;
 }
 
-void blub(ENetPacket *packet){
-  COUT(4) << "blubb" << std::endl;
-}
-
 Packet::Packet(uint8_t *data, unsigned int clientID){
   flags_ = PACKET_FLAG_DEFAULT;
   packetDirection_ = Direction::Incoming;

Modified: code/branches/network2/src/libraries/network/synchronisable/Synchronisable.cc
===================================================================
--- code/branches/network2/src/libraries/network/synchronisable/Synchronisable.cc	2010-01-17 10:49:48 UTC (rev 6449)
+++ code/branches/network2/src/libraries/network/synchronisable/Synchronisable.cc	2010-01-17 23:05:57 UTC (rev 6450)
@@ -131,9 +131,10 @@
    * @param mode defines the mode, how the data should be loaded
    * @return pointer to the newly created synchronisable
    */
-  Synchronisable *Synchronisable::fabricate(uint8_t*& mem, bool diffed, uint8_t mode)
+  Synchronisable *Synchronisable::fabricate(uint8_t*& mem, uint8_t mode)
   {
     SynchronisableHeader header(mem);
+    assert( !header.isDiffed() );
 
     COUT(4) << "fabricating object with id: " << header.getObjectID() << std::endl;
 
@@ -307,45 +308,44 @@
       mode=state_;
     if(syncList_.empty()){
       assert(0);
-      COUT(4) << "Synchronisable::updateData syncList_ is empty" << std::endl;
+      COUT(2) << "Synchronisable::updateData syncList_ is empty" << std::endl;
       return false;
     }
 
     uint8_t* data=mem;
     // start extract header
-    SynchronisableHeader syncHeader(mem);
-    assert(syncHeader.getObjectID()==this->objectID_);
-    assert(syncHeader.getCreatorID()==this->creatorID_);
-    assert(syncHeader.getClassID()==this->classID_);
+    SynchronisableHeaderLight syncHeaderLight(mem);
+    assert(syncHeaderLight.getObjectID()==this->getObjectID());
 
-    mem += SynchronisableHeader::getSize();
-    // stop extract header
-
     //COUT(5) << "Synchronisable: objectID_ " << syncHeader.getObjectID() << ", classID_ " << syncHeader.getClassID() << " size: " << syncHeader.getDataSize() << " synchronising data" << std::endl;
-    if( !syncHeader.isDiffed() )
+    if( !syncHeaderLight.isDiffed() )
     {
+      SynchronisableHeader syncHeader2(mem);
+      assert( this->getClassID() == syncHeader2.getClassID() );
+      assert( this->getCreatorID() == syncHeader2.getCreatorID() );
+      mem += SynchronisableHeader::getSize();
       std::vector<SynchronisableVariableBase *>::iterator i;
       for(i=syncList_.begin(); i!=syncList_.end(); i++)
       {
-        assert( mem <= data+syncHeader.getDataSize()+SynchronisableHeader::getSize() ); // always make sure we don't exceed the datasize in our stream
+        assert( mem <= data+syncHeader2.getDataSize()+SynchronisableHeader::getSize() ); // always make sure we don't exceed the datasize in our stream
         (*i)->putData( mem, mode, forceCallback );
       }
+      assert(mem == data+syncHeaderLight.getDataSize()+SynchronisableHeader::getSize() );
     }
     else
     {
-      COUT(0) << "objectID: " << this->objectID_ << endl;
-      while( mem < data+syncHeader.getDataSize()+SynchronisableHeader::getSize() )
+      mem += SynchronisableHeaderLight::getSize();
+//       COUT(0) << "objectID: " << this->objectID_ << endl;
+      while( mem < data+syncHeaderLight.getDataSize()+SynchronisableHeaderLight::getSize() )
       {
-        uint32_t varID = *(uint32_t*)mem;
-        COUT(0) << "varID: " << varID << endl;
-        if( varID == 22 )
-          COUT(6) << " blub " << endl;
+        VariableID varID = *(VariableID*)mem;
+//         COUT(0) << "varID: " << varID << endl;
         assert( varID < syncList_.size() );
-        mem += sizeof(uint32_t);
+        mem += sizeof(VariableID);
         syncList_[varID]->putData( mem, mode, forceCallback );
       }
+      assert(mem == data+syncHeaderLight.getDataSize()+SynchronisableHeaderLight::getSize() );
     }
-    assert(mem == data+syncHeader.getDataSize()+SynchronisableHeader::getSize() );
     return true;
   }
 

Modified: code/branches/network2/src/libraries/network/synchronisable/Synchronisable.h
===================================================================
--- code/branches/network2/src/libraries/network/synchronisable/Synchronisable.h	2010-01-17 10:49:48 UTC (rev 6449)
+++ code/branches/network2/src/libraries/network/synchronisable/Synchronisable.h	2010-01-17 23:05:57 UTC (rev 6450)
@@ -63,6 +63,8 @@
       VeryLow     = 100
     };
   }
+  
+  typedef uint8_t VariableID;
 
   /**
    * @brief: stores information about a Synchronisable
@@ -76,33 +78,34 @@
    * Byte 13 to 16: creatorID_
    */
   class _NetworkExport SynchronisableHeader{
+    friend class SynchronisableHeaderLight;
     private:
-      uint8_t *data_;
+      uint8_t* data_;
     public:
       SynchronisableHeader(uint8_t* data)
         { data_ = data; }
       inline static uint32_t getSize()
-        { return 16; }
-      inline uint32_t getDataSize() const
-        { return (*(uint32_t*)data_) & 0x7FFFFFFF; } //only use the first 31 bits
-      inline void setDataSize(uint32_t size)
-        { *(uint32_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint32_t*)(data_) & 0x80000000 ); }
+        { return 14; }
+      inline uint16_t getDataSize() const
+        { return (*(uint16_t*)data_) & 0x7FFF; } //only use the first 31 bits
+      inline void setDataSize(uint16_t size)
+        { *(uint16_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint16_t*)(data_) & 0x8000 ); }
       inline bool isDiffed() const
-        { return ( (*(uint32_t*)data_) & 0x80000000 ) == 0x80000000; }
+        { return ( (*(uint16_t*)data_) & 0x8000 ) == 0x8000; }
       inline void setDiffed( bool b)
-        { *(uint32_t*)(data_) = (b << 31) | (*(uint32_t*)(data_) & 0x7FFFFFFF ); }
+        { *(uint16_t*)(data_) = (b << 15) | (*(uint16_t*)(data_) & 0x7FFF ); }
       inline uint32_t getObjectID() const
-        { return *(uint32_t*)(data_+4); }
+        { return *(uint32_t*)(data_+2); }
       inline void setObjectID(uint32_t objectID_)
-        { *(uint32_t*)(data_+4) = objectID_; }
+        { *(uint32_t*)(data_+2) = objectID_; }
       inline uint32_t getClassID() const
-        { return *(uint32_t*)(data_+8); }
+        { return *(uint32_t*)(data_+6); }
       inline void setClassID(uint32_t classID_)
-        { *(uint32_t*)(data_+8) = classID_; }
+        { *(uint32_t*)(data_+6) = classID_; }
       inline uint32_t getCreatorID() const
-        { return *(uint32_t*)(data_+12); }
+        { return *(uint32_t*)(data_+10); }
       inline void setCreatorID(uint32_t creatorID_)
-        { *(uint32_t*)(data_+12) = creatorID_; }
+        { *(uint32_t*)(data_+10) = creatorID_; }
       inline void operator=(SynchronisableHeader& h)
         { memcpy(data_, h.data_, getSize()); }
   };
@@ -118,24 +121,24 @@
    */
   class _NetworkExport SynchronisableHeaderLight{
     private:
-      uint8_t *data_;
+      uint8_t* data_;
     public:
-      SynchronisableHeader(uint8_t* data)
+      SynchronisableHeaderLight(uint8_t* data)
         { data_ = data; }
       inline static uint32_t getSize()
-        { return 16; }
-      inline uint32_t getDataSize() const
-        { return (*(uint32_t*)data_) & 0x7FFFFFFF; } //only use the first 31 bits
-      inline void setDataSize(uint32_t size)
-        { *(uint32_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint32_t*)(data_) & 0x80000000 ); }
+        { return 6; }
+      inline uint16_t getDataSize() const
+        { return (*(uint16_t*)data_) & 0x7FFF; } //only use the first 31 bits
+      inline void setDataSize(uint16_t size)
+        { *(uint16_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint16_t*)(data_) & 0x8000 ); }
       inline bool isDiffed() const
-        { return ( (*(uint32_t*)data_) & 0x80000000 ) == 0x80000000; }
+        { return ( (*(uint16_t*)data_) & 0x8000 ) == 0x8000; }
       inline void setDiffed( bool b)
-        { *(uint32_t*)(data_) = (b << 31) | (*(uint32_t*)(data_) & 0x7FFFFFFF ); }
+        { *(uint16_t*)(data_) = (b << 15) | (*(uint16_t*)(data_) & 0x7FFF ); }
       inline uint32_t getObjectID() const
-        { return *(uint32_t*)(data_+4); }
+        { return *(uint32_t*)(data_+2); }
       inline void setObjectID(uint32_t objectID_)
-        { *(uint32_t*)(data_+4) = objectID_; }
+        { *(uint32_t*)(data_+2) = objectID_; }
       inline void operator=(SynchronisableHeader& h)
         { memcpy(data_, h.data_, getSize()); }
   };
@@ -152,7 +155,7 @@
 
     static void setClient(bool b);
 
-    static Synchronisable *fabricate(uint8_t*& mem, bool diffed, uint8_t mode=0x0);
+    static Synchronisable *fabricate(uint8_t*& mem, uint8_t mode=0x0);
     static bool deleteObject(uint32_t objectID_);
     static Synchronisable *getSynchronisable(uint32_t objectID_);
     static unsigned int getNumberOfDeletedObject(){ return deletedObjects_.size(); }
@@ -167,7 +170,7 @@
     void setSyncMode(uint8_t mode);
     
     inline uint32_t getNrOfVariables(){ return this->syncList_.size(); }
-    inline uint32_t getVarSize( uint32_t ID )
+    inline uint32_t getVarSize( VariableID ID )
     { return this->syncList_[ID]->getSize(state_); }
 
   protected:




More information about the Orxonox-commit mailing list