以下のシナリオのコレクション クラスを探しています。
- 一度に 1 アイテムずつ、コレクションをすばやく検索します。
- コレクションには約 30 万点のアイテムが含まれています。
- コレクションの作成速度は重要ではないかもしれませんが、理想的には高速でもあります。
- コレクションがロードされると、更新/削除/挿入は必要ありません
Ip2Location
コレクションに入力されるタイプのアイテムの例:
public class Ip2Location
{
public long IpFrom {get; set;}
public long IpTo {get; set;}
public string Country {get; set;}
}
IpFrom IpTo Country
16909056 16909311 AU
16909312 16941055 US
コレクションに対するアイテムの検索は、次のように指定された IP を介して行われます。
IpFrom < currentIp < IpTo
参考リンクを含め、どんなアイデアでも大歓迎です!
比較:HashSet, SortedSet
より良いコレクションクラスはありますか?
参照: 以下のリンクの比較表: http://geekswithblogs.net/BlackRabbitCoder/archive/2011/06/16/c.net-fundamentals-choosing-the-right-collection-class.aspx
更新:
Array.BinarySearch の使用に関する問題:
var index = Array.BinarySearch(ipCountries, new IpCountry { IpFrom = 16909056}, new Ip2LocationComparer());
少数の行で機能し、300k アイテムでは機能しません (たとえば、インデックスは -(totalrow+1) です)。検索アイテムは、300 K アイテム コレクション内に読み込まれます。
public class Ip2LocationComparer: IComparer<IpCountry>
{
public int Compare(IpCountry x, IpCountry y)
{
if (x != null && y != null)
return (x.IpFrom <= y.IpFrom && y.IpFrom <= x.IpTo)? 0 : -1;
return -1;
}
}
更新 2
以下に変更しました
public class Ip2LocationComparer: IComparer<IpCountry>
{
public int Compare(IpCountry x, IpCountry y)
{
if (x != null && y != null)
{
if (x.IpFrom > y.IpFrom)
return 1;
if (x.IpFrom < y.IpFrom)
return -1;
if (x.IpFrom == y.IpFrom)
{
if (y.IpFrom > x.IpTo)
return 1;
if (y.IpFrom < x.IpTo)
return -1;
}
}
return 0;
}
しかし、BinarySearch からのインデックスの戻り値はまだネガティブで、一致するアイテムとフォローするアイテムのちょうど中間にあります。たとえば、検索 IpFrom が 3 の場合、インデックスは 2 から 4 の間です。なぜ 2 が返されないのですか? IpTo シナリオはまだテストしていません。
どんなアイデアでも大歓迎です!