DbListCommand taking too long when there's too many records
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
ovsdbapp |
Fix Released
|
Undecided
|
Daniel Alvarez |
Bug Description
When there are too many records and we call DbListCommand it's very likely to get a timeout exception. This is mainly because that it can be an O(n^2) operation as it will go through all the passed in records to retrieve the uuids and this operation goes through all the existing rows of the table to match by the index column.
ie.
for record in self.records:
row_
|
-> row_by_value() (which iterates over all elements in the table and calls Row.getattr() that can be costly [0] as it's converting to/from Datum/Atom and creating new objects).
This O(n^2) operation can be avoided if we simply retrieve all the elements and remove all those present in the passed in arguments making the method be O(n).
For example, with 2000 ports, the following code takes 8 seconds:
import logging
from ovs.db import idl
from ovsdbapp.
from ovsdbapp.
from ovsdbapp.
TIMEOUT_SEC = 3600
def connect():
connection_
helper = idlutils.
tables = ('Open_vSwitch', 'Bridge', 'Port', 'Interface')
for table in tables:
ovs_idl = idl.Idl(
conn = connection.
return idl_ovs.
def get_port_
return ovs_idl.
def main():
ovs_idl = connect()
port_names = get_port_
ovs_
if __name__ == "__main__":
logging.
main()
# time python dblist.py
Loop took 8.09
real 0m12.781s
user 0m12.242s
sys 0m0.166s
And with the optimizations (I'll propose the patch now):
# time python dblist.py
Loop took 0.15
real 0m4.577s
user 0m4.269s
sys 0m0.126s
[0] https:/
Changed in ovsdbapp: | |
assignee: | nobody → Daniel Alvarez (dalvarezs) |
For ocata, addressed by https:/ /review. openstack. org/#/c/ 566912