diff options
author | Rafael H. Schloming <rhs@apache.org> | 2008-06-03 17:54:45 +0000 |
---|---|---|
committer | Rafael H. Schloming <rhs@apache.org> | 2008-06-03 17:54:45 +0000 |
commit | f081132e845b3ae92aa08ef3996ec29a2f6de2ed (patch) | |
tree | 7b190b5429d1d0fd48f846f4a68f3c34fd33515d | |
parent | 83a3dc24856d12270c71fd56dd983769179e0727 (diff) | |
download | qpid-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
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); } |