[f-spot/cleanup-backend: 16/23] Add SqliteCachedModelProvider to cache objects created from database



commit 55f2ac889227426f14cd2fbf2a6b945b5b084284
Author: Mike Gemünde <mike gemuende de>
Date:   Tue Jul 13 10:49:43 2010 +0200

    Add SqliteCachedModelProvider to cache objects created from database

 src/FSpot.Database/Makefile.am                  |    3 +-
 src/FSpot.Database/SqliteCachedModelProvider.cs |  118 +++++++++++++++++++++++
 2 files changed, 120 insertions(+), 1 deletions(-)
---
diff --git a/src/FSpot.Database/Makefile.am b/src/FSpot.Database/Makefile.am
index 6740f90..7f2d0e7 100644
--- a/src/FSpot.Database/Makefile.am
+++ b/src/FSpot.Database/Makefile.am
@@ -3,7 +3,8 @@ TARGET = library
 LINK = $(REF_FSPOT_DATABASE)
 
 SOURCES = \
-	FSpotDatabaseConnection.cs
+	FSpotDatabaseConnection.cs \
+	SqliteCachedModelProvider.cs
 
 
 RESOURCES =
diff --git a/src/FSpot.Database/SqliteCachedModelProvider.cs b/src/FSpot.Database/SqliteCachedModelProvider.cs
new file mode 100644
index 0000000..40e0aa5
--- /dev/null
+++ b/src/FSpot.Database/SqliteCachedModelProvider.cs
@@ -0,0 +1,118 @@
+//
+// SqliteCachedModelProvider.cs
+//
+// Author:
+//   Mike Gemuende <mike gemuende de>
+// 
+// Copyright (c) 2010 Mike Gemuende <mike gemuende de>
+//
+// This is free software. See COPYING for details.
+//
+
+using System;
+using System.Collections.Generic;
+
+using Hyena.Data.Sqlite;
+
+namespace FSpot.Database
+{
+
+    /// <summary>
+    ///    This class implements a SqliteModelProvider where the provided items are cached,
+    ///    i.e. the items which are created are stored in a cache that they do not need to
+    ///    be recreated every time.
+    ///    This is not the same behavior a SqliteModelCache provides. An SqliteModelCache,
+    ///    caches a model in the database itself. This class caches the created items from
+    ///    database.
+    /// </summary>
+    public class SqliteCachedModelProvider<T> : SqliteModelProvider<T> where T : new()
+    {
+
+#region Private Fields
+
+        private Dictionary<long, WeakReference> cache = new Dictionary<long, WeakReference> ();
+
+#endregion
+
+#region Constructors
+
+        protected SqliteCachedModelProvider (HyenaSqliteConnection connection) : base(connection)
+        {
+        }
+
+        public SqliteCachedModelProvider (HyenaSqliteConnection connection, string table_name) : base(connection, table_name)
+        {
+        }
+
+        public SqliteCachedModelProvider (HyenaSqliteConnection connection, string table_name, bool check_table) : base(connection, table_name, check_table)
+        {
+        }
+
+#endregion
+
+
+#region Cache Access
+
+        // TODO: make threadsafe
+
+        protected void AddToCache (long id, T item)
+        {
+            WeakReference pointer;
+            
+            if (cache.TryGetValue (id, out pointer)) {
+                pointer.Target = item;
+                return;
+            }
+            
+            cache.Add (id, new WeakReference (item));
+        }
+
+        protected T LookupInCache (long id)
+        {
+            WeakReference pointer;
+            
+            if (cache.TryGetValue (id, out pointer))
+                return (T)pointer.Target;
+            
+            return default(T);
+        }
+
+#endregion
+
+        public override T Load (System.Data.IDataReader reader)
+        {
+            long id = PrimaryKeyFor (reader);
+            
+            T item = LookupInCache (id);
+            
+            if (item != null)
+                return item;
+            
+            item = base.Load (reader);
+            
+            AddToCache (id, item);
+            
+            Populate (item);
+            
+            return item;
+        }
+
+        public override T FetchSingle (long id)
+        {
+            // This function should behave as expected even if it is not overwritten.
+            // But, this implementation should be a little bit faster because it does not
+            // query to database if the item is still cached.
+            T item = LookupInCache (id);
+            
+            if (item != null)
+                return item;
+            
+            return base.FetchSingle (id);
+        }
+
+
+        protected virtual void Populate (T item)
+        {
+        }
+    }
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]