Browse Source

Datagram processing optimizations

Joe Shochet 22 years ago
parent
commit
42e8a6662d

+ 5 - 24
direct/src/distributed/ClientDistUpdate.py

@@ -1,7 +1,7 @@
 """ClientDistUpdate module: contains the ClientDistUpdate class"""
 
 import DirectNotifyGlobal
-import Datagram
+from PyDatagram import PyDatagram
 from MsgTypes import *
 
 # These are stored here so that the distributed classes we load on the fly
@@ -55,40 +55,20 @@ class ClientDistUpdate:
                     self.divisors.append(componentField.getElementDivisor(j))
         else:
             self.notify.error("field is neither atom nor molecule")
-        return None
 
     def updateField(self, cdc, do, di):
         # Get the arguments into a list
-        args = self.extractArgs(di)
-
+        args = map(lambda type, div: di.getArg(type,div), self.types, self.divisors)
         assert(self.notify.debug("Received update for %d: %s.%s(%s)" % (do.doId, cdc.name, self.name, args)))
-
         # Apply the function to the object with the arguments
         if self.func != None:
             apply(self.func, [do] + args)
-        return None
 
-    def extractArgs(self, di):
-        args = []
-        assert(len(self.types) == len(self.divisors))
-        numTypes = len(self.types)
-        for i in range(numTypes):
-            args.append(di.getArg(self.types[i], self.divisors[i]))
-        return args
-
-    def addArgs(self, datagram, args):
-        # Add the args to the datagram
-        numElems = len(args)
-        assert (numElems == len(self.types) == len(self.divisors))
-        for i in range(0, numElems):
-            datagram.putArg(args[i], self.types[i], self.divisors[i])
-    
     def sendUpdate(self, cr, do, args, sendToId = None):
         if sendToId == None:
             sendToId = do.doId
-
         assert(self.notify.debug("Sending update for %d: %s(%s)" % (sendToId, self.name, args)))
-        datagram = Datagram.Datagram()
+        datagram = PyDatagram()
         # Add message type
         datagram.addUint16(CLIENT_OBJECT_UPDATE_FIELD)
         # Add the DO id
@@ -96,6 +76,7 @@ class ClientDistUpdate:
         # Add the field id
         datagram.addUint16(self.number)
         # Add the arguments
-        self.addArgs(datagram, args)
+        for arg, type, div in zip(args, self.types, self.divisors):
+            datagram.putArg(arg, type, div)
         # send the datagram
         cr.send(datagram)

+ 107 - 0
direct/src/distributed/PyDatagram.py

