Tuesday, July 6, 2010

PortalSiteMapProvider - leveraging cache

PortalSiteMapProvider

The navigation controls provided in MOSS — specifically, the navigation providers — utilize a very powerful and performant object called Microsoft.SharePoint.Publishing.Navigation .PortalSiteMapProvider . The job of the PortalSiteMapProvider is to expose the SharePoint site hierarchy to site map data sources that can then massage the hierarchy before passing it along to the rendering controls. One of the unique characteristics of the PortalSiteMapProvider is the component ' s performance. It boasts a sophisticated, built - in caching mechanism to ensure that navigation controls are never the cause for a poorly performing site, and it has been optimized for cross - list and cross - site queries. However, like many other things in SharePoint, it cannot cross the boundaries of site collections.

When the PortalSiteMapProvider receives a request for data using one of the retrieval methods, it queries the data in SharePoint to obtain a set of results. It inserts these results into cache so that the next time the query is executed it will not have to issue the expensive results. Instead, it simply performs a few checks on the data and uses the results of the previous query. The three retrieval nodes most commonly used are as follows:

GetCachedList() — This method returns a single SharePoint list as a PortalListSiteMapNode object.
GetCachedListItemsByQuery() — By far the most commonly used, this method returns a collection of PortalListItemSiteMapNode objects from the results of a specific query passed in using the SPQuery object.
GetCachedSiteDataQuery() — This method returns data from a specified SharePoint site as an ADO.NET DataTable from the provided query specified using the SPSiteDataQuery object.

These methods include all the necessary logic required to add and fetch the results from previously executed queries, so developers are free to just use the PortalSiteMapProvider ; no special configuration is required. Using the ortalSiteMapProvider in code is fairly straightforward. Listing contains the code to select all the pages in the Press Releases subsite that have been published since 2005.
Selecting all press releases published since 2005 with the PortalSiteMapProvider
PortalSiteMapProvider psmp = PortalSiteMapProvider.CurrentNavSiteMapProvider;
// get instance of the Press Releases site
PortalWebSiteMapNode prNode = psmp.FindSiteMapNode("/PressReleases") as PortalWebSiteMapNode;
// get all Press Releases published since 2005
SPQuery query = new SPQuery();
query.Query = "< Where > < Geq > < FieldRef Name='ArticleStartDate'/><Value Type='DateTime'>2005-01-01T12:00:00Z < /Value > < /Geq > < /Where >";
SiteMapNodeCollection pages = psmp.GetCachedListItemsByQuery(prNode, "Pages", query,SPContext.Current.Web);
When using the PortalSiteMapProvider, developers should consider a few things ahead of time, as there are two occasions when it is not suitable. First, because the PortalSiteMapProvider internally caches the results of previously run queries, it should only be used for queries that are run requently, where " frequently " is defined as an interval less than that of the duration something remains in cache (by default, three minutes). Navigation fits this model very well, hence the reason why it is the workhorse for the navigation controls in Publishing sites.

However, leveraging cache to reduce or eliminate round - trips to the database comes at a cost: The results from previously executed queries are only kept in cache for a limited time. If the time between two queries is greater than the time the results are kept in cache, then the PortalSiteMapProvider is actually doing more harm than good. That's because it is incurring the overhead of adding the results to cache after retrieving them from the executed query. If the data in cache is invalidated before the query is run again, then no benefit is being realized; and in fact the process is actually slower than not using the PortalSiteMapProvider because it has the extra burden of dealing with the cache.

In addition, the PortalSiteMapProvider should not be used when the underlying data being queried changes very frequently. The reason for this is related to the behavior of the PortalSiteMapProvider, which checks the SharePoint change log to determine whether the data being queried has changed before using the results stored in cache. If the data has changed, then it invalidates the results in cache and re-executes the query. If the underlying data is changing very frequently, then subsequent queries will not pull data from the cache but instead always re-execute the query against the SharePoint object model.

.....HaPpY CoDiNg

Partha (Aurum)

No comments:

Post a Comment