Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
housekeeping: update to fix analyzer warnings/errors
  • Loading branch information
glennawatson committed Aug 6, 2019
1 parent 3f38977 commit e7dac46
Show file tree
Hide file tree
Showing 26 changed files with 317 additions and 77 deletions.
4 changes: 2 additions & 2 deletions src/Akavache.Core/Akavache.Core.csproj
Expand Up @@ -30,11 +30,11 @@
</ItemGroup>


<ItemGroup Condition=" ! $(TargetFramework.StartsWith('netstandard')) And ! $(TargetFramework.StartsWith('uap'))">
<ItemGroup Condition=" !$(TargetFramework.StartsWith('netstandard')) And !$(TargetFramework.StartsWith('uap'))">
<Compile Include="Platforms\shared-not-uwp\**\*.cs" />
</ItemGroup>

<ItemGroup Condition=" ! $(TargetFramework.StartsWith('netstandard')) ">
<ItemGroup Condition=" !$(TargetFramework.StartsWith('netstandard')) ">
<Compile Include="Platforms\shared\**\*.cs" />
</ItemGroup>

Expand Down
30 changes: 29 additions & 1 deletion src/Akavache.Core/BitmapImageMixin.cs
Expand Up @@ -27,6 +27,11 @@ public static class BitmapImageMixin
/// Observable is guaranteed to be returned on the UI thread.</returns>
public static IObservable<IBitmap> LoadImage(this IBlobCache blobCache, string key, float? desiredWidth = null, float? desiredHeight = null)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

