[libvirt] [PATCH 3/5] blockjob: optimize JSON event handler lookup

Daniel Veillard veillard at redhat.com
Thu Apr 12 01:15:59 UTC 2012


On Wed, Apr 11, 2012 at 05:40:36PM -0600, Eric Blake wrote:
> Probably in the noise, but this will let us scale more efficiently
> as we recognize ever more qemu events.

  s/ever/even/

> * src/qemu/qemu_monitor_json.c (eventHandlers): Sort.
> (eventSearch): New helper function.
> (qemuMonitorJSONIOProcessEvent): Optimize event lookup.
> ---
>  src/qemu/qemu_monitor_json.c |   54 ++++++++++++++++++++++++------------------
>  1 files changed, 31 insertions(+), 23 deletions(-)
> 
> diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
> index d4d2c3e..f7d9ef2 100644
> --- a/src/qemu/qemu_monitor_json.c
> +++ b/src/qemu/qemu_monitor_json.c
> @@ -66,36 +66,45 @@ static void qemuMonitorJSONHandleTrayChange(qemuMonitorPtr mon, virJSONValuePtr
>  static void qemuMonitorJSONHandlePMWakeup(qemuMonitorPtr mon, virJSONValuePtr data);
>  static void qemuMonitorJSONHandlePMSuspend(qemuMonitorPtr mon, virJSONValuePtr data);
> 
> -static struct {
> +typedef struct {
>      const char *type;
>      void (*handler)(qemuMonitorPtr mon, virJSONValuePtr data);
> -} eventHandlers[] = {
> -    { "SHUTDOWN", qemuMonitorJSONHandleShutdown, },
> -    { "RESET", qemuMonitorJSONHandleReset, },
> -    { "POWERDOWN", qemuMonitorJSONHandlePowerdown, },
> -    { "STOP", qemuMonitorJSONHandleStop, },
> -    { "RTC_CHANGE", qemuMonitorJSONHandleRTCChange, },
> -    { "WATCHDOG", qemuMonitorJSONHandleWatchdog, },
> +} qemuEventHandler;
> +static qemuEventHandler eventHandlers[] = {
>      { "BLOCK_IO_ERROR", qemuMonitorJSONHandleIOError, },
> -    { "VNC_CONNECTED", qemuMonitorJSONHandleVNCConnect, },
> -    { "VNC_INITIALIZED", qemuMonitorJSONHandleVNCInitialize, },
> -    { "VNC_DISCONNECTED", qemuMonitorJSONHandleVNCDisconnect, },
>      { "BLOCK_JOB_COMPLETED", qemuMonitorJSONHandleBlockJob, },
> +    { "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange, },
> +    { "POWERDOWN", qemuMonitorJSONHandlePowerdown, },
> +    { "RESET", qemuMonitorJSONHandleReset, },
> +    { "RTC_CHANGE", qemuMonitorJSONHandleRTCChange, },
> +    { "SHUTDOWN", qemuMonitorJSONHandleShutdown, },
>      { "SPICE_CONNECTED", qemuMonitorJSONHandleSPICEConnect, },
> -    { "SPICE_INITIALIZED", qemuMonitorJSONHandleSPICEInitialize, },
>      { "SPICE_DISCONNECTED", qemuMonitorJSONHandleSPICEDisconnect, },
> -    { "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange, },
> -    { "WAKEUP", qemuMonitorJSONHandlePMWakeup, },
> +    { "SPICE_INITIALIZED", qemuMonitorJSONHandleSPICEInitialize, },
> +    { "STOP", qemuMonitorJSONHandleStop, },
>      { "SUSPEND", qemuMonitorJSONHandlePMSuspend, },
> +    { "VNC_CONNECTED", qemuMonitorJSONHandleVNCConnect, },
> +    { "VNC_DISCONNECTED", qemuMonitorJSONHandleVNCDisconnect, },
> +    { "VNC_INITIALIZED", qemuMonitorJSONHandleVNCInitialize, },
> +    { "WAKEUP", qemuMonitorJSONHandlePMWakeup, },
> +    { "WATCHDOG", qemuMonitorJSONHandleWatchdog, },
> +    /* We use bsearch, so keep this list sorted.  */
>  };
> 
> +static int
> +qemuMonitorEventCompare(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");
> @@ -105,14 +114,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]), qemuMonitorEventCompare);
> +    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;
>  }

  Okay, this should speed up the lookups somehow. I also appreciate
  separating the type and the array variable declaration,

  ACK

Daniel

-- 
Daniel Veillard      | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
daniel at veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/




More information about the libvir-list mailing list