473,760 Members | 8,623 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

System.Collecti ons.Generic.Sor tedDictionary - lookup and then iterateto next/previous in o(log(n)) time

Hi,

I am converting an existing native C++ program making heavy use of STL
to C#2.0 with STL usage replaced by the new generic collections. The
conversion has gone well to the point where I am replacing an STL map
instance by a System.Collecti ons.Generic.Sor tedDictionary instance. In
need the collection to be ordered, and to have o(log(n)) look up - that
is fine so far SortedDictionar y.TryGetValue does the job. I also need
the ability after a lookup to iterate to the next and previous values in
o(log(n)) time or better. In STL this is easy because map::find returns
an iterator. However, I can't see how to perform the equivalent
operation for a SortedDictionar y in o(log(n)) time. (Enumerating the
whole SortedDictionar y is o(n) for both average and worst case.)

Have I missed anything obvious? SortedDictionar y seems to be based on a
red-black tree - System.Collecti ons.Generic.Tre eSet - so the
data-structure appears to be rich enough, but the public methods of
SortedDictionar y do not appear to allow access to the functionality I need.

Thanks in advance for any replies.

Paul Delhanty
Cadcambridge Limited
http://www.cadcambridge.net
Nov 17 '05 #1
6 5946


Paul Delhanty wrote:
Have I missed anything obvious? SortedDictionar y seems to be based on a
red-black tree - System.Collecti ons.Generic.Tre eSet - so the
data-structure appears to be rich enough, but the public methods of
SortedDictionar y do not appear to allow access to the functionality I need.


SortedDictionar y can use the natural numbers as an iterator.

You can use IndexOfKey to obtain the index of your item. Then you can
add/subtract from that index and pass it to GetKey and GetByIndex to get
the Key/Value next to the original key.

Note, that you may need to "lock ( dict.SyncRoot )", during these
operations, and that you won't get an exception if the data-structure
changes while you are holding an index, unlike most other iterators in .NET.

--
Helge Jensen
mailto:he****** ****@slog.dk
sip:he********* *@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 17 '05 #2
Helge Jensen wrote:


Paul Delhanty wrote:
Have I missed anything obvious? SortedDictionar y seems to be based on
a red-black tree - System.Collecti ons.Generic.Tre eSet - so the
data-structure appears to be rich enough, but the public methods of
SortedDictionar y do not appear to allow access to the functionality I
need.

SortedDictionar y can use the natural numbers as an iterator.

You can use IndexOfKey to obtain the index of your item. Then you can
add/subtract from that index and pass it to GetKey and GetByIndex to get
the Key/Value next to the original key.

Note, that you may need to "lock ( dict.SyncRoot )", during these
operations, and that you won't get an exception if the data-structure
changes while you are holding an index, unlike most other iterators in
.NET.


Thanks very much for your reply.

I can't seem to find IndexOfKey on SortedDictionar y. I can see
IndexOfKey on SortedList, but that is an array based implementation
rather than a red-black tree as per SortedDictionar y, so I might expect
something like IndexOfKey.

Thanks for the lock ( dict.SyncRoot ) tip.

Paul Delhanty
Cadcambridge Limited
http://www.cadcambridge.net
Nov 17 '05 #3


Paul Delhanty wrote:
I can't seem to find IndexOfKey on SortedDictionar y. I can see
IndexOfKey on SortedList, but that is an array based implementation
rather than a red-black tree as per SortedDictionar y, so I might expect
something like IndexOfKey.


Ups, sorry. I obviously mixed up those 2 when reading -- haven't looked
at .NET2 too much yet, so I mistakenly read it as SortedList.

Here are a few ideas for what you could do, although I must admit i
don't really like them as good as just being able to obtain some kind of
iterator at lookup-point from data-structures that have ordering ;)

- If the data is first built and then repeatedly looked up, you can
build the data in a SortedDictionar y and when built, copy it to an array
which you can then index using the BinarySearch-functions

- Implement IDictionary<T> by extending SortedDictionar y. Use a
seperate hash-table to track previous/next relations.

- Use introspection to get at the implementation of SortedDictionar y
and hack up a class that will return a useable iterator. I don't think
the .NET runtime checks privacy, only the C# compiler -- don't quote me
on that though!

- Reimplement SortedDictionar y yourself, (you know red/black trees
are just such fun ;) and let it exhibit the methods you need.

- Implement IDictionary<T> using std::map from C++ through the
managed extensions for C++, and expose enough methods to make it work.

--
Helge Jensen
mailto:he****** ****@slog.dk
sip:he********* *@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 17 '05 #4
Helge Jensen wrote:


Paul Delhanty wrote:
I can't seem to find IndexOfKey on SortedDictionar y. I can see
IndexOfKey on SortedList, but that is an array based implementation
rather than a red-black tree as per SortedDictionar y, so I might
expect something like IndexOfKey.

Ups, sorry. I obviously mixed up those 2 when reading -- haven't looked
at .NET2 too much yet, so I mistakenly read it as SortedList.

Here are a few ideas for what you could do, although I must admit i
don't really like them as good as just being able to obtain some kind of
iterator at lookup-point from data-structures that have ordering ;)

- If the data is first built and then repeatedly looked up, you can
build the data in a SortedDictionar y and when built, copy it to an array
which you can then index using the BinarySearch-functions

- Implement IDictionary<T> by extending SortedDictionar y. Use a
seperate hash-table to track previous/next relations.

- Use introspection to get at the implementation of SortedDictionar y
and hack up a class that will return a useable iterator. I don't think
the .NET runtime checks privacy, only the C# compiler -- don't quote me
on that though!

- Reimplement SortedDictionar y yourself, (you know red/black trees are
just such fun ;) and let it exhibit the methods you need.

