2
0
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:
Ilya Maximets
2021-09-22 09:28:50 +02:00
parent 32b51326ef
commit 429b114c5a
12 changed files with 179 additions and 130 deletions

View File

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

View File

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