Skip to content

Commit

Permalink
Engine: avoid Config locks when overrides are not used
Browse files Browse the repository at this point in the history
The locks in Config.get/set_Item() are quite expensive so we only do them when
overrides are actually in use.
  • Loading branch information
meebey committed Apr 14, 2024
1 parent 2e6e88c commit 49a5553
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 37 deletions.
54 changes: 36 additions & 18 deletions src/Engine/Config/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,25 @@ public class Config : PermanentRemoteObject
#endif
protected bool m_IsCleanConfig;
protected Hashtable m_Preferences = Hashtable.Synchronized(new Hashtable());
private Dictionary<string, object> m_Overrides;
public Version PreviousVersion { get; private set; }
public Version CurrentVersion { get; private set; }
internal Dictionary<string, object> Overrides { get; private set; }

public event EventHandler<ConfigChangedEventArgs> Changed;

public object this[string key] {
get {
// config overrides
lock (Overrides) {
foreach (var @override in Overrides) {
var pattern = @override.Key;
var value = @override.Value;
if (Pattern.IsMatch(key, pattern)) {
return value;
// config overrides hook
if (m_Overrides != null) {
lock (m_Overrides) {
foreach (var @override in m_Overrides) {
var pattern = @override.Key;
var value = @override.Value;
if (Pattern.IsMatch(key, pattern)) {
// honor config overrides by returning the
// overridden value instead
return value;
}
}
}
}
Expand All @@ -79,15 +84,19 @@ public object this[string key] {
return;
}

// config overrides
lock (Overrides) {
foreach (var @override in Overrides) {
var pattern = @override.Key;
if (Pattern.IsMatch(key, pattern)) {
#if LOG4NET
_Logger.Debug("set[]: ignoring setting an overridden config key " + key + ".");
#endif
return;
// config overrides hook
if (m_Overrides != null) {
lock (m_Overrides) {
foreach (var @override in m_Overrides) {
var pattern = @override.Key;
if (Pattern.IsMatch(key, pattern)) {
// honor config overrides by ignoring sets (writes) to
// overridden keys
#if LOG4NET
_Logger.Debug("set[]: ignoring setting an overridden config key " + key + ".");
#endif
return;
}
}
}
}
Expand All @@ -103,6 +112,16 @@ public object this[string key] {
}
}
}

internal Dictionary<string, object> Overrides {
get {
var overrides = m_Overrides;
if (overrides == null) {
m_Overrides = new Dictionary<string, object>();
}
return m_Overrides;
}
}

public bool IsCleanConfig {
get {
Expand All @@ -112,7 +131,6 @@ public bool IsCleanConfig {

public Config()
{
Overrides = new Dictionary<string, object>();
#if CONFIG_NINI
m_ConfigPath = Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData), "smuxi");
Expand Down
41 changes: 22 additions & 19 deletions src/Engine/Engine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,28 +179,31 @@ public static void Init()
_Config.Save();

// config overrides
// we only scan all config keys so we can convert the override
// value into the right type
foreach (var kvp in _Config.GetAll()) {
var configKey = kvp.Key;
var configValue = kvp.Value;

foreach (var @override in ConfigOverrides) {
var keyPattern = @override.Key;
if (ConfigOverrides != null) {
// we only scan all config keys here so we can convert the override
// string value into the actual type
foreach (var kvp in _Config.GetAll()) {
var configKey = kvp.Key;
var configValue = kvp.Value;

foreach (var @override in ConfigOverrides) {
var keyPattern = @override.Key;
if (!Pattern.IsMatch(configKey, keyPattern)) {
continue;
}

if (!Pattern.IsMatch(configKey, keyPattern)) {
continue;
}
// convert string to actual type
var overridenValue = Convert.ChangeType(@override.Value,
configValue.GetType());

// convert string to type
var overridenValue = Convert.ChangeType(@override.Value,
configValue.GetType());
// as the patttern could match many keys we only need one
// override with the right value type
if (_Config.Overrides.ContainsKey(keyPattern)) {
continue;
// as a patttern could match many keys we only need one
// override entry in _Config.Overrides with the right type and value
if (_Config.Overrides.ContainsKey(keyPattern)) {
// config key pattern exist already
continue;
}
_Config.Overrides.Add(keyPattern, overridenValue);
}
_Config.Overrides.Add(keyPattern, overridenValue);
}
}

Expand Down

0 comments on commit 49a5553

Please sign in to comment.