-
Notifications
You must be signed in to change notification settings - Fork 40
Simplify data structure #266
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
base: dev
Are you sure you want to change the base?
Simplify data structure #266
Conversation
# Conflicts: # src/Hocon.API.Tests/HoconAPISpec.ApproveConfiguration.approved.txt # src/Hocon.Configuration/Config.cs # src/Hocon.Configuration/HoconConfigurationFactory.cs
…n irrepairable critical error.
# Conflicts: # Hocon.sln
…eflects the memory cost of the lookup spec
# Conflicts: # src/Hocon.API.Tests/HoconAPISpec.ApproveCore.approved.txt # src/Hocon/HoconObject.cs
…into Simplify_Data_Structure
…_Data_Structure_Fast_Forwarded
…_Data_Structure_Fast_Forwarded
…_Data_Structure_Fast_Forwarded
…_Data_Structure_Fast_Forwarded
…ure_Fast_Forwarded # Conflicts: # src/Hocon.Configuration/HoconConfigurationFactory.cs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some changes, some questions
@@ -45,7 +45,6 @@ | |||
<ItemGroup> | |||
<ProjectReference Include="..\Hocon.Configuration\Hocon.Configuration.csproj" /> | |||
<ProjectReference Include="..\Hocon.Extensions.Configuration\Hocon.Extensions.Configuration.csproj" /> | |||
<ProjectReference Include="..\Hocon.Immutable\Hocon.Immutable.csproj" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, good to see Hocon.Immutable getting disposed
public static Hocon.Config Empty { get; } | ||
public virtual System.Collections.Generic.IReadOnlyList<Hocon.HoconValue> Fallbacks { get; } | ||
public virtual System.Collections.Generic.IReadOnlyList<Hocon.HoconObject> Fallbacks { get; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the significance of this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no such thing as HoconValue
anymore, the structure is simplified.
public string ToString(bool useFallbackValues) { } | ||
protected override bool TryGetNode(Hocon.HoconPath path, out Hocon.HoconValue result) { } | ||
public override bool TryGetValue(Hocon.HoconPath path, out Hocon.HoconElement result) { } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above - what's the significance of this change too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as the above, there is no HoconValue
class.
} | ||
public sealed class HoconBool : Hocon.HoconLiteral | ||
public sealed class HoconArrayBuilder : System.Collections.Generic.List<Hocon.HoconElement> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like the idea of using the builder pattern to build up the HOCON, but we need to avoid inheriting directly from mutable base classes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no danger, the builder pattern is only used for building the hocon classes, all the returned built classes are immutable.
@@ -31,19 +31,6 @@ public class MyObjectConfig | |||
public int[] IntergerArray { get; set; } | |||
} | |||
|
|||
[Fact] | |||
public void Config_should_be_serializable() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fine deferring this for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is moved to SerializationSpec. Config does not support direct JSON serialization anymore, because of immutability.
|
||
namespace Hocon | ||
{ | ||
public sealed class HoconObjectBuilder : SortedDictionary<string, HoconElement> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above - might want to make internal
|
||
public new HoconElement this[string path] { | ||
get => GetValue(path); | ||
set => throw new InvalidOperationException("HoconObject is a read only Dictionary."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we avoid this by just not inheriting from IDictionary
- leave it as IReadOnlyDictionary
only? Or did you need this for testing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IDictionary
interface is needed for backward compatibility, I've blocked all of the write behaviour
if(root is Config cfg) | ||
{ | ||
Root = cfg.Root; | ||
_fallbacks = cfg._fallbacks.ToList(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the ToList()
call necessary here? Can the cfg._fallbacks
property be modified?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, each Config
instance need to have their own separate instance of fallbacks, else changing (appending a new fallback value in WithFallback
) will affect ALL Config
objects before it.
protected List<HoconValue> _fallbacks { get; } = new List<HoconValue>(); | ||
public virtual IReadOnlyList<HoconValue> Fallbacks => _fallbacks.ToList().AsReadOnly(); | ||
protected List<HoconObject> _fallbacks { get; } = new List<HoconObject>(); | ||
public virtual IReadOnlyList<HoconObject> Fallbacks => _fallbacks.ToList().AsReadOnly(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to call ToList().AsReadOnly()
- List<T>
is castable to IReadOnlyList<T>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Defensive coding, I want to be 100% sure that the user could not change the internal representation of the fallback list.
|
||
if (fallback.IsNullOrEmpty()) | ||
return this; // no-op | ||
|
||
if (IsEmpty) | ||
return fallback; | ||
|
||
return new Config(this, fallback); | ||
var result = new Config(this); | ||
result.MergeConfig(fallback); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this just appends the latest fallback to what position on the linked list?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fallbacks are always added to the back of the chain
Going to do a perf comparison in a second - stay tuned |
Sigh, all of my performance comparison posts got added to here by accident: akkadotnet/akka.net#4301 (comment) Performance in this PR is looking good. |
Remove implicit casting