summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael H. Schloming <rhs@apache.org>2008-06-03 17:54:45 +0000
committerRafael H. Schloming <rhs@apache.org>2008-06-03 17:54:45 +0000
commitf081132e845b3ae92aa08ef3996ec29a2f6de2ed (patch)
tree7b190b5429d1d0fd48f846f4a68f3c34fd33515d
parent83a3dc24856d12270c71fd56dd983769179e0727 (diff)
downloadqpid-python-f081132e845b3ae92aa08ef3996ec29a2f6de2ed.tar.gz
QPID-1062: modified generated code to keep packing flags in wire form and override commonly used size methods for improved performance
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@662849 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--java/common/Composite.tpl127
-rw-r--r--java/common/genutil.py55
-rw-r--r--java/common/src/main/java/org/apache/qpidity/transport/Struct.java19
-rw-r--r--java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractDecoder.java49
-rw-r--r--java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractEncoder.java36
-rw-r--r--java/common/src/main/java/org/apache/qpidity/transport/codec/Decoder.java1
-rw-r--r--java/common/src/main/java/org/apache/qpidity/transport/codec/Encoder.java3
-rw-r--r--java/common/src/main/java/org/apache/qpidity/transport/codec/SizeEncoder.java60
-rw-r--r--java/common/src/main/java/org/apache/qpidity/transport/codec/Sizer.java3
-rw-r--r--java/common/src/main/java/org/apache/qpidity/transport/network/Disassembler.java2
10 files changed, 170 insertions, 185 deletions
diff --git a/java/common/Composite.tpl b/java/common/Composite.tpl
index 4f72279bcc..2b9ed873de 100644
--- a/java/common/Composite.tpl
+++ b/java/common/Composite.tpl
@@ -1,6 +1,7 @@
package org.apache.qpidity.transport;
import java.util.ArrayList;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -36,10 +37,16 @@ if type.name in ("control", "command"):
else:
base = "Struct"
size = type["@size"]
- pack = type["@pack"]
+ pack = num(type["@pack"])
payload = "false"
track = "-1"
+PACK_TYPES = {
+ 1: "byte",
+ 2: "short",
+ 4: "int"
+}
+
typecode = code(type)
}
@@ -67,17 +74,18 @@ public class $name extends $base {
return $track;
}
- private static final List<Field<?,?>> FIELDS = new ArrayList<Field<?,?>>();
- public List<Field<?,?>> getFields() { return FIELDS; }
-
${
+
+if pack > 0:
+ out(" private $(PACK_TYPES[pack]) packing_flags = 0;\n");
+
fields = get_fields(type)
params = get_parameters(fields)
options = get_options(fields)
for f in fields:
- out(" private boolean has_$(f.name);\n")
- out(" private $(f.type) $(f.name);\n")
+ if not f.empty:
+ out(" private $(f.type) $(f.name);\n")
}
${
@@ -91,9 +99,6 @@ for f in fields:
if f.option: continue
out(" $(f.set)($(f.name));\n")
-for f in options:
- out(" boolean _$(f.name) = false;\n")
-
if options:
out("""
for (int i=0; i < _options.length; i++) {
@@ -101,16 +106,13 @@ if options:
""")
for f in options:
- out(" case $(f.option): _$(f.name) = true; break;\n")
+ out(" case $(f.option): packing_flags |= $(f.flag_mask(pack)); break;\n")
out(""" case NO_OPTION: break;
default: throw new IllegalArgumentException("invalid option: " + _options[i]);
}
}
""")
-
-for f in options:
- out(" $(f.set)(_$(f.name));\n")
}
}
@@ -120,57 +122,49 @@ for f in options:
${
for f in fields:
- out("""
+ if pack > 0:
+ out("""
public final boolean $(f.has)() {
- return has_$(f.name);
+ return (packing_flags & $(f.flag_mask(pack))) != 0;
}
public final $name $(f.clear)() {
- this.has_$(f.name) = false;
- this.$(f.name) = $(f.default);
+ packing_flags &= ~$(f.flag_mask(pack));
+${
+if not f.empty:
+ out(" this.$(f.name) = $(f.default);")
+}
this.dirty = true;
return this;
}
+""")
+ out("""
public final $(f.type) $(f.get)() {
- return $(f.name);
+${
+if f.empty:
+ out(" return $(f.has)();")
+else:
+ out(" return $(f.name);")
+}
}
public final $name $(f.set)($(f.type) value) {
$(f.check)
- this.$(f.name) = value;
- this.has_$(f.name) = true;
+${
+if not f.empty:
+ out(" this.$(f.name) = value;")
+}
+${
+if pack > 0:
+ out(" packing_flags |= $(f.flag_mask(pack));")
+}
this.dirty = true;
return this;
}
public final $name $(f.name)($(f.type) value) {
- $(f.check)
- this.$(f.name) = value;
- this.has_$(f.name) = true;
- this.dirty = true;
- return this;
- }
-
- static {
- FIELDS.add(new Field<$name,$(jref(jclass(f.type)))>($name.class, $(jref(jclass(f.type))).class, "$(f.name)", $(f.index)) {
- public boolean has(Object struct) {
- return check(struct).has_$(f.name);
- }
- public void has(Object struct, boolean value) {
- check(struct).has_$(f.name) = value;
- }
- public $(jref(f.type)) get(Object struct) {
- return check(struct).$(f.get)();
- }
- public void read(Decoder dec, Object struct) {
- check(struct).$(f.name) = $(f.read);
- check(struct).dirty = true;
- }
- public void write(Encoder enc, Object struct) {
- $(f.write);
- }
- });
+ return $(f.set)(value);
}
""")
}
@@ -178,23 +172,14 @@ for f in fields:
public void write(Encoder enc)
{
${
-flag_count = 8*int(pack)
-reserved_count = flag_count - len(fields)
-
if pack > 0:
- for f in fields:
- if f.type == "boolean":
- out(" enc.writeBit(this.$(f.name));\n")
- else:
- out(" enc.writeBit(this.has_$(f.name));\n")
- for i in range(reserved_count):
- out(" enc.writeBit(false);\n")
+ out(" enc.writeUint%s(packing_flags);\n" % (pack*8));
for f in fields:
- if f.type == "boolean":
+ if f.empty:
continue
if pack > 0:
- out(" if (this.has_$(f.name))\n ")
+ out(" if ((packing_flags & $(f.flag_mask(pack))) != 0)\n ")
pre = ""
post = ""
if f.type_node.name == "struct":
@@ -209,19 +194,13 @@ for f in fields:
{
${
if pack > 0:
- for f in fields:
- if f.type == "boolean":
- out(" this.$(f.name) = dec.readBit();\n")
- else:
- out(" this.has_$(f.name) = dec.readBit();\n")
- for i in range(reserved_count):
- out(" dec.readBit();\n")
+ out(" packing_flags = ($(PACK_TYPES[pack])) dec.readUint%s();\n" % (pack*8));
for f in fields:
- if f.type == "boolean":
+ if f.empty:
continue
if pack > 0:
- out(" if (this.has_$(f.name))\n ")
+ out(" if ((packing_flags & $(f.flag_mask(pack))) != 0)\n ")
pre = ""
post = ""
arg = ""
@@ -235,4 +214,18 @@ for f in fields:
}
}
+ public Map<String,Object> getFields()
+ {
+ Map<String,Object> result = new LinkedHashMap<String,Object>();
+
+${
+for f in fields:
+ if pack > 0:
+ out(" if ((packing_flags & $(f.flag_mask(pack))) != 0)\n ")
+ out(' result.put("$(f.name)", $(f.get)());\n')
+}
+
+ return result;
+ }
+
}
diff --git a/java/common/genutil.py b/java/common/genutil.py
index dac0d65611..9636a91cc3 100644
--- a/java/common/genutil.py
+++ b/java/common/genutil.py
@@ -11,11 +11,11 @@ def dromedary(s):
def scream(*args):
return "_".join([a.replace("-", "_").upper() for a in args])
-def num(x):
+def num(x, default=None):
if x is not None and x != "":
return int(x, 0)
else:
- return None
+ return default
def klass(nd):
parent = nd.parent
@@ -53,24 +53,35 @@ def qname(nd):
else:
return name
+RESOLVED = {}
+
def resolve(node, name):
- spec = root(node)
- cls = klass(node)
- if cls:
- for nd in cls.query["#tag"]:
- if nd["@name"] == name:
+ key = (node, name)
+ if RESOLVED.has_key(key):
+ return RESOLVED[key]
+ else:
+ spec = root(node)
+ cls = klass(node)
+ if cls:
+ for nd in cls.query["#tag"]:
+ if nd["@name"] == name:
+ RESOLVED[key] = nd
+ return nd
+ for nd in spec.query["amqp/#tag"] + spec.query["amqp/class/#tag"]:
+ if name == qname(nd):
+ RESOLVED[key] = nd
return nd
- for nd in spec.query["amqp/#tag"] + spec.query["amqp/class/#tag"]:
- if name == qname(nd):
- return nd
- raise Exception("unresolved name: %s" % name)
+ raise Exception("unresolved name: %s" % name)
def resolve_type(nd):
- name = nd["@type"]
- type = resolve(nd, name)
- if type.name == "domain" and not type["enum"]:
- return resolve_type(type)
+ if hasattr(nd, "_resolved_type"):
+ return nd._resolved_type
else:
+ name = nd["@type"]
+ type = resolve(nd, name)
+ if type.name == "domain" and not type["enum"]:
+ type = resolve_type(type)
+ nd._resolved_type = type
return type
TYPES = {
@@ -148,6 +159,13 @@ class Field:
self.index = index
self.name = camel(1, nd["@name"])
self.type_node = resolve_type(nd)
+ if self.type_node.name == "domain":
+ self.prim_type = resolve_type(self.type_node)
+ else:
+ self.prim_type = self.type_node
+ self.variable_width = num(self.prim_type["@variable-width"], 0)
+ self.fixed_width = num(self.prim_type["@fixed-width"], 0)
+ self.empty = self.variable_width == 0 and self.fixed_width == 0 and self.prim_type.name != "struct"
tname = cname(self.type_node)
if self.type_node.name == "struct":
self.read = "(%s) dec.readStruct(%s.TYPE)" % (tname, tname)
@@ -155,7 +173,7 @@ class Field:
self.check = ""
self.coder = "Struct"
elif self.type_node.name == "domain":
- self.coder = camel(0, resolve_type(self.type_node)["@name"])
+ self.coder = camel(0, self.prim_type["@name"])
self.read = "%s.get(dec.read%s())" % (tname, self.coder)
self.write = "enc.write%s(check(struct).%s.getValue())" % (self.coder, self.name)
self.check = ""
@@ -175,6 +193,11 @@ class Field:
else:
self.option = None
+ def flag_mask(self, pack):
+ flag = pack * 8 - 8 - (self.index/8)*8 + (self.index % 8)
+ return 1 << flag
+
+
def get_fields(nd):
fields = []
index = 0
diff --git a/java/common/src/main/java/org/apache/qpidity/transport/Struct.java b/java/common/src/main/java/org/apache/qpidity/transport/Struct.java
index 9146f41535..a15d0a1fb8 100644
--- a/java/common/src/main/java/org/apache/qpidity/transport/Struct.java
+++ b/java/common/src/main/java/org/apache/qpidity/transport/Struct.java
@@ -21,6 +21,7 @@
package org.apache.qpidity.transport;
import java.util.List;
+import java.util.Map;
import org.apache.qpidity.transport.codec.Decoder;
import org.apache.qpidity.transport.codec.Encodable;
@@ -55,8 +56,6 @@ public abstract class Struct implements Encodable
public abstract int getStructType();
- public abstract List<Field<?,?>> getFields();
-
public abstract int getSizeWidth();
public abstract int getPackWidth();
@@ -112,6 +111,8 @@ public abstract class Struct implements Encodable
public abstract void write(Encoder enc);
+ public abstract Map<String,Object> getFields();
+
public String toString()
{
StringBuilder str = new StringBuilder();
@@ -119,16 +120,8 @@ public abstract class Struct implements Encodable
str.append("(");
boolean first = true;
- for (Field<?,?> f : getFields())
+ for (Map.Entry<String,Object> me : getFields().entrySet())
{
- if (packed())
- {
- if (!f.has(this))
- {
- continue;
- }
- }
-
if (first)
{
first = false;
@@ -137,9 +130,9 @@ public abstract class Struct implements Encodable
{
str.append(", ");
}
- str.append(f.getName());
+ str.append(me.getKey());
str.append("=");
- str.append(f.get(this));
+ str.append(me.getValue());
}
str.append(")");
diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractDecoder.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractDecoder.java
index 7b680171da..ebfc6b120f 100644
--- a/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractDecoder.java
+++ b/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractDecoder.java
@@ -45,30 +45,18 @@ import static org.apache.qpidity.transport.util.Functions.*;
abstract class AbstractDecoder implements Decoder
{
- private int count;
-
- protected AbstractDecoder()
- {
- this.count = 0;
- }
-
protected abstract byte doGet();
protected abstract void doGet(byte[] bytes);
protected byte get()
{
- clearBits();
- byte b = doGet();
- count += 1;
- return b;
+ return doGet();
}
protected void get(byte[] bytes)
{
- clearBits();
doGet(bytes);
- count += bytes.length;
}
protected short uget()
@@ -76,32 +64,6 @@ abstract class AbstractDecoder implements Decoder
return (short) (0xFF & get());
}
- private byte bits = 0x0;
- private byte nbits = 0;
-
- public boolean readBit()
- {
- if (nbits == 0)
- {
- bits = get();
- }
-
- boolean result = (bits & (1 << nbits++)) != 0;
-
- if (nbits == 8)
- {
- clearBits();
- }
-
- return result;
- }
-
- private void clearBits()
- {
- bits = 0x0;
- nbits = 0;
- }
-
public short readUint8()
{
return uget();
@@ -271,10 +233,9 @@ abstract class AbstractDecoder implements Decoder
public Map<String,Object> readMap()
{
long size = readUint32();
- int start = count;
- long fieldCount = readUint32();
+ long count = readUint32();
Map<String,Object> result = new LinkedHashMap();
- while (count < start + size)
+ for (int i = 0; i < count; i++)
{
String key = readStr8();
byte code = get();
@@ -288,9 +249,9 @@ abstract class AbstractDecoder implements Decoder
public List<Object> readList()
{
long size = readUint32();
- int start = count;
+ long count = readUint32();
List<Object> result = new ArrayList();
- while (count < start + size)
+ for (int i = 0; i < count; i++)
{
byte code = get();
Type t = getType(code);
diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractEncoder.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractEncoder.java
index 4e9f918b61..aa90627943 100644
--- a/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractEncoder.java
+++ b/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractEncoder.java
@@ -75,13 +75,11 @@ abstract class AbstractEncoder implements Encoder
protected void put(byte b)
{
- flushBits();
doPut(b);
}
protected void put(ByteBuffer src)
{
- flushBits();
doPut(src);
}
@@ -90,39 +88,6 @@ abstract class AbstractEncoder implements Encoder
put(ByteBuffer.wrap(bytes));
}
- private byte bits = 0x0;
- private byte nbits = 0;
-
- public void writeBit(boolean b)
- {
- if (b)
- {
- bits |= 1 << nbits;
- }
-
- nbits += 1;
-
- if (nbits == 8)
- {
- flushBits();
- }
- }
-
- private void flushBits()
- {
- if (nbits > 0)
- {
- doPut(bits);
- bits = 0x0;
- nbits = 0;
- }
- }
-
- public void flush()
- {
- flushBits();
- }
-
public void writeUint8(short b)
{
assert b < 0x100;
@@ -406,6 +371,7 @@ abstract class AbstractEncoder implements Encoder
sizer.writeList(list);
// XXX: - 4
writeUint32(sizer.size() - 4);
+ writeUint32(list.size());
writeListEntries(list);
}
diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/Decoder.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/Decoder.java
index df2d208118..62abc74668 100644
--- a/java/common/src/main/java/org/apache/qpidity/transport/codec/Decoder.java
+++ b/java/common/src/main/java/org/apache/qpidity/transport/codec/Decoder.java
@@ -37,7 +37,6 @@ import org.apache.qpidity.transport.Struct;
public interface Decoder
{
- boolean readBit();
short readUint8();
int readUint16();
long readUint32();
diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/Encoder.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/Encoder.java
index 0449ba6702..9d7a1a695d 100644
--- a/java/common/src/main/java/org/apache/qpidity/transport/codec/Encoder.java
+++ b/java/common/src/main/java/org/apache/qpidity/transport/codec/Encoder.java
@@ -37,9 +37,6 @@ import org.apache.qpidity.transport.Struct;
public interface Encoder
{
- void flush();
-
- void writeBit(boolean b);
void writeUint8(short b);
void writeUint16(int s);
void writeUint32(long i);
diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/SizeEncoder.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/SizeEncoder.java
index 2c501a0746..2e7e883a0b 100644
--- a/java/common/src/main/java/org/apache/qpidity/transport/codec/SizeEncoder.java
+++ b/java/common/src/main/java/org/apache/qpidity/transport/codec/SizeEncoder.java
@@ -23,6 +23,9 @@ package org.apache.qpidity.transport.codec;
import java.nio.ByteBuffer;
import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpidity.transport.RangeSet;
/**
@@ -59,7 +62,6 @@ public class SizeEncoder extends AbstractEncoder implements Sizer
public int size()
{
- flush();
return getSize();
}
@@ -73,4 +75,60 @@ public class SizeEncoder extends AbstractEncoder implements Sizer
size += src.remaining();
}
+ public void writeUint8(short b)
+ {
+ size += 1;
+ }
+
+ public void writeUint16(int s)
+ {
+ size += 2;
+ }
+
+ public void writeUint32(long i)
+ {
+ size += 4;
+ }
+
+ public void writeUint64(long l)
+ {
+ size += 8;
+ }
+
+ public void writeDatetime(long l)
+ {
+ size += 8;
+ }
+
+ public void writeUuid(UUID uuid)
+ {
+ size += 16;
+ }
+
+ public void writeSequenceNo(int s)
+ {
+ size += 4;
+ }
+
+ public void writeSequenceSet(RangeSet ranges)
+ {
+ size += 2 + 8*ranges.size();
+ }
+
+ //void writeByteRanges(RangeSet ranges); // XXX
+
+ //void writeStr8(String s);
+ //void writeStr16(String s);
+
+ //void writeVbin8(byte[] bytes);
+ //void writeVbin16(byte[] bytes);
+ //void writeVbin32(byte[] bytes);
+
+ //void writeStruct32(Struct s);
+ //void writeMap(Map<String,Object> map);
+ //void writeList(List<Object> list);
+ //void writeArray(List<Object> array);
+
+ //void writeStruct(int type, Struct s);
+
}
diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/Sizer.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/Sizer.java
index 8ffdd5150b..d386987d64 100644
--- a/java/common/src/main/java/org/apache/qpidity/transport/codec/Sizer.java
+++ b/java/common/src/main/java/org/apache/qpidity/transport/codec/Sizer.java
@@ -38,9 +38,6 @@ public interface Sizer extends Encoder
public static final Sizer NULL = new Sizer()
{
- public void flush() {}
-
- public void writeBit(boolean b) {}
public void writeUint8(short b) {}
public void writeUint16(int s) {}
public void writeUint32(long i) {}
diff --git a/java/common/src/main/java/org/apache/qpidity/transport/network/Disassembler.java b/java/common/src/main/java/org/apache/qpidity/transport/network/Disassembler.java
index 0357df6e86..709b4f0e02 100644
--- a/java/common/src/main/java/org/apache/qpidity/transport/network/Disassembler.java
+++ b/java/common/src/main/java/org/apache/qpidity/transport/network/Disassembler.java
@@ -164,7 +164,6 @@ public class Disassembler implements Sender<ConnectionEvent>,
}
}
method.write(enc);
- enc.flush();
buf.flip();
byte flags = FIRST_SEG;
@@ -193,7 +192,6 @@ public class Disassembler implements Sender<ConnectionEvent>,
for (Struct st : header.getStructs())
{
enc.writeStruct32(st);
- enc.flush();
}
header.setBuf(buf);
}