aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Reed <ebr@mediabrowser3.com>2013-03-15 15:08:49 -0400
committerEric Reed <ebr@mediabrowser3.com>2013-03-15 15:08:49 -0400
commitc02ac2a8ca0a01e6951d5ccca13e98a118057505 (patch)
tree4e1215674203c4f9eaa95671727d72a4492f62b0
parentb86a03bbdcca3c03b2cd880e607472bc7b3d0850 (diff)
Manage some items as single instance throughout #54
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs6
-rw-r--r--MediaBrowser.Controller/Entities/BasePluginFolder.cs3
-rw-r--r--MediaBrowser.Controller/Entities/CollectionFolder.cs3
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs2
-rw-r--r--MediaBrowser.Controller/Library/ILibraryManager.cs7
-rw-r--r--MediaBrowser.Model/Entities/IByReferenceItem.cs16
-rw-r--r--MediaBrowser.Model/MediaBrowser.Model.csproj1
-rw-r--r--MediaBrowser.Server.Implementations/Library/LibraryManager.cs40
8 files changed, 70 insertions, 8 deletions
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 4f34f2b67..b7d2a75ec 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -24,7 +24,11 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
public abstract class BaseItem : IHasProviderIds
{
- /// <summary>
+ private Guid _testId = Guid.NewGuid();
+ public Guid TestId
+ {
+ get { return _testId; }
+ } /// <summary>
/// The trailer folder name
/// </summary>
public const string TrailerFolderName = "trailers";
diff --git a/MediaBrowser.Controller/Entities/BasePluginFolder.cs b/MediaBrowser.Controller/Entities/BasePluginFolder.cs
index 7cabcf9f0..ca6cfd246 100644
--- a/MediaBrowser.Controller/Entities/BasePluginFolder.cs
+++ b/MediaBrowser.Controller/Entities/BasePluginFolder.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Common.Extensions;
using System;
+using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Entities
{
@@ -7,7 +8,7 @@ namespace MediaBrowser.Controller.Entities
/// Plugins derive from and export this class to create a folder that will appear in the root along
/// with all the other actual physical folders in the system.
/// </summary>
- public abstract class BasePluginFolder : Folder, ICollectionFolder
+ public abstract class BasePluginFolder : Folder, ICollectionFolder, IByReferenceItem
{
/// <summary>
/// Gets or sets the id.
diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs
index a3db5ca26..091cbdc3b 100644
--- a/MediaBrowser.Controller/Entities/CollectionFolder.cs
+++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs
@@ -1,4 +1,5 @@
using MediaBrowser.Common.Extensions;
+using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Tasks;
using System;
using System.Collections.Concurrent;
@@ -15,7 +16,7 @@ namespace MediaBrowser.Controller.Entities
/// Specialized Folder class that points to a subset of the physical folders in the system.
/// It is created from the user-specific folders within the system root
/// </summary>
- public class CollectionFolder : Folder, ICollectionFolder
+ public class CollectionFolder : Folder, ICollectionFolder, IByReferenceItem
{
/// <summary>
/// Gets a value indicating whether this instance is virtual folder.
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index ef34742df..9e5096920 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -811,7 +811,7 @@ namespace MediaBrowser.Controller.Entities
/// <returns>IEnumerable{BaseItem}.</returns>
protected virtual IEnumerable<BaseItem> GetCachedChildren()
{
- return Kernel.Instance.ItemRepository.RetrieveChildren(this);
+ return Kernel.Instance.ItemRepository.RetrieveChildren(this).Select(i => i is IByReferenceItem ? LibraryManager.GetOrAddByReferenceItem(i) : i);
}
/// <summary>
diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs
index dd720d043..a69e06460 100644
--- a/MediaBrowser.Controller/Library/ILibraryManager.cs
+++ b/MediaBrowser.Controller/Library/ILibraryManager.cs
@@ -181,5 +181,12 @@ namespace MediaBrowser.Controller.Library
/// <param name="searchTerm">The search term.</param>
/// <returns>IEnumerable{BaseItem}.</returns>
IEnumerable<BaseItem> Search(IEnumerable<BaseItem> items, string searchTerm);
+
+ /// <summary>
+ /// Ensure supplied item has only one instance throughout
+ /// </summary>
+ /// <param name="item"></param>
+ /// <returns>The proper instance to the item</returns>
+ BaseItem GetOrAddByReferenceItem(BaseItem item);
}
} \ No newline at end of file
diff --git a/MediaBrowser.Model/Entities/IByReferenceItem.cs b/MediaBrowser.Model/Entities/IByReferenceItem.cs
new file mode 100644
index 000000000..7554ad36d
--- /dev/null
+++ b/MediaBrowser.Model/Entities/IByReferenceItem.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MediaBrowser.Model.Entities
+{
+ /// <summary>
+ /// This is a marker class that tells us that a particular item type may be physically resolved
+ /// more than once within the library and we need to be sure to resolve them all to the same
+ /// instance of that item.
+ /// </summary>
+ public interface IByReferenceItem
+ {
+ }
+}
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index 36f585e5c..5f76c49ca 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -45,6 +45,7 @@
<Compile Include="Dto\BaseItemPerson.cs" />
<Compile Include="Dto\ChapterInfoDto.cs" />
<Compile Include="Dto\IItemDto.cs" />
+ <Compile Include="Entities\IByReferenceItem.cs" />
<Compile Include="Querying\ItemsByNameQuery.cs" />
<Compile Include="Entities\BaseItemInfo.cs" />
<Compile Include="Connectivity\ClientConnectionInfo.cs" />
diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
index 549ea9be2..71fe6e125 100644
--- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
@@ -106,6 +106,13 @@ namespace MediaBrowser.Server.Implementations.Library
private IServerConfigurationManager ConfigurationManager { get; set; }
/// <summary>
+ /// A collection of items that may be referenced from multiple physical places in the library
+ /// (typically, multiple user roots). We store them here and be sure they all reference a
+ /// single instance.
+ /// </summary>
+ private ConcurrentDictionary<Guid, BaseItem> ByReferenceItems { get; set; }
+
+ /// <summary>
/// Initializes a new instance of the <see cref="LibraryManager" /> class.
/// </summary>
/// <param name="kernel">The kernel.</param>
@@ -120,6 +127,7 @@ namespace MediaBrowser.Server.Implementations.Library
_taskManager = taskManager;
_userManager = userManager;
ConfigurationManager = configurationManager;
+ ByReferenceItems = new ConcurrentDictionary<Guid, BaseItem>();
ConfigurationManager.ConfigurationUpdated += kernel_ConfigurationUpdated;
@@ -232,11 +240,35 @@ namespace MediaBrowser.Server.Implementations.Library
if (item != null)
{
ResolverHelper.SetInitialItemValues(item, args);
+
+ // Now handle the issue with posibly having the same item referenced from multiple physical
+ // places within the library. Be sure we always end up with just one instance.
+ if (item is IByReferenceItem)
+ {
+ item = GetOrAddByReferenceItem(item);
+ }
}
return item;
}
+
+ /// <summary>
+ /// Ensure supplied item has only one instance throughout
+ /// </summary>
+ /// <param name="item"></param>
+ /// <returns>The proper instance to the item</returns>
+ public BaseItem GetOrAddByReferenceItem(BaseItem item)
+ {
+ // Add this item to our list if not there already
+ if (!ByReferenceItems.TryAdd(item.Id, item))
+ {
+ // Already there - return the existing reference
+ item = ByReferenceItems[item.Id];
+ }
+ return item;
+ }
+
/// <summary>
/// Resolves a path into a BaseItem
/// </summary>
@@ -617,10 +649,10 @@ namespace MediaBrowser.Server.Implementations.Library
// Now validate the entire media library
await RootFolder.ValidateChildren(progress, cancellationToken, recursive: true).ConfigureAwait(false);
- foreach (var user in _userManager.Users)
- {
- await user.ValidateMediaLibrary(new Progress<double> { }, cancellationToken).ConfigureAwait(false);
- }
+ //foreach (var user in _userManager.Users)
+ //{
+ // await user.ValidateMediaLibrary(new Progress<double> { }, cancellationToken).ConfigureAwait(false);
+ //}
}
/// <summary>