Collection for fast read in C#
<p>I am looking for a collection class for the scenario below:</p>

<ul>
<li>Fast collection lookup, one item at a time.</li>
<li>The collection contains around 300 K items. </li>
<li>Collection population speed might not be important, but ideally fast too.</li>
<li>No update/delete/insert is needed once collection is loaded</li>
</ul>

<p>Example of items of type <code>Ip2Location</code> that would be populated into the collection:</p>

<pre><code>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
</code></pre>

<p>Item lookup against the collection is done via a specified IP, like this:</p>

<pre><code>IpFrom &lt; currentIp &lt; IpTo
</code></pre>

<p>Any ideas, including reference links, would be very much appreciated!</p>

<p>Comparison: <code>HashSet, SortedSet</code></p>

<p>Are there any better collection classes? </p>

<p>Reference: the comparison table in the link below:
<a href="http://geekswithblogs.net/BlackRabbitCoder/archive/2011/06/16/c.net-fundamentals-choosing-the-right-collection-class.aspx" rel="nofollow">http://geekswithblogs.net/BlackRabbitCoder/archive/2011/06/16/c.net-fundamentals-choosing-the-right-collection-class.aspx</a></p>

<p><strong>Update</strong>:</p>

<p>Problem using Array.BinarySearch:</p>

<pre><code>var index = Array.BinarySearch(ipCountries, new IpCountry { IpFrom = 16909056}, new Ip2LocationComparer());
</code></pre>

<p>It works in small numbers of row, doesn't work in 300k items (e.g. index is -(totalrow+1) ). The search item is loaded within the 300 K items collection.</p>

<pre><code>        public class Ip2LocationComparer: IComparer&lt;IpCountry&gt;
        {
            public int Compare(IpCountry x, IpCountry y)
            {
                if (x != null &amp;&amp; y != null)
                    return (x.IpFrom &lt;= y.IpFrom &amp;&amp; y.IpFrom &lt;= x.IpTo)? 0 : -1;

                return -1;

            }
        }
</code></pre>

<p><strong>Update 2</strong></p>

<p>I changed it to below</p>

<pre><code>public class Ip2LocationComparer: IComparer&lt;IpCountry&gt;
            {
                public int Compare(IpCountry x, IpCountry y)
                {
       if (x != null &amp;&amp; y != null)

            {
                if (x.IpFrom &gt; y.IpFrom)
                    return 1;

                if (x.IpFrom &lt; y.IpFrom)
                    return -1;

                if (x.IpFrom == y.IpFrom)
                {
                    if (y.IpFrom &gt; x.IpTo)
                        return 1;

                    if (y.IpFrom &lt; x.IpTo)
                        return -1;

                }

            }

            return 0;
}
</code></pre>

<p>But the index return from BinarySearch is still nagtive, which is right between the matching item and the follow item. e.g. if my search IpFrom is 3, the index is between 2 and 4. Why it doen't return 2? I haven't test the IpTo scenario yet.</p>

<p>Any idea would be appreciated!</p>
