Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

housekeeping: further cleanup #790

Merged
merged 1 commit into from
Jun 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* text=auto

# Text files that should be normalized to LF in odb.
*.cs text eol=lf diff=csharp
*.cs text diff=csharp
*.xaml text
*.config text
*.c text
Expand Down Expand Up @@ -40,6 +40,3 @@
*.pdb binary
*.sdf binary
*.7z binary

# Generated file should just use CRLF, it's fiiine
SolutionInfo.cs text eol=crlf diff=csharp
1 change: 0 additions & 1 deletion src/Akavache.Core/Akavache.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
<PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.2" />
<PackageReference Include="System.Reactive" Version="5.0.0" />
<PackageReference Include="Splat" Version="14.*" />
<PackageReference Include="IsExternalInit" Version="1.0.2" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
Expand Down
10 changes: 1 addition & 9 deletions src/Akavache.Core/BlobCache/BlobCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,7 @@ static BlobCache()
[SuppressMessage("Design", "CA1065: Properties should not fire exceptions.", Justification = "Extreme non standard case.")]
public static string ApplicationName
{
get
{
if (_applicationName is null)
{
throw new("Make sure to set BlobCache.ApplicationName on startup");
}

return _applicationName;
}
get => _applicationName ?? throw new("Make sure to set BlobCache.ApplicationName on startup");

set => _applicationName = value;
}
Expand Down
3 changes: 0 additions & 3 deletions src/Akavache.Core/BlobCache/CacheEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.

using System.Diagnostics.CodeAnalysis;

namespace Akavache;

/// <summary>
Expand Down Expand Up @@ -45,6 +43,5 @@ public CacheEntry(string? typeName, byte[] value, DateTimeOffset createdAt, Date
/// <summary>
/// Gets or sets the value of the entry.
/// </summary>
[SuppressMessage("FxCop.Style", "CA1819: Properties should not return arrays", Justification = "Legacy reasons.")]
public byte[] Value { get; protected set; }
}
9 changes: 3 additions & 6 deletions src/Akavache.Core/BlobCache/InMemoryBlobCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -225,12 +225,9 @@ public IObservable<byte[]> Get(string key)
}
}

if (entry is null)
{
return ExceptionHelper.ObservableThrowKeyNotFoundException<DateTimeOffset?>(key);
}

return Observable.Return<DateTimeOffset?>(entry.CreatedAt, Scheduler);
return entry is null
? ExceptionHelper.ObservableThrowKeyNotFoundException<DateTimeOffset?>(key)
: Observable.Return<DateTimeOffset?>(entry.CreatedAt, Scheduler);
}

/// <inheritdoc />
Expand Down
14 changes: 13 additions & 1 deletion src/Akavache.Core/BlobCache/ObjectWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,16 @@

namespace Akavache;

internal record ObjectWrapper<T>(T Value) : IObjectWrapper;
internal class ObjectWrapper<T> : IObjectWrapper
{
public ObjectWrapper()
{
}

public ObjectWrapper(T value)
{
Value = value;
}

public T? Value { get; set; }
}
19 changes: 5 additions & 14 deletions src/Akavache.Core/BulkOperationsMixin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,10 @@ public static IObservable<IDictionary<string, byte[]>> Get(this IBlobCache blobC
null => throw new ArgumentNullException(nameof(blobCache)),
IBulkBlobCache bulkCache => bulkCache.Get(keys),
_ => keys.ToObservable()
.SelectMany(x =>
{
return blobCache.Get(x)
.SelectMany(x => blobCache.Get(x)
.Select(y => new KeyValuePair<string, byte[]>(x, y))
.Catch<KeyValuePair<string, byte[]>, KeyNotFoundException>(_ =>
Observable.Empty<KeyValuePair<string, byte[]>>());
})
Observable.Empty<KeyValuePair<string, byte[]>>()))
.ToDictionary(k => k.Key, v => v.Value)
};

