[longomatch] Add a IReferenceResolver as a cache for deserialized objects
- From: Andoni Morales Alastruey <amorales src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [longomatch] Add a IReferenceResolver as a cache for deserialized objects
- Date: Wed, 18 Mar 2015 14:47:35 +0000 (UTC)
commit 7a4352dcf0f8ec3cec97cf4bf4844721ca64a51b
Author: Andoni Morales Alastruey <ylatuya gmail com>
Date: Tue Mar 17 15:33:02 2015 +0100
Add a IReferenceResolver as a cache for deserialized objects
LongoMatch.Core/Common/Serializer.cs | 179 +++++++++++++---------------------
LongoMatch.DB/DocumentsSerializer.cs | 165 +++++++++++++++----------------
2 files changed, 147 insertions(+), 197 deletions(-)
---
diff --git a/LongoMatch.Core/Common/Serializer.cs b/LongoMatch.Core/Common/Serializer.cs
index 93af38b..d2ef0d3 100644
--- a/LongoMatch.Core/Common/Serializer.cs
+++ b/LongoMatch.Core/Common/Serializer.cs
@@ -35,32 +35,33 @@ namespace LongoMatch.Core.Common
{
public class Serializer
{
- public static void Save<T>(T obj, Stream stream,
- SerializationType type=SerializationType.Json) {
+ public static void Save<T> (T obj, Stream stream,
+ SerializationType type = SerializationType.Json)
+ {
switch (type) {
case SerializationType.Binary:
- BinaryFormatter formatter = new BinaryFormatter();
- formatter.Serialize(stream, obj);
+ BinaryFormatter formatter = new BinaryFormatter ();
+ formatter.Serialize (stream, obj);
break;
case SerializationType.Xml:
- XmlSerializer xmlformatter = new XmlSerializer(typeof(T));
- xmlformatter.Serialize(stream, obj);
+ XmlSerializer xmlformatter = new XmlSerializer (typeof(T));
+ xmlformatter.Serialize (stream, obj);
break;
case SerializationType.Json:
StreamWriter sw = new StreamWriter (stream, Encoding.UTF8);
sw.NewLine = "\n";
sw.Write (JsonConvert.SerializeObject (obj, JsonSettings));
- sw.Flush();
+ sw.Flush ();
break;
}
}
-
+
public static void Save<T> (T obj, string filepath,
- SerializationType type=SerializationType.Json)
+ SerializationType type = SerializationType.Json)
{
string tmpPath = filepath + ".tmp";
- using (Stream stream = new FileStream(tmpPath, FileMode.Create,
- FileAccess.Write, FileShare.None)) {
+ using (Stream stream = new FileStream (tmpPath, FileMode.Create,
+ FileAccess.Write, FileShare.None)) {
Save<T> (obj, stream, type);
}
if (File.Exists (filepath)) {
@@ -70,35 +71,38 @@ namespace LongoMatch.Core.Common
}
}
- public static T Load<T>(Stream stream,
- SerializationType type=SerializationType.Json) {
+ public static T Load<T> (Stream stream,
+ SerializationType type = SerializationType.Json)
+ {
switch (type) {
case SerializationType.Binary:
- BinaryFormatter formatter = new BinaryFormatter();
- return (T)formatter.Deserialize(stream);
+ BinaryFormatter formatter = new BinaryFormatter ();
+ return (T)formatter.Deserialize (stream);
case SerializationType.Xml:
- XmlSerializer xmlformatter = new XmlSerializer(typeof(T));
- return (T) xmlformatter.Deserialize(stream);
+ XmlSerializer xmlformatter = new XmlSerializer (typeof(T));
+ return (T)xmlformatter.Deserialize (stream);
case SerializationType.Json:
StreamReader sr = new StreamReader (stream, Encoding.UTF8);
- return JsonConvert.DeserializeObject<T> (sr.ReadToEnd(), JsonSettings);
+ return JsonConvert.DeserializeObject<T> (sr.ReadToEnd (), JsonSettings);
default:
- throw new Exception();
+ throw new Exception ();
}
}
-
- public static T Load<T>(string filepath,
- SerializationType type=SerializationType.Json) {
- Stream stream = new FileStream(filepath, FileMode.Open, FileAccess.Read,
FileShare.Read);
+
+ public static T Load<T> (string filepath,
+ SerializationType type = SerializationType.Json)
+ {
+ Stream stream = new FileStream (filepath, FileMode.Open, FileAccess.Read,
FileShare.Read);
using (stream) {
return Load<T> (stream, type);
}
}
-
- public static T LoadSafe<T>(string filepath) {
+
+ public static T LoadSafe<T> (string filepath)
+ {
Stream stream = new FileStream (filepath, FileMode.Open,
- FileAccess.Read, FileShare.Read);
+ FileAccess.Read, FileShare.Read);
using (stream) {
try {
return Load<T> (stream, SerializationType.Json);
@@ -109,9 +113,9 @@ namespace LongoMatch.Core.Common
}
}
}
-
+
static JsonSerializerSettings JsonSettings {
- get{
+ get {
JsonSerializerSettings settings = new JsonSerializerSettings ();
settings.Formatting = Formatting.Indented;
settings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
@@ -123,133 +127,88 @@ namespace LongoMatch.Core.Common
}
}
}
-
+
public class LongoMatchConverter : JsonConverter
{
bool handleImages;
- public LongoMatchConverter (bool handleImages) {
+ public LongoMatchConverter (bool handleImages)
+ {
this.handleImages = handleImages;
}
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ public override void WriteJson (JsonWriter writer, object value, JsonSerializer serializer)
{
if (value is Time) {
Time time = value as Time;
if (time != null) {
- writer.WriteValue(time.MSeconds);
+ writer.WriteValue (time.MSeconds);
}
} else if (value is Color) {
Color color = value as Color;
if (color != null) {
- writer.WriteValue(String.Format ("#{0}{1}{2}{3}",
- color.R.ToString ("X2"),
- color.G.ToString ("X2"),
- color.B.ToString ("X2"),
- color.A.ToString ("X2")));
+ writer.WriteValue (String.Format ("#{0}{1}{2}{3}",
+ color.R.ToString ("X2"),
+ color.G.ToString ("X2"),
+ color.B.ToString ("X2"),
+ color.A.ToString ("X2")));
}
} else if (value is Image) {
Image image = value as Image;
if (image != null) {
- writer.WriteValue(image.Serialize());
+ writer.WriteValue (image.Serialize ());
}
} else if (value is HotKey) {
HotKey hotkey = value as HotKey;
if (hotkey != null) {
- writer.WriteValue(String.Format ("{0} {1}", hotkey.Key,
hotkey.Modifier));
+ writer.WriteValue (String.Format ("{0} {1}", hotkey.Key,
hotkey.Modifier));
}
} else if (value is Point) {
Point p = value as Point;
if (p != null) {
- writer.WriteValue(String.Format ("{0} {1}",
- p.X.ToString
(NumberFormatInfo.InvariantInfo),
- p.Y.ToString
(NumberFormatInfo.InvariantInfo)));
+ writer.WriteValue (String.Format ("{0} {1}",
+ p.X.ToString (NumberFormatInfo.InvariantInfo),
+ p.Y.ToString (NumberFormatInfo.InvariantInfo)));
}
}
}
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
+ public override object ReadJson (JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
{
if (reader.Value != null) {
- if (objectType == typeof (Time)) {
- Int64 t = (Int64) reader.Value;
- return new Time((int)t);
- } else if (objectType == typeof (Color)) {
- string rgbStr = (string) reader.Value;
+ if (objectType == typeof(Time)) {
+ if (reader.ValueType == typeof(Int64)) {
+ return new Time ((int)(Int64)reader.Value);
+ } else {
+ return new Time ((Int32)reader.Value);
+ }
+ } else if (objectType == typeof(Color)) {
+ string rgbStr = (string)reader.Value;
return Color.Parse (rgbStr);
- } else if (objectType == typeof (Image)) {
+ } else if (objectType == typeof(Image)) {
byte[] buf = Convert.FromBase64String ((string)reader.Value);
return Image.Deserialize (buf);
- } else if (objectType == typeof (HotKey)) {
+ } else if (objectType == typeof(HotKey)) {
string[] hk = ((string)reader.Value).Split (' ');
- return new HotKey {Key = int.Parse(hk[0]), Modifier =
int.Parse(hk[1])};
- } else if (objectType == typeof (Point)) {
+ return new HotKey { Key = int.Parse (hk [0]), Modifier = int.Parse
(hk [1]) };
+ } else if (objectType == typeof(Point)) {
string[] ps = ((string)reader.Value).Split (' ');
- return new Point (double.Parse(ps[0], NumberFormatInfo.InvariantInfo),
- double.Parse(ps[1],
NumberFormatInfo.InvariantInfo));
+ return new Point (double.Parse (ps [0],
NumberFormatInfo.InvariantInfo),
+ double.Parse (ps [1], NumberFormatInfo.InvariantInfo));
}
}
return null;
}
-
- public override bool CanConvert(Type objectType)
+
+ public override bool CanConvert (Type objectType)
{
return (
- objectType == typeof(Time) ||
- objectType == typeof(Color) ||
- objectType == typeof(Point) ||
- objectType == typeof(HotKey) ||
- objectType == typeof(Image) && handleImages);
+ objectType == typeof(Time) ||
+ objectType == typeof(Color) ||
+ objectType == typeof(Point) ||
+ objectType == typeof(HotKey) ||
+ objectType == typeof(Image) && handleImages);
}
}
-
- public class IdReferenceResolver : IReferenceResolver
- {
- private int _references;
- private readonly Dictionary<string, object> _idtoobjects;
- private readonly Dictionary<object, string> _objectstoid;
-
- public IdReferenceResolver () {
- _references = 0;
- _idtoobjects = new Dictionary<string, object>();
- _objectstoid = new Dictionary<object, string>();
- }
-
- public object ResolveReference(object context, string reference)
- {
- object p;
- _idtoobjects.TryGetValue(reference, out p);
- return p;
- }
-
- public string GetReference(object context, object value)
- {
- string referenceStr;
- if (value is IIDObject) {
- IIDObject p = (IIDObject)value;
- referenceStr = p.ID.ToString();
- } else {
- if (!_objectstoid.TryGetValue (value, out referenceStr)) {
- _references++;
- referenceStr = _references.ToString(CultureInfo.InvariantCulture);
- }
- }
- _idtoobjects[referenceStr] = value;
- _objectstoid[value] = referenceStr;
- return referenceStr;
- }
-
- public bool IsReferenced(object context, object value)
- {
- string reference;
- return _objectstoid.TryGetValue (value, out reference);
- }
-
- public void AddReference(object context, string reference, object value)
- {
- _idtoobjects[reference] = value;
- _objectstoid[value] = reference;
- }
- }
}
diff --git a/LongoMatch.DB/DocumentsSerializer.cs b/LongoMatch.DB/DocumentsSerializer.cs
index d89ccb8..3c21a5b 100644
--- a/LongoMatch.DB/DocumentsSerializer.cs
+++ b/LongoMatch.DB/DocumentsSerializer.cs
@@ -35,18 +35,11 @@ namespace LongoMatch.DB
public static class DocumentsSerializer
{
- public static void SaveObject (IStorable obj, Database db, JsonSerializer serializer = null)
+ public static void SaveObject (IStorable obj, Database db, StorablesConverter
storablesConverter = null)
{
- List<Type> localStorables = new List<Type> ();
- if (obj is Project) {
- localStorables.Add (typeof(Team));
- localStorables.Add (typeof(Dashboard));
- localStorables.Add (typeof(Player));
- }
-
Document doc = db.GetDocument (obj.ID.ToString ());
doc.Update ((UnsavedRevision rev) => {
- JObject jo = SerializeObject (obj, rev, db, localStorables, serializer);
+ JObject jo = SerializeObject (obj, rev, db, storablesConverter);
IDictionary<string, object> props = jo.ToObject<IDictionary<string, object>>
();
/* SetProperties sets a new properties dictionary, removing the attachments we
* added in the serialization */
@@ -58,10 +51,10 @@ namespace LongoMatch.DB
});
}
- public static object LoadObject (Type objType, Guid id, Database db, JsonSerializer
serializer = null)
+ public static object LoadObject (Type objType, Guid id, Database db, StorablesConverter
storablesConverter = null)
{
Document doc = db.GetExistingDocument (id.ToString ());
- return DeserializeObject (objType, doc, db, serializer);
+ return DeserializeObject (objType, doc, db, storablesConverter);
}
/// <summary>
@@ -73,11 +66,10 @@ namespace LongoMatch.DB
/// <param name="localStorables">A list of <see cref="LongoMatch.Core.Interfaces.IStorable"/>
/// types that should be serialized as local referencies instead of by document ID.</param>
internal static JObject SerializeObject (IStorable obj, Revision rev, Database db,
- List<Type> localStorables, JsonSerializer serializer
= null)
+ StorablesConverter storablesConverter = null)
{
- if (serializer == null) {
- serializer = GetSerializer (obj.GetType (), rev, db, localStorables);
- }
+ JsonSerializer serializer = GetSerializer (obj.GetType (), rev, db,
+ storablesConverter, GetLocalTypes (obj.GetType
()));
JObject jo = JObject.FromObject (obj, serializer);
jo ["DocType"] = obj.GetType ().Name;
@@ -92,17 +84,32 @@ namespace LongoMatch.DB
/// <param name="doc">The document to deserialize.</param>
/// <param name = "serializer">The serializer to use when deserializing the object</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
- internal static object DeserializeObject (Type type, Document doc, Database db,
JsonSerializer serializer = null)
+ internal static object DeserializeObject (Type type, Document doc, Database db,
+ StorablesConverter storablesConverter = null)
{
JObject jo = JObject.FromObject (doc.Properties);
- if (serializer == null) {
- serializer = GetSerializer (type, doc.CurrentRevision, db, null);
- }
+ JsonSerializer serializer = GetSerializer (type, doc.CurrentRevision, db,
+ storablesConverter, GetLocalTypes (type));
return jo.ToObject (type, serializer);
}
- static JsonSerializer GetSerializer (Type serType, Revision rev, Database db, List<Type>
localTypes)
+ static List<Type> GetLocalTypes (Type objType)
{
+ List<Type> localStorables = new List<Type> ();
+ if (objType == typeof(Project)) {
+ localStorables.Add (typeof(Team));
+ localStorables.Add (typeof(Dashboard));
+ localStorables.Add (typeof(Player));
+ }
+ return localStorables;
+ }
+
+ static JsonSerializer GetSerializer (Type serType, Revision rev, Database db,
+ StorablesConverter storablesConverter, List<Type>
localTypes)
+ {
+ if (storablesConverter == null) {
+ storablesConverter = new StorablesConverter (db, localTypes);
+ }
if (localTypes == null) {
localTypes = new List<Type> ();
}
@@ -113,76 +120,14 @@ namespace LongoMatch.DB
settings.TypeNameHandling = TypeNameHandling.Objects;
settings.Converters.Add (new ImageConverter (rev));
settings.Converters.Add (new VersionConverter ());
- settings.Converters.Add (new StorablesConverter (db, localTypes));
+ settings.Converters.Add (storablesConverter);
settings.Converters.Add (new LongoMatchConverter (false));
- //settings.ReferenceResolver = new IDReferenceResolver (db);
+ settings.ReferenceResolver = storablesConverter;
return JsonSerializer.Create (settings);
}
}
- class IdReferenceResolver : IReferenceResolver
- {
- int _references;
- readonly Dictionary<string, object> _idtoobjects;
- readonly Dictionary<object, string> _objectstoid;
- Database _db;
- Type _parent;
- Type[] _localRefType;
-
- public IdReferenceResolver (Database db, Type parent, Type[] localRefTypes)
- {
- _db = db;
- _parent = parent;
- _localRefType = localRefTypes;
- _references = 0;
- _idtoobjects = new Dictionary<string, object> ();
- _objectstoid = new Dictionary<object, string> ();
- }
-
- public object ResolveReference (object context, string reference)
- {
- object p;
- _idtoobjects.TryGetValue (reference, out p);
-
- if (p == null) {
- //DocumentsSerializer.DeserializeObject ( Serializer.
- }
- return p;
- }
-
- public string GetReference (object context, object value)
- {
- string referenceStr;
- if (value is IStorable) {
- IStorable p = value as IStorable;
- referenceStr = p.ID.ToString ();
- } else {
- if (!_objectstoid.TryGetValue (value, out referenceStr)) {
- _references++;
- referenceStr = _references.ToString (CultureInfo.InvariantCulture);
- }
- }
- _idtoobjects [referenceStr] = value;
- _objectstoid [value] = referenceStr;
- return referenceStr;
- }
-
- public bool IsReferenced (object context, object value)
- {
- if (value is IStorable) {
- return true;
- }
- return _objectstoid.ContainsKey (value);
- }
-
- public void AddReference (object context, string reference, object value)
- {
- _idtoobjects [reference] = value;
- _objectstoid [value] = reference;
- }
- }
-
/// <summary>
/// Converts fields with <see cref="LongoMatch.Core.Common.Image"/> objects
/// into Attachments, using as field value the name of the attachment prefixed
@@ -258,10 +203,13 @@ namespace LongoMatch.DB
/// Serialize objects matching any of the types lists passed in the constructor
/// using their object ID.
/// </summary>
- class StorablesConverter : JsonConverter
+ public class StorablesConverter : JsonConverter, IReferenceResolver
{
List<Type> localTypes;
Database db;
+ int _references;
+ readonly Dictionary<string, object> _idtoobjects;
+ readonly Dictionary<object, string> _objectstoid;
public StorablesConverter (Database db, List<Type> localTypes)
{
@@ -270,6 +218,10 @@ namespace LongoMatch.DB
if (this.localTypes == null) {
this.localTypes = new List<Type> ();
}
+
+ _references = 0;
+ _idtoobjects = new Dictionary<string, object> ();
+ _objectstoid = new Dictionary<object, string> ();
}
public override void WriteJson (JsonWriter writer, object value, JsonSerializer serializer)
@@ -287,10 +239,49 @@ namespace LongoMatch.DB
public override bool CanConvert (Type objectType)
{
+ bool ret;
+
if (!typeof(IStorable).IsAssignableFrom (objectType)) {
- return false;
+ ret = false;
+ } else {
+ ret = !localTypes.Contains (objectType);
+ }
+ return ret;
+ }
+
+ public object ResolveReference (object context, string reference)
+ {
+ object p;
+ _idtoobjects.TryGetValue (reference, out p);
+ return p;
+ }
+
+ public string GetReference (object context, object value)
+ {
+ string referenceStr;
+ if (value is IStorable) {
+ IStorable p = value as IStorable;
+ referenceStr = p.ID.ToString ();
+ } else {
+ if (!_objectstoid.TryGetValue (value, out referenceStr)) {
+ _references++;
+ referenceStr = _references.ToString (CultureInfo.InvariantCulture);
+ }
}
- return !localTypes.Contains (objectType);
+ _idtoobjects [referenceStr] = value;
+ _objectstoid [value] = referenceStr;
+ return referenceStr;
+ }
+
+ public bool IsReferenced (object context, object value)
+ {
+ return _objectstoid.ContainsKey (value);
+ }
+
+ public void AddReference (object context, string reference, object value)
+ {
+ _idtoobjects [reference] = value;
+ _objectstoid [value] = reference;
}
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]