- Implement IDictionary<T> using std::map from C++ through the managed
extensions for C++, and expose enough methods to make it work.

Thanks once again for your reply.

I have reordered things so the data is first built and then repeatedly
queried, so I will do as you suggest with copying into an array and
using BinarySearch. That should be pretty efficient - like using a
sorted vector in STL.

As for the other suggestions, I don't really want to get into the
business of building and maintaining my own collections if I can help
it. If I had not been able to use the batch build first and then query
approach, I would probably have had to do one of the other things you
suggested though. Implementing using hash-tables to track previous-next
would probably have been fairly solid, even if less efficient than just
a straight red-black tree. Using introspection was not something that
occurred to me - I guess it would give the same o(log(n)) performance
for inserts etc, though I'm not sure about the constant term. As for
reimplementing, SortedDictionar y, I have just reconstructed and built
the source code using Lutz Roeder's Reflector (
http://www.aisto.com/roeder/dotnet/ ), but there is quite a lot and I am
glad that I won't have to maintain it now. Using C++, would work
though, I want to compile everything as safe, so as to be able to run in
a partial trust environment, so it would have had to have been the new
managed STL. I read somewhere recently, (I can't remember where), that
managed STL might not ship with Visual C++ 2005.

Anyway, once again, thanks for your help.
Paul Delhanty
Cadcambridge Limited
http://www.cadcambridge.net
Nov 17 '05 #5


Paul Delhanty wrote:
for inserts etc, though I'm not sure about the constant term. As for
reimplementing, SortedDictionar y, I have just reconstructed and built
the source code using Lutz Roeder's Reflector (
http://www.aisto.com/roeder/dotnet/ ), but there is quite a lot and I am


That was a nice and sneaky approach... perhaps you should read the EULA,
just to make sure you're not on shaky ground ;)

--
Helge Jensen
mailto:he****** ****@slog.dk
sip:he********* *@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 17 '05 #6
Helge Jensen wrote:


Paul Delhanty wrote:
for inserts etc, though I'm not sure about the constant term. As for
reimplementing, SortedDictionar y, I have just reconstructed and built
the source code using Lutz Roeder's Reflector (
http://www.aisto.com/roeder/dotnet/ ), but there is quite a lot and I am

That was a nice and sneaky approach... perhaps you should read the EULA,
just to make sure you're not on shaky ground ;)

Luckily your first suggestion about building the data first and then
querying first worked better anyway, so I was able to throw the
reflector generated code away :-) (I didn't want to maintain it anyway,
as it had a lot of legacy pre-generics stuff in there.)
Paul
Nov 17 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
4377
by: Doug Dew | last post by:
This won't compile: using IEnumerable<T> = System.Collections.Generic.IEnumerable<T>; namespace MyNamespace { public class MyClass<T> : IEnumerable<T> { // Appropriate stuff here }
3
15182
by: Abhi | last post by:
In the following hypothetical example I want to build a generic list of unique string items. How should I implement the pred function so that it returns true/false if target string exists in the generic list...is not clear to me. Any suggestions? System.Collections.Generic.List<string> list = new System.Collections.Generic.List<string>(); foreach(string s in myAnotherArray)
2
3310
by: ljlevend | last post by:
I've noticed that in VS.NET 2.0 Beta 1 that none of the methods in System.Collections.Generic.List are overridable. In my app I currently have over 50 strongly typed ArrayLists that inherit from System.Collections.ArrayList. Each of these types raise strongly typed events for when items are added and removed (e.g., AddingItem, AddedItem, CollectionChanged, etc.). One of my hopes for v2.0 was to create a single generic List that replaces...
4
8191
by: nhmark64 | last post by:
Hi, Does System.Collections.Generic.Queue not have a Synchronized method because it is already in effect synchronized, or is the Synchronized functionality missing from System.Collections.Generic.Queue? Putting it another way can I safely replace a System.Collections.Queue.Synchronized(myUnSynchronizedQueue) with a System.Collections.Generic.Queue while porting a working 2003 project? Thanks,
0
1161
by: Susan | last post by:
I have an issue with the System.Collections.Generic.List that I can't find anywhere else... My website suddenly starts giving off System.IndexOutOfRangeException: Index was outside the bounds of the array. errors in a spot that I cannot figure out the problem. It will work all day, then suddenly start giving off the error, which makes quite a bit fail. The error (System.IndexOutOfRangeException: Index was outside the bounds of the...
2
5100
by: pamela fluente | last post by:
Hi I am doing something like: Dim MiDict As New System.Collections.Generic.Dictionary(Of String, MyObject) how should I change the above so that the string comparison (key) is done using the case insensitive comparer ?
2
7361
by: Fred Heida | last post by:
Hi, i'm trying to (using managed C++) implment the IEnumerable<Tinterface on my class.. but have a problem with the 2 GetEnumerator method required.... what i have done is... generic<typename T> public ref class SetOfProxy : public System::Collections::Generic::IEnumerable<T>
2
2639
by: confused1234 | last post by:
Hi i'm trying to pass a field of type System.Collections.Generic.ICollection< FeedImage> to a function. I dont't have a clue what this icollection is. but i tried some code System.Collections.Generic.ICollection< FeedImage> imagea ; FeedImage fee = new FeedImage ("http://www.image.com/image.jpg", "http://www.image.com");
0
1337
by: DR | last post by:
System.Collections.Generic.List<intmyList = new System.Collections.Generic.List<int>(100); Does this preallocate 100 integers? Also, is there any way to preallocate an array of objects all at once? MyOb al= new MyOb; for (int z = 0; z < nCount; z++)
0
9521
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9333
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10107
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
7324
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6599
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5214
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5361
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3863
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2733
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.