Expand Down Expand Up @@ -87,20 +84,14 @@ public static IObservable<Unit> Invalidate(this IBlobCache blobCache, IEnumerabl
/// <param name="blobCache">The blob cache to extract the values from.</param>
/// <param name="keys">The keys to get the values for.</param>
/// <returns>A observable with the specified values.</returns>
public static IObservable<IDictionary<string, T>> GetObjects<T>(this IBlobCache blobCache, IEnumerable<string> keys)
{
if (blobCache is IObjectBulkBlobCache bulkCache)
{
return bulkCache.GetObjects<T>(keys);
}

return keys.ToObservable()
public static IObservable<IDictionary<string, T>> GetObjects<T>(this IBlobCache blobCache, IEnumerable<string> keys) => blobCache is IObjectBulkBlobCache bulkCache
? bulkCache.GetObjects<T>(keys)
: keys.ToObservable()
.SelectMany(x => blobCache.GetObject<T>(x)
.Where(y => y is not null)
.Select(y => new KeyValuePair<string, T>(x, y!))
.Catch<KeyValuePair<string, T>, KeyNotFoundException>(_ => Observable.Empty<KeyValuePair<string, T>>()))
.ToDictionary(k => k.Key, v => v.Value);
}

/// <summary>
/// Inserts the specified key/value pairs into the blob.
Expand Down
9 changes: 1 addition & 8 deletions src/Akavache.Core/DependencyResolverMixin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.

using System.Diagnostics.CodeAnalysis;
using System.Reflection;

using Splat;
Expand All @@ -13,7 +12,6 @@ namespace Akavache;
/// <summary>
/// A set of mix-in associated with the <see cref="IDependencyResolver"/> interface.
/// </summary>
[SuppressMessage("FxCop.Analyzer", "CA1307: The behavior of 'string.Replace(string, string)' could vary based on the current user's locale settings", Justification = "Not all platforms allow locale.")]
public static class DependencyResolverMixin
{
/// <summary>
Expand Down Expand Up @@ -63,12 +61,7 @@ public static void InitializeAkavache(this IMutableDependencyResolver resolver,

var registerer = (IWantsToRegisterStuff?)Activator.CreateInstance(registerTypeClass);

if (registerer is null)
{
continue;
}

registerer.Register(resolver, readonlyDependencyResolver);
registerer?.Register(resolver, readonlyDependencyResolver);
}
}
}
13 changes: 13 additions & 0 deletions src/Akavache.Core/IsExternalInit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) 2022 .NET Foundation and Contributors. All rights reserved.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.

using System.ComponentModel;

namespace System.Runtime.CompilerServices;

[EditorBrowsable(EditorBrowsableState.Never)]
internal class IsExternalInit
{
}
7 changes: 1 addition & 6 deletions src/Akavache.Core/Json/JsonDateTimeOffsetTickConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,7 @@ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer

var data = serializer.Deserialize<DateTimeOffsetData>(reader);

if (data is null)
{
return null;
}

return (DateTimeOffset)data;
return data is null ? null : (DateTimeOffset)data;
}

public override bool CanConvert(Type objectType) => objectType == typeof(DateTimeOffset) || objectType == typeof(DateTimeOffset?);
Expand Down
2 changes: 1 addition & 1 deletion src/Akavache.Core/Json/JsonDateTimeTickConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ internal class JsonDateTimeTickConverter : JsonConverter
throw new ArgumentNullException(nameof(reader));
}

if (reader.TokenType != JsonToken.Integer && reader.TokenType != JsonToken.Date)
if (reader.TokenType is not JsonToken.Integer and not JsonToken.Date)
{
return null;
}
Expand Down
66 changes: 16 additions & 50 deletions src/Akavache.Core/Json/JsonSerializationMixin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
// See the LICENSE file in the project root for full license information.

using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Reactive.Threading.Tasks;