@@ -0,0 +1,107 @@
+
+# This is built as a subclass instead of an extension so we can define the
+# class variable FuncDict and so we can import DCSubatomicType at the top
+# of the file rather than every time we call the putArg function.
+
+from PandaModules import *
+# Import the type numbers
+from DCSubatomicType import *
+
+class PyDatagram(Datagram):
+
+    # This is a little helper Dict to replace the huge <if> statement
+    # for trying to match up datagram subatomic types with add funtions
+    # If Python had an O(1) "case" statement we would use that instead
+    FuncDict = {
+        STInt8  : (Datagram.addInt8, int),
+        STInt16 : (Datagram.addInt16, int),
+        STInt32 : (Datagram.addInt32, int),
+        STInt64 : (Datagram.addInt64, int),
+        STUint8  : (Datagram.addUint8, int),
+        STUint16 : (Datagram.addUint16, int),
+        STUint32 : (Datagram.addUint32, int),
+        STUint64 : (Datagram.addUint64, int),
+        STFloat64 : (Datagram.addFloat64, None),
+        STString : (Datagram.addString, None),
+        STBlob : (Datagram.addString, None),
+        STBlob32 : (Datagram.addString32, None),
+        }
+
+    def putArg(self, arg, subatomicType, divisor=1):
+        if (divisor == 1):
+            funcSpecs = self.FuncDict.get(subatomicType)
+            if funcSpecs:
+                addFunc, argFunc = funcSpecs
+                if argFunc:
+                    arg = argFunc(arg)
+                addFunc(self, arg)
+            # Ok, arrays are not handled by the FuncDict yet
+            elif subatomicType == STInt8array:
+                self.addUint16(len(arg))
+                for i in arg:
+                    self.addInt8(int(i))
+            elif subatomicType == STInt16array:
+                self.addUint16(len(arg) << 1)
+                for i in arg:
+                    self.addInt16(int(i))
+            elif subatomicType == STInt32array:
+                self.addUint16(len(arg) << 2)
+                for i in arg:
+                    self.addInt32(int(i))
+            elif subatomicType == STUint8array:
+                self.addUint16(len(arg))
+                for i in arg:
+                    self.addUint8(int(i))
+            elif subatomicType == STUint16array:
+                self.addUint16(len(arg) << 1)
+                for i in arg:
+                    self.addUint16(int(i))
+            elif subatomicType == STUint32array:
+                self.addUint16(len(arg) << 2)
+                for i in arg:
+                    self.addUint32(int(i))
+            elif subatomicType == STUint32uint8array:
+                self.addUint16(len(arg) * 5)
+                for i in arg:
+                    self.addUint32(int(i[0]))
+                    self.addUint8(int(i[1]))
+            else:
+                raise Exception("Error: No such type as: " + str(subatomicType))
+        else:
+            funcSpecs = self.FuncDict.get(subatomicType)
+            if funcSpecs:
+                # argFunc is only used if divisor == 1
+                addFunc, argFunc = funcSpecs
+                addFunc(self, int(round(arg * divisor)))
+            # Ok, arrays are not handled by the FuncDict yet
+            elif subatomicType == STInt8array:
+                self.addUint16(len(arg))
+                for i in arg:
+                    self.addInt8(int(round(i*divisor)))
+            elif subatomicType == STInt16array:
+                self.addUint16(len(arg) << 1)
+                for i in arg:
+                    self.addInt16(int(round(i*divisor)))
+            elif subatomicType == STInt32array:
+                self.addUint16(len(arg) << 2)
+                for i in arg:
+                    self.addInt32(int(round(i*divisor)))
+            elif subatomicType == STUint8array:
+                self.addUint16(len(arg))
+                for i in arg:
+                    self.addUint8(int(round(i*divisor)))
+            elif subatomicType == STUint16array:
+                self.addUint16(len(arg) << 1)
+                for i in arg:
+                    self.addUint16(int(round(i*divisor)))
+            elif subatomicType == STUint32array:
+                self.addUint16(len(arg) << 2)
+                for i in arg:
+                    self.addUint32(int(round(i*divisor)))
+            elif subatomicType == STUint32uint8array:
+                self.addUint16(len(arg) * 5)
+                for i in arg:
+                    self.addUint32(int(round(i[0]*divisor)))
+                    self.addUint8(int(round(i[1]*divisor)))
+            else:
+                raise Exception("Error: type does not accept divisor: " + str(subatomicType))

+ 0 - 111
direct/src/extensions/Datagram-extensions.py

