You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by gs...@apache.org on 2019/11/21 22:28:12 UTC

[qpid-proton] branch master updated: PROTON-2140: Lazy creation of various link related objects to reduce per-link memory overhead

This is an automated email from the ASF dual-hosted git repository.

gsim pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/qpid-proton.git


The following commit(s) were added to refs/heads/master by this push:
     new add5ed2  PROTON-2140: Lazy creation of various link related objects to reduce per-link memory overhead
add5ed2 is described below

commit add5ed2c4675d8138998ed421ba358731b729fc3
Author: Gordon Sim <gs...@redhat.com>
AuthorDate: Wed Nov 20 12:55:48 2019 +0000

    PROTON-2140: Lazy creation of various link related objects to reduce per-link memory overhead
---
 c/src/core/codec.c     | 88 ++++++++++++++++++++++++++++++++++++--------------
 c/src/core/engine.c    | 79 ++++++++++++++++++++++++++++++++++++--------
 c/src/core/transport.c | 10 ++++--
 3 files changed, 136 insertions(+), 41 deletions(-)

diff --git a/c/src/core/codec.c b/c/src/core/codec.c
index 300dd3d..cbc2360 100644
--- a/c/src/core/codec.c
+++ b/c/src/core/codec.c
@@ -364,6 +364,38 @@ static int pn_data_inspect(void *obj, pn_string_t *dst)
 #define pn_data_hashcode NULL
 #define pn_data_compare NULL
 
+static inline pn_string_t *pni_data_str(pn_data_t *data)
+{
+  if (data->str == NULL) {
+    data->str = pn_string(NULL);
+  }
+  return data->str;
+}
+
+static inline pn_decoder_t *pni_data_decoder(pn_data_t *data)
+{
+  if (data->decoder == NULL) {
+    data->decoder = pn_decoder();
+  }
+  return data->decoder;
+}
+
+static inline pn_encoder_t *pni_data_encoder(pn_data_t *data)
+{
+  if (data->encoder == NULL) {
+    data->encoder = pn_encoder();
+  }
+  return data->encoder;
+}
+
+static inline pn_error_t *pni_data_error(pn_data_t *data)
+{
+  if (data->error == NULL) {
+    data->error = pn_error();
+  }
+  return data->error;
+}
+
 pn_data_t *pn_data(size_t capacity)
 {
   static const pn_class_t clazz = PN_CLASS(pn_data);
@@ -371,15 +403,15 @@ pn_data_t *pn_data(size_t capacity)
   data->capacity = capacity;
   data->size = 0;
   data->nodes = capacity ? (pni_node_t *) malloc(capacity * sizeof(pni_node_t)) : NULL;
-  data->buf = pn_buffer(64);
+  data->buf = NULL;
   data->parent = 0;
   data->current = 0;
   data->base_parent = 0;
   data->base_current = 0;
-  data->decoder = pn_decoder();
-  data->encoder = pn_encoder();
-  data->error = pn_error();
-  data->str = pn_string(NULL);
+  data->decoder = NULL;
+  data->encoder = NULL;
+  data->error = NULL;
+  data->str = NULL;
   return data;
 }
 
@@ -390,12 +422,12 @@ void pn_data_free(pn_data_t *data)
 
 int pn_data_errno(pn_data_t *data)
 {
-  return pn_error_code(data->error);
+  return pn_error_code(pni_data_error(data));
 }
 
 pn_error_t *pn_data_error(pn_data_t *data)
 {
-  return data->error;
+  return pni_data_error(data);
 }
 
 size_t pn_data_size(pn_data_t *data)
@@ -411,7 +443,7 @@ void pn_data_clear(pn_data_t *data)
     data->current = 0;
     data->base_parent = 0;
     data->base_current = 0;
-    pn_buffer_clear(data->buf);
+    if (data->buf) pn_buffer_clear(data->buf);
   }
 }
 
