[CalendarServer-changes] [1364] CalendarServer/branches/users/cdaboo/performance-1354/twistedcaldav

source_changes at macosforge.org source_changes at macosforge.org
Tue Mar 13 10:26:56 PDT 2007


Revision: 1364
          http://trac.macosforge.org/projects/calendarserver/changeset/1364
Author:   cdaboo at apple.com
Date:     2007-03-13 10:26:55 -0700 (Tue, 13 Mar 2007)

Log Message:
-----------
Speed up free-busy request SQL query by aggregating the component type query expression into a list of types
which can be translated into an SQL "IN" expression.

Modified Paths:
--------------
    CalendarServer/branches/users/cdaboo/performance-1354/twistedcaldav/caldavxml.py
    CalendarServer/branches/users/cdaboo/performance-1354/twistedcaldav/method/report_common.py
    CalendarServer/branches/users/cdaboo/performance-1354/twistedcaldav/query/calendarquery.py
    CalendarServer/branches/users/cdaboo/performance-1354/twistedcaldav/query/expression.py
    CalendarServer/branches/users/cdaboo/performance-1354/twistedcaldav/query/sqlgenerator.py

Modified: CalendarServer/branches/users/cdaboo/performance-1354/twistedcaldav/caldavxml.py
===================================================================
--- CalendarServer/branches/users/cdaboo/performance-1354/twistedcaldav/caldavxml.py	2007-03-13 01:13:54 UTC (rev 1363)
+++ CalendarServer/branches/users/cdaboo/performance-1354/twistedcaldav/caldavxml.py	2007-03-13 17:26:55 UTC (rev 1364)
@@ -182,6 +182,8 @@
         self.qualifier   = qualifier
         self.filters     = filters
         self.filter_name = attributes["name"]
+        if isinstance(self.filter_name, unicode):
+            self.filter_name = self.filter_name.encode("utf-8")
         self.defined     = not self.qualifier or (self.qualifier.qname() != (caldav_namespace, "is-not-defined"))
 
     def match(self, item):
@@ -843,7 +845,10 @@
     def _match(self, component):
         # At least one subcomponent must match (or is-not-defined is set)
         for subcomponent in component.subcomponents():
-            if subcomponent.name() != self.filter_name: continue
+            if isinstance(self.filter_name, str):
+                if subcomponent.name() != self.filter_name: continue
+            else:
+                if subcomponent.name() not in self.filter_name: continue
             if self.match(subcomponent): break
         else:
             return not self.defined

Modified: CalendarServer/branches/users/cdaboo/performance-1354/twistedcaldav/method/report_common.py
===================================================================
--- CalendarServer/branches/users/cdaboo/performance-1354/twistedcaldav/method/report_common.py	2007-03-13 01:13:54 UTC (rev 1363)
+++ CalendarServer/branches/users/cdaboo/performance-1354/twistedcaldav/method/report_common.py	2007-03-13 17:26:55 UTC (rev 1364)
@@ -294,16 +294,8 @@
                   caldavxml.ComponentFilter(
                       caldavxml.ComponentFilter(
                           timerange,
-                          name="VEVENT",
+                          name=("VEVENT", "VFREEBUSY", "VAVAILABILITY"),
                       ),
-                      caldavxml.ComponentFilter(
-                          timerange,
-                          name="VFREEBUSY",
-                      ),
-                      caldavxml.ComponentFilter(
-                          timerange,
-                          name="VAVAILABILITY",
-                      ),
                       name="VCALENDAR",
                    )
               )

Modified: CalendarServer/branches/users/cdaboo/performance-1354/twistedcaldav/query/calendarquery.py
===================================================================
--- CalendarServer/branches/users/cdaboo/performance-1354/twistedcaldav/query/calendarquery.py	2007-03-13 01:13:54 UTC (rev 1363)
+++ CalendarServer/branches/users/cdaboo/performance-1354/twistedcaldav/query/calendarquery.py	2007-03-13 17:26:55 UTC (rev 1364)
@@ -90,7 +90,10 @@
         return expression.isnotExpression(FIELD_TYPE, compfilter.filter_name, True)
         
     expressions = []
-    expressions.append(expression.isExpression(FIELD_TYPE, compfilter.filter_name, True))
+    if isinstance(compfilter.filter_name, str):
+        expressions.append(expression.isExpression(FIELD_TYPE, compfilter.filter_name, True))
+    else:
+        expressions.append(expression.inExpression(FIELD_TYPE, compfilter.filter_name, True))
     
     # Handle time-range    
     if compfilter.qualifier and isinstance(compfilter.qualifier, caldavxml.TimeRange):
@@ -226,7 +229,7 @@
                  caldavxml.ComponentFilter(
                      *[caldavxml.ComponentFilter(
                            *[caldavxml.TimeRange(**{"start":"20060605T160000Z", "end":"20060605T170000Z"})],
-                           **{"name":"VEVENT"}
+                           **{"name":("VEVENT", "VFREEBUSY", "VAVAILABILITY")}
                        )],
                      **{"name":"VCALENDAR"}
                  )