return blobCache.Get(key)
.SelectMany(ThrowOnBadImageBuffer)
.SelectMany(x => BytesToImage(x, desiredWidth, desiredHeight));
Expand All @@ -47,6 +52,11 @@ public static IObservable<IBitmap> LoadImage(this IBlobCache blobCache, string k
/// Observable is guaranteed to be returned on the UI thread.</returns>
public static IObservable<IBitmap> LoadImageFromUrl(this IBlobCache blobCache, string url, bool fetchAlways = false, float? desiredWidth = null, float? desiredHeight = null, DateTimeOffset? absoluteExpiration = null)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

return blobCache.DownloadUrl(url, null, fetchAlways, absoluteExpiration)
.SelectMany(ThrowOnBadImageBuffer)
.SelectMany(x => BytesToImage(x, desiredWidth, desiredHeight));
Expand All @@ -67,6 +77,11 @@ public static IObservable<IBitmap> LoadImageFromUrl(this IBlobCache blobCache, s
/// Observable is guaranteed to be returned on the UI thread.</returns>
public static IObservable<IBitmap> LoadImageFromUrl(this IBlobCache blobCache, Uri url, bool fetchAlways = false, float? desiredWidth = null, float? desiredHeight = null, DateTimeOffset? absoluteExpiration = null)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

return blobCache.DownloadUrl(url, null, fetchAlways, absoluteExpiration)
.SelectMany(ThrowOnBadImageBuffer)
.SelectMany(x => BytesToImage(x, desiredWidth, desiredHeight));
Expand All @@ -88,6 +103,11 @@ public static IObservable<IBitmap> LoadImageFromUrl(this IBlobCache blobCache, U
/// Observable is guaranteed to be returned on the UI thread.</returns>
public static IObservable<IBitmap> LoadImageFromUrl(this IBlobCache blobCache, string key, string url, bool fetchAlways = false, float? desiredWidth = null, float? desiredHeight = null, DateTimeOffset? absoluteExpiration = null)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

return blobCache.DownloadUrl(key, url, null, fetchAlways, absoluteExpiration)
.SelectMany(ThrowOnBadImageBuffer)
.SelectMany(x => BytesToImage(x, desiredWidth, desiredHeight));
Expand All @@ -109,6 +129,11 @@ public static IObservable<IBitmap> LoadImageFromUrl(this IBlobCache blobCache, s
/// Observable is guaranteed to be returned on the UI thread.</returns>
public static IObservable<IBitmap> LoadImageFromUrl(this IBlobCache blobCache, string key, Uri url, bool fetchAlways = false, float? desiredWidth = null, float? desiredHeight = null, DateTimeOffset? absoluteExpiration = null)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

return blobCache.DownloadUrl(key, url, null, fetchAlways, absoluteExpiration)
.SelectMany(ThrowOnBadImageBuffer)
.SelectMany(x => BytesToImage(x, desiredWidth, desiredHeight));
Expand All @@ -129,7 +154,10 @@ public static IObservable<byte[]> ThrowOnBadImageBuffer(byte[] compressedImage)

private static IObservable<IBitmap> BytesToImage(byte[] compressedImage, float? desiredWidth, float? desiredHeight)
{
return BitmapLoader.Current.Load(new MemoryStream(compressedImage), desiredWidth, desiredHeight).ToObservable();
using (var ms = new MemoryStream(compressedImage))
{
return BitmapLoader.Current.Load(ms, desiredWidth, desiredHeight).ToObservable();
}
}
}
}
47 changes: 27 additions & 20 deletions src/Akavache.Core/BlobCache/InMemoryBlobCache.cs
Expand Up @@ -5,6 +5,7 @@

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reactive;
Expand All @@ -24,6 +25,7 @@ namespace Akavache
/// </summary>
public class InMemoryBlobCache : ISecureBlobCache, IObjectBlobCache, IEnableLogger
{
[SuppressMessage("Design", "CA2213: non-disposed field.", Justification = "Used for notification of dispose.")]
private readonly AsyncSubject<Unit> _shutdown = new AsyncSubject<Unit>();
private readonly IDisposable _inner;
private Dictionary<string, CacheEntry> _cache = new Dictionary<string, CacheEntry>();
Expand Down Expand Up @@ -441,37 +443,42 @@ private byte[] SerializeObject<T>(T value)
{
var settings = Locator.Current.GetService<JsonSerializerSettings>() ?? new JsonSerializerSettings();
settings.ContractResolver = new JsonDateTimeContractResolver(settings.ContractResolver, ForcedDateTimeKind); // This will make us use ticks instead of json ticks for DateTime.
var ms = new MemoryStream();
var serializer = JsonSerializer.Create(settings);
var writer = new BsonDataWriter(ms);

serializer.Serialize(writer, new ObjectWrapper<T> { Value = value });
return ms.ToArray();
using (var ms = new MemoryStream())
{
using (var writer = new BsonDataWriter(ms))
{
serializer.Serialize(writer, new ObjectWrapper<T> { Value = value });
return ms.ToArray();
}
}
}

private T DeserializeObject<T>(byte[] data)
{
var settings = Locator.Current.GetService<JsonSerializerSettings>() ?? new JsonSerializerSettings();
settings.ContractResolver = new JsonDateTimeContractResolver(settings.ContractResolver, ForcedDateTimeKind); // This will make us use ticks instead of json ticks for DateTime.
var serializer = JsonSerializer.Create(settings);
var reader = new BsonDataReader(new MemoryStream(data));
var forcedDateTimeKind = BlobCache.ForcedDateTimeKind;

if (forcedDateTimeKind.HasValue)
using (var reader = new BsonDataReader(new MemoryStream(data)))
{
reader.DateTimeKindHandling = forcedDateTimeKind.Value;
}
var forcedDateTimeKind = BlobCache.ForcedDateTimeKind;

try
{
return serializer.Deserialize<ObjectWrapper<T>>(reader).Value;
}
catch (Exception ex)
{
this.Log().Warn(ex, "Failed to deserialize data as boxed, we may be migrating from an old Akavache");
}
if (forcedDateTimeKind.HasValue)
{
reader.DateTimeKindHandling = forcedDateTimeKind.Value;
}

return serializer.Deserialize<T>(reader);
try
{
return serializer.Deserialize<ObjectWrapper<T>>(reader).Value;
}
catch (Exception ex)
{
this.Log().Warn(ex, "Failed to deserialize data as boxed, we may be migrating from an old Akavache");
}

return serializer.Deserialize<T>(reader);
}
}
}
}
30 changes: 30 additions & 0 deletions src/Akavache.Core/BulkOperationsMixin.cs
Expand Up @@ -23,6 +23,11 @@ public static class BulkOperationsMixin
/// <returns>A observable with the specified values.</returns>
public static IObservable<IDictionary<string, byte[]>> Get(this IBlobCache blobCache, IEnumerable<string> keys)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

