ucb/CppunitTest_ucb_webdav_propfindcache.mk      |   55 +++++++++
 ucb/Library_ucpdav1.mk                           |    1 
 ucb/Module_ucb.mk                                |    1 
 ucb/qa/cppunit/webdav/webdav_options.cxx         |    1 
 ucb/qa/cppunit/webdav/webdav_propfindcache.cxx   |  136 +++++++++++++++++++++++
 ucb/source/ucp/webdav-neon/DAVResource.hxx       |    5 
 ucb/source/ucp/webdav-neon/PropfindCache.cxx     |  102 +++++++++++++++++
 ucb/source/ucp/webdav-neon/PropfindCache.hxx     |   83 ++++++++++++++
 ucb/source/ucp/webdav-neon/webdavcontentcaps.cxx |    1 
 9 files changed, 384 insertions(+), 1 deletion(-)

New commits:
commit 98bd24f8b479132ca3f2d884749b738e9e6203e3
Author: Giuseppe Castagno <giuseppe.casta...@acca-esse.eu>
Date:   Sat Aug 20 15:45:07 2016 +0200

    Related: tdf#82677, implement a PROPFIND 'propname' request cache
    
    PROPFIND 'propname' is the special usage to retrieve all the
    properties available on the URI resource, their names only.
    
    See <https://tools.ietf.org/html/rfc4918#section-9.1> for
    PROPFIND 'propname' definition.
    
    Add cache usage in Content::getProperties as well.
    The caching model is simple: a simple lifetime limit of 10 seconds
    to declare the property name list stale and request another list,
    accessing the Net.
    
    This should reduce the number of PROPFIND calls on the Net.
    
    Change-Id: Ie4ebd946dd81583dc964a62c7744f3e2c716c737
    Reviewed-on: https://gerrit.libreoffice.org/28273
    Tested-by: Jenkins <c...@libreoffice.org>
    Reviewed-by: Giuseppe Castagno <giuseppe.casta...@acca-esse.eu>

