View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0001979 | unreal | ircd | public | 2004-07-19 05:00 | 2004-07-20 21:05 |
| Reporter | fez | Assigned To | |||
| Priority | normal | Severity | feature | Reproducibility | always |
| Status | closed | Resolution | open | ||
| Product Version | 3.2.1 | ||||
| Summary | 0001979: A question and possible request.... | ||||
| Description | Well, I was thinking about the data structures used by a multiplexing daemon, and it makes sense to use a hashtable, because, one of the most CPU intensive tasks is going through a possibly huge list of users to find a particular user. Same with channels. So you have a beautiful hashtable with a function like find_user_by_nickname which goes through a hash and returns a pointer to the user in very few (often 1) iterations. Then I realized, that one of the most frequently occuring situations where a userlist scan must take place doesn't even allow for nickname based searches I'm talking about when select() returns... you only get a set of socket numbers when select() returns, and there isn't really a way to use the hash for socket numbers. So I was wondering what your method is and possibly suggest another one... Do you just basically go like this: int i; for (i = 0; i <= MAXCLIENTS; i++) if (user[i] && FD_ISSET(user[i]->sockfd, read_set)) do_read(user[i]); (I know your variable names are all different but you get the idea) or do you have another method as I'm sure you could tell, the above method could be potentially very slow, espicially for very busy servers where select() is returning all the time... It also occured to me that you could have 2 hash tables of client pointers : one for name-based hashing and one for socketnumber-based hashing Or, you could even use a less complex data structure for the socket table, since all that needs to be compared are numbers. Perhaps a socket-number based binary tree of clients to go hand-in-hand with the nickname based hashtable of clients? If you haven't already implemented that, then my request would be for you to consider it. I realize it might have a negative memory impact, but I don't think it would be THAT bad since both tables would share the same group of client pointers (just in different orders)... Well, maybe I just have the wrong idea altogether, but if that is the case then could you give me a little explanation as to the technical side of how you deal with this apparent problem? Thanks -- fez | ||||
| 3rd party modules | |||||
|
|
of course, now that I think about it, FD_ISSET is simply a macro that returns true if a given socket is in the set; is there any function or macro like FD_GET_NEXT_SOCKET_IN_SET? I remember looking at post-preprocessed C code of FD_SET and FD_ISSET and it just uses an array of ints... (at least on win32, I heard that an fd_set is some kind of bitmask on *nix) Well... keep on truckin' -- fez |
|
|
Yeah, unfortunately, fd_set is implementation specific. So you really can't assume anything about it if you want to be portable. This is, however, one of the reasons why things like poll() are nicer. Because then instead of an fd_set, you get an array you can just iterate through. |
|
|
any word on implementing poll()? :P Of course it would also be nice for some kind of win32 port of poll()... I know the guy who wrote warftpd wrote a poll() library for win32 that just wraps select()... Well anyways.... |
|
|
That would be in the new I/O engine for 3.3*.. which would have much nicer things than crappy select/poll [epoll/kqueue/..! and I guess win32 stuff as well]. Somewhere about 6-12 months. |