[libvirt] [PATCH] qemu: optimize JSON event handler lookup

Eric Blake eblake at redhat.com
Tue Apr 10 22:47:50 UTC 2012


Probably in the noise, but this will let us scale more efficiently
as we recognize ever more qemu events.

* src/qemu/qemu_monitor_json.c (eventHandlers): Sort.
(eventSearch): New helper function.
(qemuMonitorJSONIOProcessEvent): Optimize event lookup.
---

In reply to:
https://www.redhat.com/archives/libvir-list/2012-April/msg00416.html

 src/qemu/qemu_monitor_json.c |   55 +++++++++++++++++++++++------------------
 1 files changed, 31 insertions(+), 24 deletions(-)

diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 7c893d4..d142517 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -67,37 +67,45 @@ static void qemuMonitorJSONHandlePMSuspend(qemuMonitorPtr mon, virJSONValuePtr d
 static void qemuMonitorJSONHandleBlockJobCompleted(qemuMonitorPtr mon, virJSONValuePtr data);
 static void qemuMonitorJSONHandleBlockJobCanceled(qemuMonitorPtr mon, virJSONValuePtr data);

-static struct {
+typedef struct {
     const char *type;
     void (*handler)(qemuMonitorPtr mon, virJSONValuePtr data);
-} eventHandlers[] = {
-    { "SHUTDOWN", qemuMonitorJSONHandleShutdown, },
-    { "RESET", qemuMonitorJSONHandleReset, },
+} qemuEventHandler;
+static qemuEventHandler eventHandlers[] = {
+    { "BLOCK_IO_ERROR", qemuMonitorJSONHandleIOError, },
+    { "BLOCK_JOB_CANCELLED", qemuMonitorJSONHandleBlockJobCanceled, },
+    { "BLOCK_JOB_COMPLETED", qemuMonitorJSONHandleBlockJobCompleted, },
+    { "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange, },
     { "POWERDOWN", qemuMonitorJSONHandlePowerdown, },
-    { "STOP", qemuMonitorJSONHandleStop, },
+    { "RESET", qemuMonitorJSONHandleReset, },
     { "RTC_CHANGE", qemuMonitorJSONHandleRTCChange, },
-    { "WATCHDOG", qemuMonitorJSONHandleWatchdog, },
-    { "BLOCK_IO_ERROR", qemuMonitorJSONHandleIOError, },
-    { "VNC_CONNECTED", qemuMonitorJSONHandleVNCConnect, },
-    { "VNC_INITIALIZED", qemuMonitorJSONHandleVNCInitialize, },
-    { "VNC_DISCONNECTED", qemuMonitorJSONHandleVNCDisconnect, },
+    { "SHUTDOWN", qemuMonitorJSONHandleShutdown, },
     { "SPICE_CONNECTED", qemuMonitorJSONHandleSPICEConnect, },
-    { "SPICE_INITIALIZED", qemuMonitorJSONHandleSPICEInitialize, },
     { "SPICE_DISCONNECTED", qemuMonitorJSONHandleSPICEDisconnect, },
-    { "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange, },
-    { "WAKEUP", qemuMonitorJSONHandlePMWakeup, },
+    { "SPICE_INITIALIZED", qemuMonitorJSONHandleSPICEInitialize, },
+    { "STOP", qemuMonitorJSONHandleStop, },
     { "SUSPEND", qemuMonitorJSONHandlePMSuspend, },
-    { "BLOCK_JOB_COMPLETED", qemuMonitorJSONHandleBlockJobCompleted, },
-    { "BLOCK_JOB_CANCELLED", qemuMonitorJSONHandleBlockJobCanceled, },
+    { "VNC_CONNECTED", qemuMonitorJSONHandleVNCConnect, },
+    { "VNC_DISCONNECTED", qemuMonitorJSONHandleVNCDisconnect, },
+    { "VNC_INITIALIZED", qemuMonitorJSONHandleVNCInitialize, },
+    { "WAKEUP", qemuMonitorJSONHandlePMWakeup, },
+    { "WATCHDOG", qemuMonitorJSONHandleWatchdog, },
+    /* We use bsearch, so keep this list sorted.  */
 };

+static int
+eventSearch(const void *key, const void *elt) {
+    const char *type = key;
+    const qemuEventHandler *handler = elt;
+    return strcmp(type, handler->type);
+}

 static int
 qemuMonitorJSONIOProcessEvent(qemuMonitorPtr mon,
                               virJSONValuePtr obj)
 {
     const char *type;
-    int i;
+    qemuEventHandler *handler;
     VIR_DEBUG("mon=%p obj=%p", mon, obj);

     type = virJSONValueObjectGetString(obj, "event");
@@ -107,14 +115,13 @@ qemuMonitorJSONIOProcessEvent(qemuMonitorPtr mon,
         return -1;
     }

-    for (i = 0 ; i < ARRAY_CARDINALITY(eventHandlers) ; i++) {
-        if (STREQ(eventHandlers[i].type, type)) {
-            virJSONValuePtr data = virJSONValueObjectGet(obj, "data");
-            VIR_DEBUG("handle %s handler=%p data=%p", type,
-                      eventHandlers[i].handler, data);
-            (eventHandlers[i].handler)(mon, data);
-            break;
-        }
+    handler = bsearch(type, eventHandlers, ARRAY_CARDINALITY(eventHandlers),
+                      sizeof(eventHandlers[0]), eventSearch);
+    if (handler) {
+        virJSONValuePtr data = virJSONValueObjectGet(obj, "data");
+        VIR_DEBUG("handle %s handler=%p data=%p", type,
+                  handler->handler, data);
+        (handler->handler)(mon, data);
     }
     return 0;
 }
-- 
1.7.7.6




More information about the libvir-list mailing list