$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r83933 - in trunk/tools/build/v2: build engine/modules
From: steven_at_[hidden]
Date: 2013-04-16 16:48:13
Author: steven_watanabe
Date: 2013-04-16 16:48:13 EDT (Tue, 16 Apr 2013)
New Revision: 83933
URL: http://svn.boost.org/trac/boost/changeset/83933
Log:
Optimize generator.match-rank
Text files modified: 
   trunk/tools/build/v2/build/generators.jam          |    31 ++++++++++-------------                 
   trunk/tools/build/v2/build/property-set.jam        |    16 ++++++++++++                            
   trunk/tools/build/v2/engine/modules/property-set.c |    52 ++++++++++++++++++++++++++++++++++++++++
   3 files changed, 82 insertions(+), 17 deletions(-)
Modified: trunk/tools/build/v2/build/generators.jam
==============================================================================
--- trunk/tools/build/v2/build/generators.jam	(original)
+++ trunk/tools/build/v2/build/generators.jam	2013-04-16 16:48:13 EDT (Tue, 16 Apr 2013)
@@ -220,6 +220,18 @@
             self.name-prefix += $(m[3]:E="") ;
             self.name-postfix += $(m[4]:E="") ;
         }
+        
+        for local r in [ requirements ]
+        {
+            if $(r:G=)
+            {
+                self.property-requirements += $(r) ;
+            }
+            else
+            {
+                self.feature-requirements += $(r) ;
+            }
+        }
 
         # Note that 'transform' here, is the same as 'for_each'.
         sequence.transform type.validate : $(self.source-types) ;
@@ -279,24 +291,9 @@
         # See if generator requirements are satisfied by 'properties'. Treat a
         # feature name in requirements (i.e. grist-only element), as matching
         # any value of the feature.
-        local all-requirements = [ requirements ] ;
-
-        local property-requirements feature-requirements ;
-        for local r in $(all-requirements)
-        {
-            if $(r:G=)
-            {
-                property-requirements += $(r) ;
-            }
-            else
-            {
-                feature-requirements += $(r) ;
-            }
-        }
 
-        local properties-to-match = [ $(property-set-to-match).raw ] ;
-        if $(property-requirements) in $(properties-to-match) &&
-            $(feature-requirements) in $(properties-to-match:G)
+        if [ $(property-set-to-match).contains-raw $(self.property-requirements) ] &&
+            [ $(property-set-to-match).contains-features $(self.feature-requirements) ]
         {
             return true ;
         }
Modified: trunk/tools/build/v2/build/property-set.jam
==============================================================================
--- trunk/tools/build/v2/build/property-set.jam	(original)
+++ trunk/tools/build/v2/build/property-set.jam	2013-04-16 16:48:13 EDT (Tue, 16 Apr 2013)
@@ -309,6 +309,17 @@
         }
     }
 
+    # Returns true if the property-set has values for
+    # all the specified features
+    #
+    rule contains-features ( features * )
+    {
+        if $(features) in $(self.raw:G)
+        {
+            return true ;
+        }
+    }
+
     # private
 
     rule init-base ( )
@@ -395,6 +406,11 @@
     NATIVE_RULE class_at_property-set : get ;
 }
 
+if [ HAS_NATIVE_RULE class_at_property-set : contains-features : 1 ]
+{
+    NATIVE_RULE class_at_property-set : contains-features ;
+}
+
 # Creates a new 'property-set' instance after checking that all properties are
 # valid and converting implicit properties into gristed form.
 #
Modified: trunk/tools/build/v2/engine/modules/property-set.c
==============================================================================
--- trunk/tools/build/v2/engine/modules/property-set.c	(original)
+++ trunk/tools/build/v2/engine/modules/property-set.c	2013-04-16 16:48:13 EDT (Tue, 16 Apr 2013)
@@ -13,6 +13,7 @@
 #include "../native.h"
 #include "../compile.h"
 #include "../mem.h"
+#include "../constants.h"
 #include "string.h"
 
 struct ps_map_entry
@@ -259,6 +260,53 @@
     return result;
 }
 
+/* binary search for the property value */
+LIST * property_set_contains_features( FRAME * frame, int flags )
+{
+    OBJECT * varname = object_new( "self.raw" );
+    LIST * props = var_get( frame->module, varname );
+    LIST * features = lol_get( frame->args, 0 );
+    LIST * result = L0;
+    LISTITER features_iter = list_begin( features );
+    LISTITER features_end = list_end( features ) ;
+    object_free( varname );
+
+    for ( ; features_iter != features_end; ++features_iter )
+    {
+        const char * name = object_str( list_item( features_iter ) );
+        size_t name_len = strlen( name );
+        LISTITER begin, end;
+        /* Assumes random access */
+        begin = list_begin( props ), end = list_end( props );
+
+        while ( 1 )
+        {
+            ptrdiff_t diff = (end - begin);
+            LISTITER mid = begin + diff / 2;
+            int res;
+            if ( diff == 0 )
+            {
+                /* The feature is missing */
+                return L0;
+            }
+            res = strncmp( object_str( list_item( mid ) ), name, name_len );
+            if ( res < 0 )
+            {
+                begin = mid + 1;
+            }
+            else if ( res > 0 )
+            {
+                end = mid;
+            }
+            else /* We've found the property */
+            {
+                break;
+            }
+        }
+    }
+    return list_new( object_copy( constant_true ) );
+}
+
 void init_property_set()
 {
     {
@@ -269,6 +317,10 @@
         char const * args[] = { "feature", 0 };
         declare_native_rule( "class_at_property-set", "get", args, property_set_get, 1 );
     }
+    {
+        char const * args[] = { "features", "*", 0 };
+        declare_native_rule( "class_at_property-set", "contains-features", args, property_set_contains_features, 1 );
+    }
     ps_map_init( &all_property_sets );
 }