if (blobCache is IBulkBlobCache bulkCache)
{
return bulkCache.Get(keys);
Expand All @@ -47,6 +52,11 @@ public static class BulkOperationsMixin
/// <returns>A observable which signals when complete.</returns>
public static IObservable<Unit> Insert(this IBlobCache blobCache, IDictionary<string, byte[]> keyValuePairs, DateTimeOffset? absoluteExpiration = null)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

if (blobCache is IBulkBlobCache bulkCache)
{
return bulkCache.Insert(keyValuePairs, absoluteExpiration);
Expand All @@ -66,6 +76,11 @@ public static IObservable<Unit> Insert(this IBlobCache blobCache, IDictionary<st
/// <returns>A observable with the specified values.</returns>
public static IObservable<IDictionary<string, DateTimeOffset?>> GetCreatedAt(this IBlobCache blobCache, IEnumerable<string> keys)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

if (blobCache is IBulkBlobCache bulkCache)
{
return bulkCache.GetCreatedAt(keys);
Expand All @@ -84,6 +99,11 @@ public static IObservable<Unit> Insert(this IBlobCache blobCache, IDictionary<st
/// <returns>A observable which signals when complete.</returns>
public static IObservable<Unit> Invalidate(this IBlobCache blobCache, IEnumerable<string> keys)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

if (blobCache is IBulkBlobCache bulkCache)
{
return bulkCache.Invalidate(keys);
Expand Down Expand Up @@ -128,6 +148,11 @@ public static IObservable<Unit> Invalidate(this IBlobCache blobCache, IEnumerabl
/// <returns>A observable which signals when complete.</returns>
public static IObservable<Unit> InsertObjects<T>(this IBlobCache blobCache, IDictionary<string, T> keyValuePairs, DateTimeOffset? absoluteExpiration = null)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

if (blobCache is IObjectBulkBlobCache bulkCache)
{
return bulkCache.InsertObjects(keyValuePairs, absoluteExpiration);
Expand All @@ -147,6 +172,11 @@ public static IObservable<Unit> InsertObjects<T>(this IBlobCache blobCache, IDic
/// <returns>A observable which signals when complete.</returns>
public static IObservable<Unit> InvalidateObjects<T>(this IBlobCache blobCache, IEnumerable<string> keys)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

if (blobCache is IObjectBulkBlobCache bulkCache)
{
return bulkCache.InvalidateObjects<T>(keys);
Expand Down
59 changes: 58 additions & 1 deletion src/Akavache.Core/Json/JsonSerializationMixin.cs
Expand Up @@ -6,6 +6,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Reactive;
Expand Down Expand Up @@ -37,6 +38,11 @@ public static class JsonSerializationMixin
/// <returns>An observable which signals when the insertion has completed.</returns>
public static IObservable<Unit> InsertObject<T>(this IBlobCache blobCache, string key, T value, DateTimeOffset? absoluteExpiration = null)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

if (blobCache is IObjectBlobCache objCache)
{
return objCache.InsertObject(key, value, absoluteExpiration);
Expand Down Expand Up @@ -76,6 +82,11 @@ public static IObservable<Unit> InsertAllObjects<T>(this IBlobCache blobCache, I
/// <returns>A Future result representing the object in the cache.</returns>
public static IObservable<T> GetObject<T>(this IBlobCache blobCache, string key)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

if (blobCache is IObjectBlobCache objCache)
{
return objCache.GetObject<T>(key);
Expand All @@ -93,6 +104,11 @@ public static IObservable<T> GetObject<T>(this IBlobCache blobCache, string key)
/// with the specified Type.</returns>
public static IObservable<IEnumerable<T>> GetAllObjects<T>(this IBlobCache blobCache)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

if (blobCache is IObjectBlobCache objCache)
{
return objCache.GetAllObjects<T>();
Expand Down Expand Up @@ -133,7 +149,12 @@ public static IObservable<IEnumerable<T>> GetAllObjects<T>(this IBlobCache blobC
/// the cache.</returns>
public static IObservable<T> GetOrFetchObject<T>(this IBlobCache blobCache, string key, Func<IObservable<T>> fetchFunc, DateTimeOffset? absoluteExpiration = null)
{
return blobCache.GetObject<T>(key).Catch<T, Exception>(_ =>
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

return blobCache.GetObject<T>(key).Catch<T, Exception>(ex =>
{
var prefixedKey = blobCache.GetHashCode().ToString(CultureInfo.InvariantCulture) + key;
Expand Down Expand Up @@ -165,6 +186,11 @@ public static IObservable<T> GetOrFetchObject<T>(this IBlobCache blobCache, stri
/// the cache.</returns>
public static IObservable<T> GetOrFetchObject<T>(this IBlobCache blobCache, string key, Func<Task<T>> fetchFunc, DateTimeOffset? absoluteExpiration = null)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

return blobCache.GetOrFetchObject(key, () => fetchFunc().ToObservable(), absoluteExpiration);
}

Expand All @@ -186,6 +212,11 @@ public static IObservable<T> GetOrFetchObject<T>(this IBlobCache blobCache, stri
/// the cache.</returns>
public static IObservable<T> GetOrCreateObject<T>(this IBlobCache blobCache, string key, Func<T> fetchFunc, DateTimeOffset? absoluteExpiration = null)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

return blobCache.GetOrFetchObject(key, () => Observable.Return(fetchFunc()), absoluteExpiration);
}

Expand All @@ -199,6 +230,11 @@ public static IObservable<T> GetOrCreateObject<T>(this IBlobCache blobCache, str
/// <returns>The date the key was created on.</returns>
public static IObservable<DateTimeOffset?> GetObjectCreatedAt<T>(this IBlobCache blobCache, string key)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

if (blobCache is IObjectBlobCache objCache)
{
return objCache.GetObjectCreatedAt<T>(key);
Expand Down Expand Up @@ -238,6 +274,7 @@ public static IObservable<T> GetOrCreateObject<T>(this IBlobCache blobCache, str
/// if the fetched value should be cached.</param>
/// <returns>An Observable stream containing either one or two
/// results (possibly a cached version, then the latest version).</returns>
[SuppressMessage("Design", "CA2000: call dispose", Justification = "Disposed by member")]
public static IObservable<T> GetAndFetchLatest<T>(
this IBlobCache blobCache,
string key,
Expand All @@ -247,6 +284,11 @@ public static IObservable<T> GetOrCreateObject<T>(this IBlobCache blobCache, str
bool shouldInvalidateOnError = false,
Func<T, bool> cacheValidationPredicate = null)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

var fetch = Observable.Defer(() => blobCache.GetObjectCreatedAt<T>(key))
.Select(x => fetchPredicate == null || x == null || fetchPredicate(x.Value))
.Where(x => x)
Expand Down Expand Up @@ -320,6 +362,11 @@ public static IObservable<T> GetOrCreateObject<T>(this IBlobCache blobCache, str
bool shouldInvalidateOnError = false,
Func<T, bool> cacheValidationPredicate = null)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

return blobCache.GetAndFetchLatest(key, () => fetchFunc().ToObservable(), fetchPredicate, absoluteExpiration, shouldInvalidateOnError, cacheValidationPredicate);
}

Expand All @@ -334,6 +381,11 @@ public static IObservable<T> GetOrCreateObject<T>(this IBlobCache blobCache, str
/// <returns>An observable that signals when the operation has completed.</returns>
public static IObservable<Unit> InvalidateObject<T>(this IBlobCache blobCache, string key)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

if (blobCache is IObjectBlobCache objCache)
{
return objCache.InvalidateObject<T>(key);
Expand All @@ -353,6 +405,11 @@ public static IObservable<Unit> InvalidateObject<T>(this IBlobCache blobCache, s
/// this.</remarks>
public static IObservable<Unit> InvalidateAllObjects<T>(this IBlobCache blobCache)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

if (blobCache is IObjectBlobCache objCache)
{
return objCache.InvalidateAllObjects<T>();
Expand Down

0 comments on commit e7dac46

Please sign in to comment.