mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 22:35:15 +00:00
ovsdb-data: Deduplicate string atoms.
ovsdb-server spends a lot of time cloning atoms for various reasons, e.g. to create a diff of two rows or to clone a row to the transaction. All atoms, except for strings, contains a simple value that could be copied in efficient way, but duplicating strings every time has a significant performance impact. Introducing a new reference-counted structure 'ovsdb_atom_string' that allows to not copy strings every time, but just increase a reference counter. This change allows to increase transaction throughput in benchmarks up to 2x for standalone databases and 3x for clustered databases, i.e. number of transactions that ovsdb-server can handle per second. It also noticeably reduces memory consumption of ovsdb-server. Next step will be to consolidate this structure with json strings, so we will not need to duplicate strings while converting database objects to json and back. Signed-off-by: Ilya Maximets <i.maximets@ovn.org> Acked-by: Dumitru Ceara <dceara@redhat.com> Acked-by: Mark D. Gray <mark.d.gray@redhat.com>
This commit is contained in:
@@ -204,7 +204,7 @@ class Atom(object):
|
||||
else:
|
||||
return '.boolean = false'
|
||||
elif self.type == ovs.db.types.StringType:
|
||||
return '.string = "%s"' % escapeCString(self.value)
|
||||
return '.s = %s' % escapeCString(self.value)
|
||||
elif self.type == ovs.db.types.UuidType:
|
||||
return '.uuid = %s' % ovs.ovsuuid.to_c_assignment(self.value)
|
||||
|
||||
@@ -563,16 +563,41 @@ class Datum(object):
|
||||
if n == 0:
|
||||
return ["static struct ovsdb_datum %s = { .n = 0 };"]
|
||||
|
||||
s = ["static union ovsdb_atom %s_keys[%d] = {" % (name, n)]
|
||||
for key in sorted(self.values):
|
||||
s += [" { %s }," % key.cInitAtom(key)]
|
||||
s += ["};"]
|
||||
s = []
|
||||
if self.type.key.type == ovs.db.types.StringType:
|
||||
s += ["static struct ovsdb_atom_string %s_key_strings[%d] = {"
|
||||
% (name, n)]
|
||||
for key in sorted(self.values):
|
||||
s += [' { .string = "%s", .n_refs = 2 },'
|
||||
% escapeCString(key.value)]
|
||||
s += ["};"]
|
||||
s += ["static union ovsdb_atom %s_keys[%d] = {" % (name, n)]
|
||||
for i in range(n):
|
||||
s += [" { .s = &%s_key_strings[%d] }," % (name, i)]
|
||||
s += ["};"]
|
||||
else:
|
||||
s = ["static union ovsdb_atom %s_keys[%d] = {" % (name, n)]
|
||||
for key in sorted(self.values):
|
||||
s += [" { %s }," % key.cInitAtom(key)]
|
||||
s += ["};"]
|
||||
|
||||
if self.type.value:
|
||||
s = ["static union ovsdb_atom %s_values[%d] = {" % (name, n)]
|
||||
for k, v in sorted(self.values.items()):
|
||||
s += [" { %s }," % v.cInitAtom(v)]
|
||||
s += ["};"]
|
||||
if self.type.value.type == ovs.db.types.StringType:
|
||||
s += ["static struct ovsdb_atom_string %s_val_strings[%d] = {"
|
||||
% (name, n)]
|
||||
for k, v in sorted(self.values):
|
||||
s += [' { .string = "%s", .n_refs = 2 },'
|
||||
% escapeCString(v.value)]
|
||||
s += ["};"]
|
||||
s += ["static union ovsdb_atom %s_values[%d] = {" % (name, n)]
|
||||
for i in range(n):
|
||||
s += [" { .s = &%s_val_strings[%d] }," % (name, i)]
|
||||
s += ["};"]
|
||||
else:
|
||||
s = ["static union ovsdb_atom %s_values[%d] = {" % (name, n)]
|
||||
for k, v in sorted(self.values.items()):
|
||||
s += [" { %s }," % v.cInitAtom(v)]
|
||||
s += ["};"]
|
||||
|
||||
s += ["static struct ovsdb_datum %s = {" % name]
|
||||
s += [" .n = %d," % n]
|
||||
|
@@ -48,6 +48,16 @@ class AtomicType(object):
|
||||
def to_string(self):
|
||||
return self.name
|
||||
|
||||
def to_rvalue_string(self):
|
||||
if self == StringType:
|
||||
return 's->' + self.name
|
||||
return self.name
|
||||
|
||||
def to_lvalue_string(self):
|
||||
if self == StringType:
|
||||
return 's'
|
||||
return self.name
|
||||
|
||||
def to_json(self):
|
||||
return self.name
|
||||
|
||||
@@ -373,18 +383,7 @@ class BaseType(object):
|
||||
return "%(dst)s = *%(src)s;" % args
|
||||
return ("%(dst)s = %(src)s->header_.uuid;") % args
|
||||
elif self.type == StringType:
|
||||
return "%(dst)s = xstrdup(%(src)s);" % args
|
||||
else:
|
||||
return "%(dst)s = %(src)s;" % args
|
||||
|
||||
def assign_c_value_casting_away_const(self, dst, src, refTable=True):
|
||||
args = {'dst': dst, 'src': src}
|
||||
if self.ref_table_name:
|
||||
if not refTable:
|
||||
return "%(dst)s = *%(src)s;" % args
|
||||
return ("%(dst)s = %(src)s->header_.uuid;") % args
|
||||
elif self.type == StringType:
|
||||
return "%(dst)s = CONST_CAST(char *, %(src)s);" % args
|
||||
return "%(dst)s = ovsdb_atom_string_create(%(src)s);" % args
|
||||
else:
|
||||
return "%(dst)s = %(src)s;" % args
|
||||
|
||||
|
Reference in New Issue
Block a user