Skip to content
This repository has been archived by the owner on Nov 15, 2020. It is now read-only.

Commit

Permalink
Caching Issue Resolved
Browse files Browse the repository at this point in the history
  • Loading branch information
Info Offbeat committed Feb 15, 2016
1 parent 95f3593 commit 23487ee
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 37 deletions.
58 changes: 49 additions & 9 deletions HandsetDetectionAPI/HDCache.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Runtime.Caching;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Caching;
using System.Web.Script.Serialization;

Expand All @@ -13,20 +17,15 @@ namespace HandsetDetectionAPI
public class HdCache
{
private static int _maxJsonLength = 40000000;
string _prefix = "hd4-";
string _prefix = "hd4_";
//int duration = 7200;
ObjectCache _myCache;
readonly MemoryCache _myCache = MemoryCache.Default;
CacheItemPolicy _policy = new CacheItemPolicy();
JavaScriptSerializer _jss = new JavaScriptSerializer { MaxJsonLength = _maxJsonLength };

public HdCache()
{
_policy.AbsoluteExpiration = new DateTimeOffset(DateTime.Now.AddHours(24));
NameValueCollection cacheSettings = new NameValueCollection(3)
{
{"CacheMemoryLimitMegabytes", Convert.ToString(200)}
};
_myCache = MemoryCache.Default;
}

public T Write<T>(string key, T value)
Expand All @@ -36,7 +35,7 @@ public T Write<T>(string key, T value)
{
if (value != null && key != "")
{
// string storethis = _jss.Serialize(value);
// var count = _myCache.Count();
_myCache.Set(_prefix + key, value, _policy);
return value;
}
Expand All @@ -58,7 +57,13 @@ public T Read<T>(string key)
try
{
object fromCache = _myCache.Get(_prefix + key);
if (fromCache != null) return (T)Convert.ChangeType(fromCache, typeof(T));


if (fromCache != null)
{
T item = (T)Convert.ChangeType(fromCache, typeof(T));
return item.Clone();
}
}
catch (Exception)
{
Expand Down Expand Up @@ -86,4 +91,39 @@ public bool Purge()

}
}

/// <summary>
/// Provides a method for performing a deep copy of an object.
/// Binary Serialization is used to perform the copy.
/// </summary>
public static class ObjectCopier
{
/// <summary>
/// Perform a deep Copy of the object.
/// </summary>
/// <typeparam name="T">The type of object being copied.</typeparam>
/// <param name="source">The object instance to copy./// <returns>The copied object.</returns>
public static T Clone<T>(this T source)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", "source");
}

// Don't serialize a null object, simply return the default for that object
if (Object.ReferenceEquals(source, null))
{
return default(T);
}

IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream();
using (stream)
{
formatter.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}
}
}
54 changes: 30 additions & 24 deletions HandsetDetectionAPI/HDDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ public Dictionary<string, dynamic> FindRating(string deviceId, Dictionary<string
/// <param name="specsField">string specsField : Either "platform', 'browser', 'language'</param>
/// <param name="device"></param>
/// <param name="specs"></param>
public void SpecsOverlay(string specsField, ref dynamic device, Dictionary<string, dynamic> specs)
public Dictionary<string, dynamic> SpecsOverlay(string specsField, Dictionary<string, dynamic> device, Dictionary<string, dynamic> specs)
{
switch (specsField)
{
Expand Down Expand Up @@ -361,6 +361,7 @@ public void SpecsOverlay(string specsField, ref dynamic device, Dictionary<stri
}
} break;
}
return device;
}

/// <summary>
Expand Down Expand Up @@ -406,11 +407,12 @@ private Dictionary<string, dynamic> InfoStringToArray(string hardwareInfo)
/// </summary>
/// <param name="device"></param>
/// <param name="infoArray"></param>
private void HardwareInfoOverlay(ref dynamic device, Dictionary<string, dynamic> infoArray)
private Dictionary<string, dynamic> HardwareInfoOverlay(Dictionary<string, dynamic> device, Dictionary<string, dynamic> infoArray)
{
device["Device"]["hd_ops"]["display_x"] = infoArray["display_x"];
device["Device"]["hd_ops"]["display_y"] = infoArray["display_y"];
device["Device"]["hd_ops"]["display_pixel_ratio"] = infoArray["display_pixel_ratio"];
return device;
}

/// <summary>
Expand All @@ -425,7 +427,7 @@ private void HardwareInfoOverlay(ref dynamic device, Dictionary<string, dynamic>
/// </summary>
/// <param name="headers"></param>
/// <returns>array The matched device or null if not found</returns>
private dynamic MatchDevice(Dictionary<string, dynamic> headers)
private Dictionary<string, dynamic> MatchDevice(Dictionary<string, dynamic> headers)
{
// Opera mini sometimes puts the vendor # model in the header - nice! ... sometimes it puts ? # ? in as well
if (headers.ContainsKey("x-operamini-phone") && headers["x-operamini-phone"].ToString() != "? # ?")
Expand Down Expand Up @@ -494,7 +496,7 @@ private dynamic MatchDevice(Dictionary<string, dynamic> headers)
return this.FindById(itemid);
}

return false;
return null;
}

/// <summary>
Expand Down Expand Up @@ -558,7 +560,9 @@ public dynamic V4MatchBuildInfo(Dictionary<string, dynamic> buildInfo)
// Platform Detection
dynamic platform = V4MatchBiHelper(buildInfo, "platform");
if (platform != null && platform.Count != 0)
this.SpecsOverlay("platform", ref device, platform["Extra"]);
{
device = this.SpecsOverlay("platform", device, platform["Extra"]);
}

