diff options
Diffstat (limited to 'apps/drwho/BS_Server.cpp')
-rw-r--r-- | apps/drwho/BS_Server.cpp | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/apps/drwho/BS_Server.cpp b/apps/drwho/BS_Server.cpp new file mode 100644 index 00000000000..16e344b7cb2 --- /dev/null +++ b/apps/drwho/BS_Server.cpp @@ -0,0 +1,113 @@ +// $Id$ +#include "BS_Server.h" +#include "new.h" + +// This constructor takes a message of sorted login names and loads up +// the symbol table on the server's side. It assumes that the number +// of friends is stored in the first MAXUSERIDNAMELEN bytes of the +// packet. Note that we assume that the client sends the login names +// in sorted order, so we don't bother sorting them! + +BS_Server::BS_Server (char *packet) +{ + char *buf_ptr = packet + MAXUSERIDNAMELEN; + + this->count_ = atoi (packet); + this->buffer_ = buf_ptr; + this->protocol_record_ = + new (PRIVATE_POOL) Protocol_Record[this->count_]; + this->sorted_record_ = + new (PRIVATE_POOL) Protocol_Record *[this->count_]; + + for (int i = 0; i < this->count_; i++) + { + Protocol_Record *rec_ptr = &this->protocol_record_[i]; + + this->sorted_record_[i] = rec_ptr; + rec_ptr->key_name1_ = buf_ptr; + + // Skip forward to the start of the next login name. + + while (*buf_ptr++ != '\0') + continue; + } + +} + +// Insert the HOST_NAME into the appropriate DRWHO_LIST slot if the +// KEY_NAME happens to be one of our friends. Binary search is used +// because the Protocol_Manager keeps a sorted representation of the +// friend names. +// +// Note that this binary search is tuned for unsuccessful searches, +// since most of the time we the KEY_NAME is *not* a friend (unless +// you've got *lots* of friends)! +// +// Note finally that we keep a cache of the last KEY_NAME that is +// looked up, as well as the result of the lookup. This speeds things +// up because the whod files tend to cluster userids together. */ + +Protocol_Record * +BS_Server::insert (char *key_name, int max_len) +{ + static char last_lookup[MAXHOSTNAMELEN]; + static int mid = 0; + static int result = 0; + Protocol_Record **buffer = this->sorted_record; + + // First check the cache... + if (ACE_OS::strncmp (last_lookup, key_name, max_len) == 0) + { + if (result == 0) + return 0; + } + else + { + // Store this away in the cache for the next iteration. + ACE_OS::strncpy (last_lookup, key_name, max_len); + + int hi = this->count - 1; + int lo = 0; + int cmp; + + while (lo < hi) + { + mid = (hi + lo + 1) / 2; + + cmp = ACE_OS::strncmp (key_name, buffer[mid]->get_login (), max_len); + + if (cmp < 0) + hi = mid - 1; + else + lo = mid; + } + + // This line is very subtle... ;-) + if (!(cmp == 0 || ACE_OS::strncmp (key_name, buffer[--mid]->get_login (), max_len) == 0)) + { + result = 0; + return 0; + } + } + + // If we get here we've located a friend. + + result = 1; + return buffer[mid]; +} + +// Returns the next friend in the sequence of sorted friends. Skips +// over the entries that don't have any hosts associated with them +// (because these entries weren't on the server machine. */ + +Protocol_Record * +BS_Server::get_next_entry (void) +{ + Protocol_Record *frp; + + while ((frp = Binary_Search::get_next_entry ()) != 0) + if (frp->get_drwho_list () != 0) + return frp; + + return 0; +} |