Modified: CalendarServer/branches/users/cdaboo/performance-1354/twistedcaldav/query/expression.py
===================================================================
--- CalendarServer/branches/users/cdaboo/performance-1354/twistedcaldav/query/expression.py	2007-03-13 01:13:54 UTC (rev 1363)
+++ CalendarServer/branches/users/cdaboo/performance-1354/twistedcaldav/query/expression.py	2007-03-13 17:26:55 UTC (rev 1364)
@@ -30,6 +30,9 @@
     "timerangeExpression",
     "containsExpression",
     "isExpression",
+    "isnotExpression",
+    "inExpression",
+    "notinExpression",
 ]
 
 class baseExpression(object):
@@ -213,12 +216,44 @@
     def operator(self):
         return "is not"
 
+class inExpression(textcompareExpression):
+    """
+    Text IN (exact string match to one of the supplied items) expression.
+    """
+    
+    def __init__(self, field, text_list, caseless):
+        super(inExpression, self).__init__(field, text_list, caseless)
+
+    def operator(self):
+        return "in"
+
+    def __str__(self):
+        return self.operator() + "(" + self.field + ", " + str(self.text) + ", " + str(self.caseless) + ")"
+
+class notinExpression(textcompareExpression):
+    """
+    Text NOT IN (exact string match to none of the supplied items) expression.
+    """
+    
+    def __init__(self, field, text, caseless):
+        super(notinExpression, self).__init__(field, text, caseless)
+
+    def operator(self):
+        return "not in"
+
+    def __str__(self):
+        return self.operator() + "(" + self.field + ", " + str(self.text) + ", " + str(self.caseless) + ")"
+
 if __name__ == "__main__":
     
     e1 = isExpression("type", "vevent", False)
-    e2 = timerangeExpression("20060101T120000Z", "20060101T130000Z")
+    e2 = timerangeExpression("20060101T120000Z", "20060101T130000Z", "20060101T120000Z", "20060101T130000Z")
     e3 = containsExpression("summary", "help", True)
     e4 = notExpression(e3)
     e5 = andExpression([e1, e2, e4])
     print e5
+    e6 = inExpression("type", ("vevent", "vtodo",), False)
+    print e6
+    e7 = notinExpression("type", ("vevent", "vtodo",), False)
+    print e7
 

Modified: CalendarServer/branches/users/cdaboo/performance-1354/twistedcaldav/query/sqlgenerator.py
===================================================================
--- CalendarServer/branches/users/cdaboo/performance-1354/twistedcaldav/query/sqlgenerator.py	2007-03-13 01:13:54 UTC (rev 1363)
+++ CalendarServer/branches/users/cdaboo/performance-1354/twistedcaldav/query/sqlgenerator.py	2007-03-13 17:26:55 UTC (rev 1364)
@@ -43,6 +43,8 @@
     NOTCONTAINSOP = " NOT GLOB "
     ISOP          = " == "
     ISNOTOP       = " != "
+    INOP          = " IN "
+    NOTINOP       = " NOT IN "
 
     TIMESPANTEST  = "((TIMESPAN.FLOAT == 'N' AND TIMESPAN.START < %s AND TIMESPAN.END > %s) OR (TIMESPAN.FLOAT == 'Y' AND TIMESPAN.START < %s AND TIMESPAN.END > %s)) AND TIMESPAN.NAME == RESOURCE.NAME"
 
@@ -149,6 +151,28 @@
             self.sout.write(expr.field)
             self.sout.write(self.ISNOTOP)
             self.addArgument(expr.text)
+        
+        # IN
+        elif isinstance(expr, expression.inExpression):
+            self.sout.write(expr.field)
+            self.sout.write(self.INOP)
+            self.sout.write("(")
+            for count, item in enumerate(expr.text):
+                if count != 0:
+                    self.sout.write(", ")
+                self.addArgument(item)
+            self.sout.write(")")
+        
+        # NOT IN
+        elif isinstance(expr, expression.notinExpression):
+            self.sout.write(expr.field)
+            self.sout.write(self.NOTINOP)
+            self.sout.write("(")
+            for count, item in enumerate(expr.text):
+                if count != 0:
+                    self.sout.write(", ")
+                self.addArgument(item)
+            self.sout.write(")")
 
     def generateSubExpression(self, expression):
         """
@@ -195,3 +219,11 @@
     print e5
     sql = sqlgenerator(e5)
     print sql.generate()
+    e6 = expression.inExpression("TYPE", ("VEVENT", "VTODO",), False)
+    print e6
+    sql = sqlgenerator(e6)
+    print sql.generate()
+    e7 = expression.notinExpression("TYPE", ("VEVENT", "VTODO",), False)
+    print e7
+    sql = sqlgenerator(e7)
+    print sql.generate()

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20070313/8915e309/attachment.html


More information about the calendarserver-changes mailing list