@@ -431,6 +463,9 @@ static int pni_data_grow(pn_data_t *data)
 
 static ssize_t pni_data_intern(pn_data_t *data, const char *start, size_t size)
 {
+  if (data->buf == NULL) {
+    data->buf = pn_buffer(size);
+  }
   size_t offset = pn_buffer_size(data->buf);
   int err = pn_buffer_append(data->buf, start, size);
   if (err) return err;
@@ -465,6 +500,9 @@ static int pni_data_intern_node(pn_data_t *data, pni_node_t *node)
 {
   pn_bytes_t *bytes = pni_data_bytes(data, node);
   if (!bytes) return 0;
+  if (data->buf == NULL) {
+    data->buf = pn_buffer(bytes->size);
+  }
   size_t oldcap = pn_buffer_capacity(data->buf);
   ssize_t offset = pni_data_intern(data, bytes->start, bytes->size);
   if (offset < 0) return offset;
@@ -655,7 +693,7 @@ int pn_data_vfill(pn_data_t *data, const char *fmt, va_list ap)
         if (parent->atom.type == PN_ARRAY) {
           parent->type = (pn_type_t) va_arg(ap, int);
         } else {
-          return pn_error_format(data->error, PN_ERR, "naked type");
+          return pn_error_format(pni_data_error(data), PN_ERR, "naked type");
         }
       }
       break;
@@ -687,7 +725,7 @@ int pn_data_vfill(pn_data_t *data, const char *fmt, va_list ap)
     case '}':
     case ']':
       if (!pn_data_exit(data))
-        return pn_error_format(data->error, PN_ERR, "exit failed");
+        return pn_error_format(pni_data_error(data), PN_ERR, "exit failed");
       break;
     case '?':
       if (!va_arg(ap, int)) {
@@ -1123,7 +1161,7 @@ int pn_data_vscan(pn_data_t *data, const char *fmt, va_list ap)
     case '}':
       level--;
       if (!suspend && !pn_data_exit(data))
-        return pn_error_format(data->error, PN_ERR, "exit failed");
+        return pn_error_format(pni_data_error(data), PN_ERR, "exit failed");
       if (resume_count && level == count_level) resume_count--;
       break;
     case '.':
@@ -1133,7 +1171,7 @@ int pn_data_vscan(pn_data_t *data, const char *fmt, va_list ap)
       break;
     case '?':
       if (!*fmt || *fmt == '?')
-        return pn_error_format(data->error, PN_ARG_ERR, "codes must follow a ?");
+        return pn_error_format(pni_data_error(data), PN_ARG_ERR, "codes must follow a ?");
       scanarg = va_arg(ap, bool *);
       break;
     case 'C':
@@ -1159,7 +1197,7 @@ int pn_data_vscan(pn_data_t *data, const char *fmt, va_list ap)
       if (resume_count && level == count_level) resume_count--;
       break;
     default:
-      return pn_error_format(data->error, PN_ARG_ERR, "unrecognized scan code: 0x%.2X '%c'", code, code);
+      return pn_error_format(pni_data_error(data), PN_ARG_ERR, "unrecognized scan code: 0x%.2X '%c'", code, code);
     }
 
     if (scanarg && code != '?') {
@@ -1182,16 +1220,16 @@ int pn_data_scan(pn_data_t *data, const char *fmt, ...)
 
 static int pni_data_inspectify(pn_data_t *data)
 {
-  int err = pn_string_set(data->str, "");
+  int err = pn_string_set(pni_data_str(data), "");
   if (err) return err;
-  return pn_data_inspect(data, data->str);
+  return pn_data_inspect(data, pni_data_str(data));
 }
 
 int pn_data_print(pn_data_t *data)
 {
   int err = pni_data_inspectify(data);
   if (err) return err;
-  printf("%s", pn_string_get(data->str));
+  printf("%s", pn_string_get(pni_data_str(data)));
   return 0;
 }
 
@@ -1199,11 +1237,11 @@ int pn_data_format(pn_data_t *data, char *bytes, size_t *size)
 {
   int err = pni_data_inspectify(data);
   if (err) return err;
-  if (pn_string_size(data->str) >= *size) {
+  if (pn_string_size(pni_data_str(data)) >= *size) {
     return PN_OVERFLOW;
   } else {
-    pn_string_put(data->str, bytes);
-    *size = pn_string_size(data->str);
+    pn_string_put(pni_data_str(data), bytes);
+    *size = pn_string_size(pni_data_str(data));
     return 0;
   }
 }
@@ -1447,8 +1485,8 @@ void pn_data_dump(pn_data_t *data)
   for (unsigned i = 0; i < data->size; i++)
   {
     pni_node_t *node = &data->nodes[i];
-    pn_string_set(data->str, "");
-    pni_inspect_atom((pn_atom_t *) &node->atom, data->str);
+    pn_string_set(pni_data_str(data), "");
+    pni_inspect_atom((pn_atom_t *) &node->atom, pni_data_str(data));
     printf("Node %i: prev=%" PN_ZI ", next=%" PN_ZI ", parent=%" PN_ZI ", down=%" PN_ZI 
            ", children=%" PN_ZI ", type=%s (%s)\n",
            i + 1, (size_t) node->prev,
@@ -1456,7 +1494,7 @@ void pn_data_dump(pn_data_t *data)
            (size_t) node->parent,
            (size_t) node->down,
            (size_t) node->children,
-           pn_type_name(node->atom.type), pn_string_get(data->str));
+           pn_type_name(node->atom.type), pn_string_get(pni_data_str(data)));
   }
 }
 
@@ -1522,17 +1560,17 @@ static pni_node_t *pni_data_add(pn_data_t *data)
 
 ssize_t pn_data_encode(pn_data_t *data, char *bytes, size_t size)
 {
-  return pn_encoder_encode(data->encoder, data, bytes, size);
+  return pn_encoder_encode(pni_data_encoder(data), data, bytes, size);
 }
 
 ssize_t pn_data_encoded_size(pn_data_t *data)
 {
-  return pn_encoder_size(data->encoder, data);
+  return pn_encoder_size(pni_data_encoder(data), data);
 }
 
 ssize_t pn_data_decode(pn_data_t *data, const char *bytes, size_t size)
 {
-  return pn_decoder_decode(data->decoder, bytes, size, data);
+  return pn_decoder_decode(pni_data_decoder(data), bytes, size, data);
 }
 
 int pn_data_put_list(pn_data_t *data)
diff --git a/c/src/core/engine.c b/c/src/core/engine.c
index e70117e..3c3c24c 100644
--- a/c/src/core/engine.c
+++ b/c/src/core/engine.c
@@ -203,9 +203,9 @@ pn_transport_t *pn_connection_transport(pn_connection_t *connection)
 
 void pn_condition_init(pn_condition_t *condition)
 {
-  condition->name = pn_string(NULL);
-  condition->description = pn_string(NULL);
-  condition->info = pn_data(0);
+  condition->name = NULL;
+  condition->description = NULL;
+  condition->info = NULL;
 }
 
 pn_condition_t *pn_condition() {
@@ -2123,39 +2123,57 @@ pn_condition_t *pn_link_remote_condition(pn_link_t *link)
 
 bool pn_condition_is_set(pn_condition_t *condition)
 {
-  return condition && pn_string_get(condition->name);
+  return condition && condition->name && pn_string_get(condition->name);
 }
 
 void pn_condition_clear(pn_condition_t *condition)
 {
   assert(condition);
-  pn_string_clear(condition->name);
-  pn_string_clear(condition->description);
-  pn_data_clear(condition->info);
+  if (condition->name) pn_string_clear(condition->name);
+  if (condition->description) pn_string_clear(condition->description);
+  if (condition->info) pn_data_clear(condition->info);
 }
 
 const char *pn_condition_get_name(pn_condition_t *condition)
 {
   assert(condition);
-  return pn_string_get(condition->name);
+  if (condition->name == NULL) {
+    return NULL;
+  } else {
+    return pn_string_get(condition->name);
+  }
 }
 
 int pn_condition_set_name(pn_condition_t *condition, const char *name)
 {
   assert(condition);
-  return pn_string_set(condition->name, name);
+  if (condition->name == NULL) {
+    condition->name = pn_string(name);
+    return 0;
+  } else {
+    return pn_string_set(condition->name, name);
+  }
 }
 
 const char *pn_condition_get_description(pn_condition_t *condition)
 {
   assert(condition);
-  return pn_string_get(condition->description);
+  if (condition->description == NULL) {
+    return NULL;
+  } else {
+    return pn_string_get(condition->description);
+  }
 }
 
 int pn_condition_set_description(pn_condition_t *condition, const char *description)
 {
   assert(condition);
-  return pn_string_set(condition->description, description);
+  if (condition->description == NULL) {
+    condition->description = pn_string(description);
+    return 0;
+  } else {
+    return pn_string_set(condition->description, description);
+  }
 }
 
 int pn_condition_vformat(pn_condition_t *condition, const char *name, const char *fmt, va_list ap)
@@ -2186,6 +2204,9 @@ int pn_condition_format(pn_condition_t *condition, const char *name, const char
 pn_data_t *pn_condition_info(pn_condition_t *condition)
 {
   assert(condition);
+  if (condition->info == NULL) {
+    condition->info = pn_data(0);
+  }
   return condition->info;
 }
 
@@ -2299,9 +2320,39 @@ int pn_condition_copy(pn_condition_t *dest, pn_condition_t *src) {
   assert(src);
   int err = 0;
   if (src != dest) {
-    err = pn_string_copy(dest->name, src->name);
-    if (!err) err = pn_string_copy(dest->description, src->description);
-    if (!err) err = pn_data_copy(dest->info, src->info);
+    if (!(src->name == NULL && dest->name == NULL)) {
+      if (src->name == NULL) {
+        pn_free(dest->name);
+        dest->name = NULL;
+      } else {
+        if (dest->name == NULL) {
+          dest->name = pn_string(NULL);
+        }
+        err = pn_string_copy(dest->name, src->name);
+      }
+    }
+    if (!err && !(src->description == NULL && dest->description == NULL)) {
+      if (src->description == NULL) {
+        pn_free(dest->description);
+        dest->description = NULL;
+      } else {
+        if (dest->description == NULL) {
+          dest->description = pn_string(NULL);
+        }
+        err = pn_string_copy(dest->description, src->description);
+      }
+    }
+    if (!err && !(src->info == NULL && dest->info == NULL)) {
+      if (src->info == NULL) {
+        pn_data_free(dest->info);
+        dest->info = NULL;
+      } else {
+        if (dest->info == NULL) {
+          dest->info = pn_data(0);
+        }
+        err = pn_data_copy(dest->info, src->info);
+      }
+    }
   }
   return err;
 }
diff --git a/c/src/core/transport.c b/c/src/core/transport.c
index 4dea853..0a930ae 100644
--- a/c/src/core/transport.c
+++ b/c/src/core/transport.c
@@ -1617,11 +1617,17 @@ static int pn_scan_error(pn_data_t *data, pn_condition_t *condition, const char
   pn_bytes_t cond;
   pn_bytes_t desc;
   pn_condition_clear(condition);
-  int err = pn_data_scan(data, fmt, &cond, &desc, condition->info);
+  int err = pn_data_scan(data, fmt, &cond, &desc, pn_condition_info(condition));
   if (err) return err;
+  if (condition->name == NULL) {
+    condition->name = pn_string(NULL);
+  }
   pn_string_setn(condition->name, cond.start, cond.size);
+  if (condition->description == NULL) {
+    condition->description = pn_string(NULL);
+  }
   pn_string_setn(condition->description, desc.start, desc.size);
-  pn_data_rewind(condition->info);
+  pn_data_rewind(pn_condition_info(condition));
   return 0;
 }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org