Datagram processing optimizations

This commit is contained in:
Joe Shochet 2004-04-05 20:05:29 +00:00
parent 7b19c4b1f6
commit 42e8a6662d
3 changed files with 112 additions and 135 deletions

View File

@ -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)

View File

@ -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))

View File

@ -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