...
namespace ISC.MapDotNetServer.Core.Services
{
public interface IMapCacheManager
{
/// <summary>
/// Read a MapResponse from cache based on the supplied cache-key.
/// </summary>
/// <param name="cacheKey">Cache-key - an MD5 hash of a MapRequest.</param>
/// <param name="mapResponse">Serialized map response object to read.</param>
/// <param name="cacheInfo">Cache information.</param>
void ReadFromCache(string cacheKey, out string mapResponseSerial, out CacheInfo cacheInfo);
/// <summary>
/// Peek into the cache and just get information about it.
/// </summary>
/// <param name="cacheKey">Cache-key - an MD5 hash of a MapRequest.</param>
/// <returns>Cache information.</returns>
CacheInfo LookIntoCache(string cacheKey);
/// <summary>
/// Delete an entry in the cache by cache-key.
/// </summary>
/// <param name="cacheKey">Cache-key - an MD5 hash of a MapRequest.</param>
void DeleteFromCache(string cacheKey);
/// <summary>
/// Write (Insert/Update) an entry in the cache based on the supplied cache-key.
/// </summary>
/// <param name="cacheKey">Cache-key - an MD5 hash of a MapRequest.</param>
/// <param name="mapResponseSerial">Serialized map response object to save.</param>
void WriteToCache(string cacheKey, string mapResponseSerial);
}
}
web.config entries to enable caching
<add key="EnableMapCaching" value="false"/>
<add key="MapCacheManagerClassName" value="InProcMapCache"/>
...
Included in the installation of 6.5 is an example (part of app_code.dll - source not included):
The example below simply stores up to 100 map requests in your web service application process and manages the maximum in a "most-used" approach. You can use the source below to determine how you might implement your own cache more suitable for an enterprise solution such as RDBMS store.
/*
Copyright © 2008 – Specialized Technology Products, Inc. All Rights Reserved.
Product: MapDotNet Server
*/
using System;
using System.Collections.Generic;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using ISC.MapDotNetServer.Core.Services;
/// <summary>
/// Summary description for SessionMapCache
/// </summary>
public class InProcMapCache : IMapCacheManager
{
#region DATA
private const int kMaxCacheItems = 100;
/// <summary>
/// App-domain sorted list of cache items
/// </summary>
protected SortedList<string, CacheItem> Cache
{
get
{
if (_Cache == null)
{
_Cache = new SortedList<string, CacheItem>(kMaxCacheItems);
}
return _Cache;
}
}
private volatile static SortedList<string, CacheItem> _Cache;
// define cache item
public class CacheItem
{
public string Data;
public CacheInfo CacheInfo;
}
#endregion
#region ICacheManager Members
/// <summary>
/// Read a MapResponse from cache based on the supplied cache-key.
/// </summary>
/// <param name="cacheKey">Cache-key - an MD5 hash of a MapRequest.</param>
/// <param name="mapResponse">Serialized map response object to read.</param>
/// <param name="cacheInfo">Cache information.</param>
public void ReadFromCache(string cacheKey, out string mapResponseSerial, out CacheInfo cacheInfo)
{
lock (Cache)
{
if (Cache.ContainsKey(cacheKey))
{
CacheItem item = Cache[cacheKey];
item.CacheInfo.ReadCount++;
cacheInfo = item.CacheInfo;
mapResponseSerial = item.Data;
}
else
{
cacheInfo = new CacheInfo();
cacheInfo.Exist = false;
mapResponseSerial = null;
}
}
}
/// <summary>
/// Peek into the cache and just get information about it.
/// </summary>
/// <param name="cacheKey">Cache-key - an MD5 hash of a MapRequest.</param>
/// <returns>Cache information.</returns>
public CacheInfo LookIntoCache(string cacheKey)
{
lock (Cache)
{
if (Cache.ContainsKey(cacheKey))
{
CacheItem item = Cache[cacheKey];
return item.CacheInfo;
}
else
{
CacheInfo ci = new CacheInfo();
ci.Exist = false;
return ci;
}
}
}
/// <summary>
/// Delete an entry in the cache by cache-key.
/// </summary>
/// <param name="cacheKey">Cache-key - an MD5 hash of a MapRequest.</param>
public void DeleteFromCache(string cacheKey)
{
lock (Cache)
{
if (Cache.ContainsKey(cacheKey))
{
Cache.Remove(cacheKey);
}
}
}
/// <summary>
/// Write (Insert/Update) an entry in the cache based on the supplied cache-key.
/// </summary>
/// <param name="cacheKey">Cache-key - an MD5 hash of a MapRequest.</param>
/// <param name="mapResponseSerial">Serialized map response object to save.</param>
public void WriteToCache(string cacheKey, string mapResponseSerial)
{
if (!string.IsNullOrEmpty(cacheKey) && !string.IsNullOrEmpty(mapResponseSerial))
{
lock (Cache)
{
// check current cache capacity
// remove the least desirable item
if (Cache.Count >= kMaxCacheItems)
{
// iterate and find the best item to remove
int oldestIdx = 0;
double staleFactor = -1.0;
for (int idx = 0; idx < Cache.Count; idx++)
{
CacheItem item = Cache.Values[idx];
// compute the stale-factor for each item
// this is based on the number of acccesses per unit time
double sf = Convert.ToDouble(item.CacheInfo.ReadCount + 1) /
Convert.ToDouble((DateTime.Now - item.CacheInfo.WriteDateTime).Seconds);
if (staleFactor < 0.0 || sf < staleFactor)
{
staleFactor = sf;
oldestIdx = idx;
}
}
Cache.RemoveAt(oldestIdx);
}
// insert new item
CacheItem newItem = new CacheItem();
newItem.CacheInfo = new CacheInfo();
newItem.CacheInfo.Exist = true;
newItem.CacheInfo.ReadCount = 0;
newItem.CacheInfo.WriteDateTime = DateTime.Now;
newItem.Data = mapResponseSerial;
Cache[cacheKey] = newItem;
}
}
}
#endregion
}