diff --git a/ucb/CppunitTest_ucb_webdav_propfindcache.mk 
b/ucb/CppunitTest_ucb_webdav_propfindcache.mk
new file mode 100644
index 0000000..ebbaee7
--- /dev/null
+++ b/ucb/CppunitTest_ucb_webdav_propfindcache.mk
@@ -0,0 +1,55 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*************************************************************************
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+#*************************************************************************
+
+$(eval $(call gb_CppunitTest_CppunitTest,ucb_webdav_propfindcache))
+
+$(eval $(call gb_CppunitTest_use_api,ucb_webdav_propfindcache, \
+       offapi \
+       udkapi \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,ucb_webdav_propfindcache, \
+       comphelper \
+       cppu \
+       cppuhelper \
+       sal \
+       salhelper \
+       test \
+       ucbhelper \
+))
+
+$(eval $(call gb_CppunitTest_use_library_objects,ucb_webdav_propfindcache, \
+       ucpdav1 \
+))
+
+$(eval $(call gb_CppunitTest_use_externals,ucb_webdav_propfindcache,\
+       boost_headers \
+       libxml2 \
+       neon \
+       openssl \
+))
+
+$(eval $(call gb_CppunitTest_use_custom_headers,ucb_webdav_propfindcache,\
+       officecfg/registry \
+))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,ucb_webdav_propfindcache, \
+    ucb/qa/cppunit/webdav/webdav_propfindcache \
+))
+
+$(eval $(call gb_CppunitTest_set_include,ucb_webdav_propfindcache,\
+    $$(INCLUDE) \
+    -I$(SRCDIR)/ucb/source/ucp/webdav-neon \
+))
+
+$(eval $(call gb_CppunitTest_use_static_libraries,ucb_webdav_propfindcache))
+
+# vim: set noet sw=4 ts=4:
diff --git a/ucb/Library_ucpdav1.mk b/ucb/Library_ucpdav1.mk
index 02e3681..88306db 100644
--- a/ucb/Library_ucpdav1.mk
+++ b/ucb/Library_ucpdav1.mk
@@ -53,6 +53,7 @@ $(eval $(call gb_Library_add_exception_objects,ucpdav1,\
        ucb/source/ucp/webdav-neon/NeonPropFindRequest \
        ucb/source/ucp/webdav-neon/NeonSession \
        ucb/source/ucp/webdav-neon/NeonUri \
+       ucb/source/ucp/webdav-neon/PropfindCache \
        ucb/source/ucp/webdav-neon/UCBDeadPropertyValue \
        ucb/source/ucp/webdav-neon/webdavcontentcaps \
        ucb/source/ucp/webdav-neon/webdavcontent \
diff --git a/ucb/Module_ucb.mk b/ucb/Module_ucb.mk
index e14c524..5fcd1e7 100644
--- a/ucb/Module_ucb.mk
+++ b/ucb/Module_ucb.mk
@@ -36,6 +36,7 @@ ifeq ($(WITH_WEBDAV),neon)
 $(eval $(call gb_Module_add_check_targets,ucb,\
     CppunitTest_ucb_webdav_local_neon \
     CppunitTest_ucb_webdav_neon_opts \
+    CppunitTest_ucb_webdav_propfindcache \
 ))
 
 endif
diff --git a/ucb/qa/cppunit/webdav/webdav_options.cxx 
b/ucb/qa/cppunit/webdav/webdav_options.cxx
index 6c89623..bad3adc 100644
--- a/ucb/qa/cppunit/webdav/webdav_options.cxx
+++ b/ucb/qa/cppunit/webdav/webdav_options.cxx
@@ -11,7 +11,6 @@
 #include <cppunit/plugin/TestPlugIn.h>
 #include "DAVTypes.hxx"
 
-
 namespace
 {
 
diff --git a/ucb/qa/cppunit/webdav/webdav_propfindcache.cxx 
b/ucb/qa/cppunit/webdav/webdav_propfindcache.cxx
new file mode 100644
index 0000000..074f21d
--- /dev/null
+++ b/ucb/qa/cppunit/webdav/webdav_propfindcache.cxx
@@ -0,0 +1,136 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/bootstrapfixture.hxx>
+#include <cppunit/plugin/TestPlugIn.h>
+#include <cmath>
+#include "PropfindCache.hxx"
+
+using namespace webdav_ucp;
+
+namespace
+{
+
+    class webdav_propcache_test: public test::BootstrapFixture
+    {
+
+    public:
+        webdav_propcache_test() : BootstrapFixture( true, true ) {}
+
+        // initialise your test code values here.
+        void setUp(  ) override;
+
+        void tearDown(  ) override;
+
+        void PropfindCacheElemTests();
+        void PropfindCacheTests();
+
+        // Change the following lines only, if you add, remove or rename
+        // member functions of the current class,
+        // because these macros are need by auto register mechanism.
+
+        CPPUNIT_TEST_SUITE( webdav_propcache_test );
+        CPPUNIT_TEST( PropfindCacheElemTests );
+        CPPUNIT_TEST( PropfindCacheTests );
+        CPPUNIT_TEST_SUITE_END();
+    };                          // class webdav_local_test
+
+    // initialise your test code values here.
+    void webdav_propcache_test::setUp()
+    {
+    }
+
+    void webdav_propcache_test::tearDown()
+    {
+    }
+
+    void webdav_propcache_test::PropfindCacheElemTests( )
+    {
+        OUString aTheURL( "http:://server/path/filename.odt" );
+        PropertyNames aPropsNames( aTheURL );
+
+        CPPUNIT_ASSERT_EQUAL( aTheURL, aPropsNames.getURL() );
+        CPPUNIT_ASSERT_EQUAL( static_cast< sal_uInt32 >(0), 
aPropsNames.getStaleTime() );
+
+        sal_uInt32 maxTime = static_cast< sal_uInt32 >(std::pow(2,32)-1);
+
+        aPropsNames.setStaleTime( maxTime );
+        CPPUNIT_ASSERT_EQUAL( maxTime, aPropsNames.getStaleTime() );
+
+        std::vector < OUString > properties {
+                "DAV:lockdiscovery",
+                "DAV:supportedlock",
+                "DAV:resourcetype",
+                "DAV:displayname",
+                "DAV:getlastmodified",
+                "DAV:getcontentlength",
+                "DAV:creationdate",
+                "DAV:getetag",
+                "DAV:authticket",
+                };
+
+        DAVResourceInfo aSingleInfo { properties };
+        std::vector< DAVResourceInfo > aProps { aSingleInfo };
+        std::vector< DAVResourceInfo > aRetProp;
+
+        aPropsNames.setPropertiesNames( aProps );
+        aRetProp = aPropsNames.getPropertiesNames();
+        CPPUNIT_ASSERT_EQUAL( true, ( aProps == aRetProp ) );
+
+        aProps[0].properties.push_back( "DAV:getlastmodified" );
+        aRetProp = aPropsNames.getPropertiesNames();
+        CPPUNIT_ASSERT_EQUAL( false, ( aProps == aRetProp ) );
+    }
+
+    void webdav_propcache_test::PropfindCacheTests( )
+    {
+        PropertyNamesCache PropCache;
+        OUString aTheURL( "http:://server/path/filename.odt" );
+        PropertyNames aPropsNames( aTheURL );
+
+        // check cache emptiness
+        CPPUNIT_ASSERT_EQUAL( false, PropCache.getCachedPropertyNames( 
aTheURL,  aPropsNames ) );
+
+        std::vector < OUString > properties {
+                "DAV:lockdiscovery",
+                "DAV:supportedlock",
+                "DAV:resourcetype",
+                "DAV:displayname",
+                "DAV:getlastmodified",
+                "DAV:getcontentlength",
+                "DAV:creationdate",
+                "DAV:getetag",
+                "DAV:authticket",
+                };
+
+        DAVResourceInfo aSingleInfo { properties };
+        std::vector< DAVResourceInfo > aProps { aSingleInfo };
+
+        // add the cache an element
+        aPropsNames.setPropertiesNames( aProps );
+        PropCache.addCachePropertyNames( aPropsNames, 10 );
+
+        PropertyNames aRetPropsNames;
+        //test existence
+        CPPUNIT_ASSERT_EQUAL( true, PropCache.getCachedPropertyNames( aTheURL, 
aRetPropsNames ) );
+        //check equality
+        std::vector< DAVResourceInfo > aRetProp = 
aRetPropsNames.getPropertiesNames();
+        CPPUNIT_ASSERT_EQUAL( true, ( aProps == aRetProp ) );
+        //remove from cache
+        PropCache.removeCachedPropertyNames( aTheURL );
+        //check absence
+        CPPUNIT_ASSERT_EQUAL( false, PropCache.getCachedPropertyNames( 
aTheURL,  aPropsNames ) );
+    }
+
+    CPPUNIT_TEST_SUITE_REGISTRATION( webdav_propcache_test );
+}                               // namespace rtl_random
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/ucb/source/ucp/webdav-neon/DAVResource.hxx 
b/ucb/source/ucp/webdav-neon/DAVResource.hxx
index 56a2009..9ec4270 100644
--- a/ucb/source/ucp/webdav-neon/DAVResource.hxx
+++ b/ucb/source/ucp/webdav-neon/DAVResource.hxx
@@ -59,6 +59,11 @@ struct DAVResource
 struct DAVResourceInfo
 {
     std::vector < OUString > properties;
+
+    bool operator==( const struct DAVResourceInfo& a ) const
+    {
+        return (properties == a.properties );
+    }
 };
 
 } // namespace webdav_ucp
diff --git a/ucb/source/ucp/webdav-neon/PropfindCache.cxx 
b/ucb/source/ucp/webdav-neon/PropfindCache.cxx
new file mode 100644
index 0000000..095273a1
--- /dev/null
+++ b/ucb/source/ucp/webdav-neon/PropfindCache.cxx
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <osl/time.h>
+#include "PropfindCache.hxx"
+
+namespace webdav_ucp
+{
+
+    // PropertyNames implementation
+
+    PropertyNames::PropertyNames() :
+        m_nStaleTime( 0 ),
+        m_sURL(),
+        m_aPropertiesNames()
+    {
+    }
+
+    PropertyNames::PropertyNames( const OUString& rURL ) :
+        m_nStaleTime( 0 ),
+        m_sURL( rURL ),
+        m_aPropertiesNames()
+    {
+    }
+
+    PropertyNames::PropertyNames( const PropertyNames& theOther ) :
+        m_nStaleTime( theOther.m_nStaleTime ),
+        m_sURL( theOther.m_sURL ),
+        m_aPropertiesNames( theOther.m_aPropertiesNames )
+    {
+    }
+
+    PropertyNames::~PropertyNames()
+    {
+    }
+
+    //PropertyNamesCache implementation
+
+    PropertyNamesCache::PropertyNamesCache()
+    {
+    }
+
+    PropertyNamesCache::~PropertyNamesCache()
+    {
+    }
+
+    bool PropertyNamesCache::getCachedPropertyNames( const OUString& rURL, 
PropertyNames& rCacheElement )
+    {
+        // search the URL in the static map
+        osl::MutexGuard aGuard( m_aMutex );
+        PropNameCache::const_iterator it;
+        it = m_aTheCache.find( rURL );
+        if ( it == m_aTheCache.end() )
+            return false;
+        else
+        {
+            // check if the element is stale, before restoring
+            TimeValue t1;
+            osl_getSystemTime( &t1 );
+            if ( (*it).second.getStaleTime() < t1.Seconds )
+            {
+                // if stale, remove from cache, do not restore
+                m_aTheCache.erase( it );
+                return false;
+                // return false instead
+            }
+            rCacheElement = (*it).second;
+            return true;
+        }
+    }
+
+    void PropertyNamesCache::removeCachedPropertyNames( const OUString& rURL )
+    {
+        osl::MutexGuard aGuard( m_aMutex );
+        PropNameCache::const_iterator it;
+        it = m_aTheCache.find( rURL );
+        if ( it != m_aTheCache.end() )
+        {
+            m_aTheCache.erase( it );
+        }
+    }
+
+    void PropertyNamesCache::addCachePropertyNames( PropertyNames& 
rCacheElement, const sal_uInt32 nLifeTime )
+    {
+        osl::MutexGuard aGuard( m_aMutex );
+        OUString aURL( rCacheElement.getURL() );
+        TimeValue t1;
+        osl_getSystemTime( &t1 );
+        rCacheElement.setStaleTime( t1.Seconds + nLifeTime );
+
+        m_aTheCache[ aURL ] = rCacheElement;
+    }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/ucb/source/ucp/webdav-neon/PropfindCache.hxx 
b/ucb/source/ucp/webdav-neon/PropfindCache.hxx
new file mode 100644
index 0000000..1415a63
--- /dev/null
+++ b/ucb/source/ucp/webdav-neon/PropfindCache.hxx
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_UCB_SOURCE_UCP_WEBDAV_NEON_PROPFINDCACHE_HXX
+#define INCLUDED_UCB_SOURCE_UCP_WEBDAV_NEON_PROPFINDCACHE_HXX
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+#include <osl/mutex.hxx>
+#include <list>
+#include <map>
+#include <vector>
+
+#include "DAVResource.hxx"
+
+namespace webdav_ucp
+{
+    // A property names cache mechanism, URL driven.
+    // It is used to cache the property names received
+    // from the WebDAV server, to minimize the need of
+    // net transactions (e.g. PROPFIND).
+    // The cache lifetime should be short
+    // just to remove the annoying slowness when
+    // typing text or moving cursor around when the
+    // net link is slow.
+
+    // Define the properties cache element
+    class PropertyNames
+    {
+        /// target time when this element becomes stale
+        sal_uInt32 m_nStaleTime;
+        OUString    m_sURL;
+        // the property name list received from WebDAV server
+        std::vector< DAVResourceInfo > m_aPropertiesNames;
+
+    public:
+        PropertyNames();
+        PropertyNames( const OUString& rURL );
+        PropertyNames( const PropertyNames& theOther );
+        virtual ~PropertyNames();
+
+        sal_uInt32 getStaleTime() const { return m_nStaleTime; };
+        void setStaleTime( const sal_uInt32 nStaleTime ) { m_nStaleTime = 
nStaleTime; };
+
+        OUString& getURL() { return m_sURL; };
+
+        const std::vector< DAVResourceInfo >& getPropertiesNames() { return 
m_aPropertiesNames; };
+        void setPropertiesNames( const std::vector< DAVResourceInfo >& 
aPropertiesNames ) { m_aPropertiesNames = aPropertiesNames; };
+    };
+
+    // Define the PropertyNames cache
+    // TODO: the OUString key element in std::map needs to be changed with a 
URI representation
+    // with a specific compare (std::less) implementation, this last one 
implementing
+    // as suggested in <https://tools.ietf.org/html/rfc3986#section-6>.
+    // To find by URI and not by string equality.
+    typedef std::map< OUString, PropertyNames,
+                      std::less< OUString > >PropNameCache;
+
+    class PropertyNamesCache
+    {
+        PropNameCache       m_aTheCache;
+        osl::Mutex          m_aMutex;
+
+    public:
+        PropertyNamesCache();
+        virtual ~PropertyNamesCache();
+
+        bool getCachedPropertyNames( const OUString& URL, PropertyNames& 
rCacheElement );
+        void removeCachedPropertyNames( const OUString& URL );
+        void addCachePropertyNames( PropertyNames& rCacheElement, const 
sal_uInt32 nLifeTime );
+    };
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/ucb/source/ucp/webdav-neon/webdavcontentcaps.cxx 
b/ucb/source/ucp/webdav-neon/webdavcontentcaps.cxx
index 4dd8f41..fec4b62 100644
--- a/ucb/source/ucp/webdav-neon/webdavcontentcaps.cxx
+++ b/ucb/source/ucp/webdav-neon/webdavcontentcaps.cxx
@@ -52,6 +52,7 @@
 #include "webdavprovider.hxx"
 #include "DAVSession.hxx"
 #include "ContentProperties.hxx"
+#include "PropfindCache.hxx"
 
 using namespace com::sun::star;
 using namespace webdav_ucp;
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to