Expand Down Expand Up @@ -55,15 +54,9 @@ public static IObservable<Unit> InsertObject<T>(this IBlobCache blobCache, strin
/// <param name="keyValuePairs">The data to insert into the cache.</param>
/// <param name="absoluteExpiration">An optional expiration date.</param>
/// <returns>A Future result representing the completion of the insert.</returns>
public static IObservable<Unit> InsertAllObjects<T>(this IBlobCache blobCache, IDictionary<string, T> keyValuePairs, DateTimeOffset? absoluteExpiration = null)
{
if (blobCache is IObjectBlobCache objCache)
{
return objCache.InsertObjects(keyValuePairs, absoluteExpiration);
}

throw new NotImplementedException();
}
public static IObservable<Unit> InsertAllObjects<T>(this IBlobCache blobCache, IDictionary<string, T> keyValuePairs, DateTimeOffset? absoluteExpiration = null) => blobCache is IObjectBlobCache objCache
? objCache.InsertObjects(keyValuePairs, absoluteExpiration)
: throw new NotImplementedException();

/// <summary>
/// Get an object from the cache and deserialize it via the JSON
Expand Down Expand Up @@ -130,25 +123,19 @@ public static IObservable<IEnumerable<T>> GetAllObjects<T>(this IBlobCache blobC
/// <typeparam name="T">The type of item to get.</typeparam>
/// <returns>A Future result representing the deserialized object from
/// the cache.</returns>
public static IObservable<T?> GetOrFetchObject<T>(this IBlobCache blobCache, string key, Func<IObservable<T>> fetchFunc, DateTimeOffset? absoluteExpiration = null)
{
if (blobCache is null)
{
throw new ArgumentNullException(nameof(blobCache));
}

return blobCache.GetObject<T>(key).Catch<T?, Exception>(ex =>
public static IObservable<T?> GetOrFetchObject<T>(this IBlobCache blobCache, string key, Func<IObservable<T>> fetchFunc, DateTimeOffset? absoluteExpiration = null) => blobCache is null
? throw new ArgumentNullException(nameof(blobCache))
: blobCache.GetObject<T>(key).Catch<T?, Exception>(ex =>
{
var prefixedKey = blobCache.GetHashCode().ToString(CultureInfo.InvariantCulture) + key;

var result = Observable.Defer(fetchFunc)
.Do(x => blobCache.InsertObject(key, x, absoluteExpiration))
.Finally(() => _inflightFetchRequests.TryRemove(prefixedKey, out var _))
.Finally(() => _inflightFetchRequests.TryRemove(prefixedKey, out _))
.Multicast(new AsyncSubject<T>()).RefCount();

return (IObservable<T>)_inflightFetchRequests.GetOrAdd(prefixedKey, result);
});
}

/// <summary>
/// <para>
Expand All @@ -170,15 +157,9 @@ public static IObservable<IEnumerable<T>> GetAllObjects<T>(this IBlobCache blobC
/// <param name="absoluteExpiration">An optional expiration date.</param>
/// <returns>A Future result representing the deserialized object from
/// 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);
}
public static IObservable<T?> GetOrFetchObject<T>(this IBlobCache blobCache, string key, Func<Task<T>> fetchFunc, DateTimeOffset? absoluteExpiration = null) => blobCache is null
? throw new ArgumentNullException(nameof(blobCache))
: blobCache.GetOrFetchObject(key, () => fetchFunc().ToObservable(), absoluteExpiration);

/// <summary>
/// <para>
Expand All @@ -199,15 +180,9 @@ public static IObservable<IEnumerable<T>> GetAllObjects<T>(this IBlobCache blobC
/// <param name="absoluteExpiration">An optional expiration date.</param>
/// <returns>A Future result representing the deserialized object from
/// 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);
}
public static IObservable<T?> GetOrCreateObject<T>(this IBlobCache blobCache, string key, Func<T> fetchFunc, DateTimeOffset? absoluteExpiration = null) => blobCache is null
? throw new ArgumentNullException(nameof(blobCache))
: blobCache.GetOrFetchObject(key, () => Observable.Return(fetchFunc()), absoluteExpiration);

/// <summary>
/// Returns the time that the key was added to the cache, or returns
Expand Down Expand Up @@ -261,7 +236,6 @@ public static IObservable<IEnumerable<T>> GetAllObjects<T>(this IBlobCache blobC
/// 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 Down Expand Up @@ -360,15 +334,9 @@ public static IObservable<IEnumerable<T>> GetAllObjects<T>(this IBlobCache blobC
Func<DateTimeOffset, bool>? fetchPredicate = null,
DateTimeOffset? absoluteExpiration = null,
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);
}
Func<T, bool>? cacheValidationPredicate = null) => blobCache is null
? throw new ArgumentNullException(nameof(blobCache))
: blobCache.GetAndFetchLatest(key, () => fetchFunc().ToObservable(), fetchPredicate, absoluteExpiration, shouldInvalidateOnError, cacheValidationPredicate);

/// <summary>
/// Invalidates a single object from the cache. It is important that the Type
Expand Down Expand Up @@ -441,9 +409,7 @@ internal static byte[] SerializeObject<T>(T value)
var bytes = Encoding.UTF8.GetString(x, 0, x.Length);

var ret = JsonConvert.DeserializeObject<T>(bytes, settings);
#pragma warning disable CS8604 // Possible null reference argument.
return Observable.Return(ret);
#pragma warning restore CS8604 // Possible null reference argument.
}
catch (Exception ex)
{
Expand Down
4 changes: 2 additions & 2 deletions src/Akavache.Core/KeyedOperations/KeyedOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ internal abstract class KeyedOperation
/// </summary>
/// <param name="key">The key of the operation.</param>
/// <param name="id">The ID of the operation.</param>
public KeyedOperation(string key, int id)
protected KeyedOperation(string key, int id)
{
Key = key;
Id = id;
Expand Down Expand Up @@ -68,4 +68,4 @@ public override IObservable<Unit> EvaluateFunc()

return ret.Select(_ => Unit.Default);
}
}
}
3 changes: 1 addition & 2 deletions src/Akavache.Core/KeyedOperations/KeyedOperationQueue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.

using System.Diagnostics.CodeAnalysis;
using System.Globalization;

using Splat;

namespace Akavache;
Expand All @@ -24,7 +24,6 @@ public class KeyedOperationQueue : IKeyedOperationQueue, IEnableLogger, IDisposa
/// Initializes a new instance of the <see cref="KeyedOperationQueue"/> class.
/// </summary>
/// <param name="scheduler">The scheduler for Observable operations.</param>
[SuppressMessage("Design", "CA2000: call dispose", Justification = "Disposed by member")]
public KeyedOperationQueue(IScheduler? scheduler = null)
{
scheduler ??= BlobCache.TaskpoolScheduler;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,6 @@ protected static string GetAssemblyDirectoryName()
{
var assemblyDirectoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

if (assemblyDirectoryName is null)
{
throw new InvalidOperationException("The directory name of the assembly location is null");
}

return assemblyDirectoryName;
return assemblyDirectoryName ?? throw new InvalidOperationException("The directory name of the assembly location is null");
}
}
1 change: 1 addition & 0 deletions src/Akavache.Core/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// See the LICENSE file in the project root for full license information.

using System.Runtime.CompilerServices;

using Akavache.Core;

[assembly: InternalsVisibleTo("Akavache.Tests")]
Expand Down
Loading