Reply["hd_specs"] = device["Device"]["hd_specs"];
return SetError(0, "OK");
Expand Down Expand Up @@ -695,9 +699,9 @@ private dynamic V4MatchHttpHeaders(Dictionary<string, dynamic> headers, string h
}
}

dynamic device = MatchDevice(deviceHeaders);
Dictionary<string, dynamic> device = MatchDevice(deviceHeaders);

if (device is bool)
if (device == null)
{
return SetError(301, "Not Found");
}
Expand All @@ -715,7 +719,7 @@ private dynamic V4MatchHttpHeaders(Dictionary<string, dynamic> headers, string h
{
if (hwProps is IDictionary)
{
HardwareInfoOverlay(ref device, (Dictionary<string, dynamic>)hwProps);
device = HardwareInfoOverlay(device, (Dictionary<string, dynamic>)hwProps);
}

}
Expand All @@ -725,10 +729,10 @@ private dynamic V4MatchHttpHeaders(Dictionary<string, dynamic> headers, string h
}
// Get extra info

dynamic platform = _extra.MatchExtra("platform", extraHeaders);
dynamic browser = _extra.MatchExtra("browser", extraHeaders);
dynamic app = _extra.MatchExtra("app", extraHeaders);
dynamic language = _extra.MatchLanguage(extraHeaders);
Dictionary<string, dynamic> platform = _extra.MatchExtra("platform", extraHeaders);
Dictionary<string, dynamic> browser = _extra.MatchExtra("browser", extraHeaders);
Dictionary<string, dynamic> app = _extra.MatchExtra("app", extraHeaders);
Dictionary<string, dynamic> language = _extra.MatchLanguage(extraHeaders);

// Find out if there is any contention on the detected rule.
dynamic deviceList = GetHighAccuracyCandidates();
Expand All @@ -737,14 +741,14 @@ private dynamic V4MatchHttpHeaders(Dictionary<string, dynamic> headers, string h
{
List<string> pass1List = new List<string>();
// Resolve contention with OS check
if (!(platform is bool))
if (platform != null)
{
_extra.Set(platform);


foreach (dynamic item in deviceList)
{
dynamic tryDevice = this.FindById(item);
Dictionary<string, dynamic> tryDevice = this.FindById(item);

if (_extra.VerifyPlatform(tryDevice["Device"]["hd_specs"]))
{
Expand Down Expand Up @@ -772,7 +776,7 @@ private dynamic V4MatchHttpHeaders(Dictionary<string, dynamic> headers, string h
// Sort the results
//usort($result, array($this, 'hd_sortByScore'));
Dictionary<string, dynamic> bestRatedDevice = GetDeviceFromRatingResult(result);
dynamic objDevice = this.FindById(bestRatedDevice["_id"]);
Dictionary<string, dynamic> objDevice = this.FindById(bestRatedDevice["_id"]);
if (objDevice.Count > 0)
{
device = objDevice;
Expand All @@ -782,25 +786,27 @@ private dynamic V4MatchHttpHeaders(Dictionary<string, dynamic> headers, string h
}

// Overlay specs
if (!(platform is bool))
if (platform != null)
{
SpecsOverlay("platform", ref device, platform["Extra"]);
device = SpecsOverlay("platform", device, platform["Extra"]);
}
if (!(browser is bool))
if (browser != null)
{
SpecsOverlay("browser", ref device, browser["Extra"]);
device = SpecsOverlay("browser", device, browser["Extra"]);
}
if (!(app is bool))
if (app != null)
{
SpecsOverlay("app", ref device, app["Extra"]);
device = SpecsOverlay("app", device, app["Extra"]);
}
if (!(language is bool))
if (language != null)
{
SpecsOverlay("language", ref device, language["Extra"]);
device = SpecsOverlay("language", device, language["Extra"]);
}
// Overlay hardware info result if required
if (device["Device"]["hd_ops"]["overlay_result_specs"].ToString() == "1" && !string.IsNullOrEmpty(hardwareInfo))
HardwareInfoOverlay(ref device, hwProps);
{
device = HardwareInfoOverlay(device, hwProps);
}

Reply["hd_specs"] = device["Device"]["hd_specs"];
return SetError(0, "OK");//for meantime
Expand Down
4 changes: 2 additions & 2 deletions HandsetDetectionAPI/HDExtra.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public dynamic MatchExtra(string className, Dictionary<string, dynamic> headers)
return extra;
}
}
return false;
return null;

}

Expand All @@ -71,7 +71,7 @@ public dynamic FindById(string id)
/// </summary>
/// <param name="headers">headers A key => value array of sanitized http headers</param>
/// <returns>array Extra on success, false otherwise</returns>
public dynamic MatchLanguage(Dictionary<string, dynamic> headers)
public Dictionary<string, dynamic> MatchLanguage(Dictionary<string, dynamic> headers)
{
Dictionary<string, dynamic> extra = new Dictionary<string, dynamic>();
// Mock up a fake Extra for merge into detection reply.
Expand Down
4 changes: 2 additions & 2 deletions HandsetDetectionAPI/HDStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,15 +130,15 @@ public bool store(string key, Dictionary<string, dynamic> data)
/// <returns> boolean true on success, false</returns>
public T Read<T>(string key)
{
var reply = _cache.Read<T>(key);
T reply = _cache.Read<T>(key);
if (reply != null)
return reply;

reply = Fetch<T>(key);
if (reply != null)
{
_cache.Write(key, reply);
return reply;
return reply.Clone();
}
else
{
Expand Down

0 comments on commit 23487ee

Please sign in to comment.