Skip to content

Commit

Permalink
BUG: Lucene.Net.Benchmark.ByTask.Feeds.SpatialDocMaker: Since Diction…
Browse files Browse the repository at this point in the history
…ary this[key] is not marked virtual in .NET, subclassing Dictionary<string, string> is not a valid approach. So we implement IDictionary<string, string> instead.
  • Loading branch information
NightOwl888 committed Mar 15, 2021
1 parent ec65e26 commit 2731bfd
Showing 1 changed file with 57 additions and 5 deletions.
62 changes: 57 additions & 5 deletions src/Lucene.Net.Benchmark/ByTask/Feeds/SpatialDocMaker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Spatial4n.Core.Context;
using Spatial4n.Core.Shapes;
using System;
using System.Collections;
using System.Collections.Generic;
using Console = Lucene.Net.Util.SystemConsole;

Expand Down Expand Up @@ -70,31 +71,82 @@ protected virtual SpatialStrategy MakeSpatialStrategy(Config config)
//A Map view of Config that prefixes keys with "spatial."
var configMap = new DictionaryAnonymousClass(config);

SpatialContext ctx = SpatialContextFactory.MakeSpatialContext(configMap /*, null*/); // LUCENENET TODO: What is this extra param?
// LUCENENET: The second argument was ClassLoader in Java, which should be made into
// Assembly in .NET. However, Spatial4n currently doesn't support it.
// In .NET it makes more logical sense to make 2 overloads and throw NullReferenceException
// if the second argument is null, anyway. So no need to change this once support has been added.
// See: https://github.com/NightOwl888/Spatial4n/issues/1
SpatialContext ctx = SpatialContextFactory.MakeSpatialContext(configMap /*, assembly: null*/);

//Some day the strategy might be initialized with a factory but such a factory
// is non-existent.
return MakeSpatialStrategy(config, configMap, ctx);
}

private class DictionaryAnonymousClass : Dictionary<string, string>
// LUCENENET specific: since this[string] is not virtual in .NET, this full implementation
// of IDictionary<string, string> is required to override methods to get a value by key
private class DictionaryAnonymousClass : IDictionary<string, string>
{
private readonly Config config;
public DictionaryAnonymousClass(Config config)
{
this.config = config;
}

// LUCENENET TODO: EntrySet not supported. Should we throw on GetEnumerator()?
public string this[string key]
{
get => config.Get("spatial." + key, null);
set => throw new NotSupportedException();
}

public bool TryGetValue(string key, out string value)
{
value = config.Get("spatial." + key, null);
return value != null;
}

public bool ContainsKey(string key)
{
const string notSupported = "notsupported";
var value = config.Get("spatial." + key, notSupported);
return !value.Equals(notSupported, StringComparison.Ordinal);
}

#region IDictionary<string, string> members

ICollection<string> IDictionary<string, string>.Keys => throw new NotSupportedException();

ICollection<string> IDictionary<string, string>.Values => throw new NotSupportedException();

int ICollection<KeyValuePair<string, string>>.Count => throw new NotSupportedException();

public bool IsReadOnly => true;

void IDictionary<string, string>.Add(string key, string value) => throw new NotSupportedException();
void ICollection<KeyValuePair<string, string>>.Add(KeyValuePair<string, string> item) => throw new NotSupportedException();
void ICollection<KeyValuePair<string, string>>.Clear() => throw new NotSupportedException();
bool ICollection<KeyValuePair<string, string>>.Contains(KeyValuePair<string, string> item) => throw new NotSupportedException();

void ICollection<KeyValuePair<string, string>>.CopyTo(KeyValuePair<string, string>[] array, int arrayIndex) => throw new NotSupportedException();
IEnumerator<KeyValuePair<string, string>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator() => throw new NotSupportedException();
bool IDictionary<string, string>.Remove(string key) => throw new NotSupportedException();
bool ICollection<KeyValuePair<string, string>>.Remove(KeyValuePair<string, string> item) => throw new NotSupportedException();

IEnumerator IEnumerable.GetEnumerator() => throw new NotSupportedException();

new public string this[string key] => config.Get("spatial." + key, null);
#endregion IDictionary<string, string> members
}

protected virtual SpatialStrategy MakeSpatialStrategy(Config config, IDictionary<string, string> configMap,
SpatialContext ctx)
{
//A factory for the prefix tree grid
SpatialPrefixTree grid = SpatialPrefixTreeFactory.MakeSPT(configMap, /*null,*/ ctx); // LUCENENET TODO: What is this extra param?
// LUCENENET: The second argument was ClassLoader in Java, which should be made into
// Assembly in .NET. However, Spatial4n currently doesn't support it.
// In .NET it makes more logical sense to make 2 overloads and throw NullReferenceException
// if the second argument is null, anyway. So no need to change this once support has been added.
// See: https://github.com/NightOwl888/Spatial4n/issues/1
SpatialPrefixTree grid = SpatialPrefixTreeFactory.MakeSPT(configMap/*, assembly: null*/, ctx);

RecursivePrefixTreeStrategy strategy = new RecursivePrefixTreeStrategyAnonymousClass(grid, SPATIAL_FIELD, config);

Expand Down

0 comments on commit 2731bfd

Please sign in to comment.