@@ -1,111 +0,0 @@
-
-    def putArg(self, arg, subatomicType, divisor=1):
-        # Import the type numbers
-        import DCSubatomicType
-        if (divisor == 1):
-            if subatomicType == DCSubatomicType.STInt8:
-                self.addInt8(int(arg))
-            elif subatomicType == DCSubatomicType.STInt16:
-                self.addInt16(int(arg))
-            elif subatomicType == DCSubatomicType.STInt32:
-                self.addInt32(int(arg))
-            elif subatomicType == DCSubatomicType.STInt64:
-                self.addInt64(int(arg))
-            elif subatomicType == DCSubatomicType.STUint8:
-                self.addUint8(int(arg))
-            elif subatomicType == DCSubatomicType.STUint16:
-                self.addUint16(int(arg))
-            elif subatomicType == DCSubatomicType.STUint32:
-                self.addUint32(int(arg))
-            elif subatomicType == DCSubatomicType.STUint64:
-                self.addUint64(int(arg))
-            elif subatomicType == DCSubatomicType.STFloat64:
-                self.addFloat64(arg)
-            elif subatomicType == DCSubatomicType.STString:
-                self.addString(arg)
-            elif subatomicType == DCSubatomicType.STBlob:
-                self.addString(arg)
-            elif hasattr(DCSubatomicType, "STBlob32") and subatomicType == DCSubatomicType.STBlob32:
-                self.addString32(arg)
-            elif subatomicType == DCSubatomicType.STInt8array:
-                self.addUint16(len(arg))
-                for i in arg:
-                    self.addInt8(int(i))
-            elif subatomicType == DCSubatomicType.STInt16array:
-                self.addUint16(len(arg) << 1)
-                for i in arg:
-                    self.addInt16(int(i))
-            elif subatomicType == DCSubatomicType.STInt32array:
-                self.addUint16(len(arg) << 2)
-                for i in arg:
-                    self.addInt32(int(i))
-            elif subatomicType == DCSubatomicType.STUint8array:
-                self.addUint16(len(arg))
-                for i in arg:
-                    self.addUint8(int(i))
-            elif subatomicType == DCSubatomicType.STUint16array:
-                self.addUint16(len(arg) << 1)
-                for i in arg:
-                    self.addUint16(int(i))
-            elif subatomicType == DCSubatomicType.STUint32array:
-                self.addUint16(len(arg) << 2)
-                for i in arg:
-                    self.addUint32(int(i))
-            elif subatomicType == DCSubatomicType.STUint32uint8array:
-                self.addUint16(len(arg) * 5)
-                for i in arg:
-                    self.addUint32(int(i[0]))
-                    self.addUint8(int(i[1]))
-            else:
-                raise Exception("Error: No such type as: " + str(subatomicType))
-        else:
-            if subatomicType == DCSubatomicType.STInt8:
-                self.addInt8(int(round(arg*divisor)))
-            elif subatomicType == DCSubatomicType.STInt16:
-                self.addInt16(int(round(arg*divisor)))
-            elif subatomicType == DCSubatomicType.STInt32:
-                self.addInt32(int(round(arg*divisor)))
-            elif subatomicType == DCSubatomicType.STInt64:
-                self.addInt64(int(round(arg*divisor)))
-            elif subatomicType == DCSubatomicType.STUint8:
-                self.addUint8(int(round(arg*divisor)))
-            elif subatomicType == DCSubatomicType.STUint16:
-                self.addUint16(int(round(arg*divisor)))
-            elif subatomicType == DCSubatomicType.STUint32:
-                self.addUint32(int(round(arg*divisor)))
-            elif subatomicType == DCSubatomicType.STUint64:
-                self.addUint64(int(round(arg*divisor)))
-            elif subatomicType == DCSubatomicType.STInt8array:
-                self.addUint16(len(arg))
-                for i in arg:
-                    self.addInt8(int(round(i*divisor)))
-            elif subatomicType == DCSubatomicType.STInt16array:
-                self.addUint16(len(arg) << 1)
-                for i in arg:
-                    self.addInt16(int(round(i*divisor)))
-            elif subatomicType == DCSubatomicType.STInt32array:
-                self.addUint16(len(arg) << 2)
-                for i in arg:
-                    self.addInt32(int(round(i*divisor)))
-            elif subatomicType == DCSubatomicType.STUint8array:
-                self.addUint16(len(arg))
-                for i in arg:
-                    self.addUint8(int(round(i*divisor)))
-            elif subatomicType == DCSubatomicType.STUint16array:
-                self.addUint16(len(arg) << 1)
-                for i in arg:
-                    self.addUint16(int(round(i*divisor)))
-            elif subatomicType == DCSubatomicType.STUint32array:
-                self.addUint16(len(arg) << 2)
-                for i in arg:
-                    self.addUint32(int(round(i*divisor)))
-            elif subatomicType == DCSubatomicType.STUint32uint8array:
-                self.addUint16(len(arg) * 5)
-                for i in arg:
-                    self.addUint32(int(round(i[0]*divisor)))
-                    self.addUint8(int(round(i[1]*divisor)))
-            else:
-                raise Exception("Error: type does not accept divisor: " + str(subatomicType))
-        return None
-
-