[interfacekit] Re: BHandler::fToken

  • From: Ingo Weinhold <bonefish@xxxxxxxxxxxxxxx>
  • To: interfacekit@xxxxxxxxxxxxx
  • Date: Tue, 11 Mar 2003 20:18:30 +0100 (MET)

On Tue, 11 Mar 2003, Adi Oanca wrote:

> > enter the queue, and are
> > handled like all other messages. From the messages that are dispatched by
> > the window directly I don't really see a problem with finding the
> > destination.
> >
> > -Key messages: except for some exceptions, they go to the focus view,
> which
> > pointer is kept in BWindow::fFocus. They can also go to the default
> button,
> > which is kept in BWindow::fDefaultButton. If a command key is down, you
> find
> > the possible target in BWindow::accellist. View navigation is handled in
> > BWindow itself.
> >
> > -Mouse messages: if a view grabbed the pointer, it's sent to this one.
> > Otherwise a quick search through the view tree using the coordinates does
> > the trick.

That is definitely an information to be provided by the server. It
already knows the correct view, so why waste time on client side?

> Yes, and that I'm trying to avoid! Having a pointer to that view eliminates
> the search?!

There is still the alternative to use a hash map on client side to map
server tokens (or reuse the handler tokens and use the already existing
BTokenSpace) to BViews.

BTW, views can also subscribe to mouse events, even if the pointer is not
over the view.

> > > That way, when we receive a message that contains a server token, we,
> > > actually do a cast to BView*, witch is MUCH FASTER, and immediately call
> > > the BView's function we need!
> >
> > I find it quite dangerous to just cast something and call functions,
> without
> > doing any checking on it. When a view gets destroyed, there can still be
> > messages for it in the queue for example.
>
> I don't think that is going to happen! Possible, but I'll assure you I will
> eliminate
> that possibility! I'll have to see how!

That should be made really sure.

> > I also don't see why there would
> > be so much overhead. Even if you would do a FindView(where) call every
> time
> > you get a B_MOUSE_MOVED message, since the amount of checks in the view
> tree
> > is at most the depth of the tree. I think reading the parameters from the
> > BMessage takes more time then the searching.
>
> I don't need to read any parameter from any BMessage! Remember! BWindow
> creates a BMessage for a specified BView, and, I already know the
> token(address) (ServerWindow gave it to me!)

Right.

> > > If we do it like that, every ServerWindow object should have a hash
> table,
> > > with the key being BView's pointer, and Layer's pointer as the
> associated
> > > object. Ingo said that memory overhead for maintaining a hash table per
> > > window would be big compared with a single one for app_server. I totally
> > > disagree. The memory overhead will be the same. Either we have a big
> > > has table maintained for all  ServerWindows or we have a lot of small
> hash
> > > tables for every ServerWindow, the memory overhead will be the same.
> >
> > A hash table uses a bit more memory then the data it contains.
>
> A little bit...

That depends on the initial capacity of the hash table. If you start with
100 and only have 10 views, then you have a usage of 10%. If you have a
whole bunch of those windows, the overall usage is 10%. In case of a
global hash table for tokens, the usage will quite likely between
treshold/2 and threshold.

> > > PLUS, this is where we AGAIN gain some time(I might say - A LOT),
> > > because we only need to search through a relatively small(!) hash, not
> the
> > > entire list of Layers that exists on the app_server!
> >
> > A hash table is usually used to search fast through a relatively large
> list
> > in O(1) time.
>
> You must be kidding. It's complexity is O(n).

If you have a very bad hash function, i.e. one that maps all elements to
the same hash value, then you're right. Otherwise -- and when using
consecutive numbers as tokens this is hard to avoid :-) -- you have O(1)
complexity.

> > If you have a hash table for each window I think the hash
> > table is more of an overhead than a speed-up.
>
> Excuse me??? where is the extra overhead???

When using small hash tables, it is more likely that you'll need to
rehash, which costs time. In fact a global hash table needs to be rehashed
sometimes too, and that may actually be quite an effort, but on the other
hand this could also be done asynchronously. :-P

BTW, as a compromise one could use a hash table per application. Then the
object pointer is still a unique key and can also be used as hash value
directly. This does, of course, only work, if the tokens doesn't need to
be unique in the whole server.

As another compromise one can also use a global hash table and pointer
tokens, when using a longer key:

struct view_key {
  ServerWindow *window;
  void         *view_token;
} _PACKED;

> > > When adding a BView as a child of a BWindow, we actually attach the
> > > pointer in the creation message. When ServerWindow receives this message
> > > it creates a Layer, then adds an entry in the (local)hash table
> > > with BView's
> > > pointer being the key, and Layer's pointer being the associated object.
> > > When we detach the BView, we will send a message to ServerWindow
> > > with BView's server token attached, it will search the hash, find the
> > > correct entry, get Layer's pointer(AGAIN, gaining some speed(!),
> > > by avoiding a search in ServerWindow's list of Layers, where, again, no
> > > optimization is possible!), and use it do delete(after other calls have
> > > been made) that object.
> >
> > But the only place where you would ever need optimization are
> B_MOUSE_MOVED
> > messages, and the target can be found quite easy, since you have a tree
> with
> > the right properties to search through. Or am I overlooking another
> > frequently sent message?
>
> No, here you are right! Let me remind you that ServerWindow, also does a
> search through its tree of Layers, before sending a message to a BWindow.
> Now why would we do that twice? It is later, after we complete R1, that we
> will try to optimize our code, why not doing it now, when we already have a
> method?

Exactly.

> > As I understand it, the BMessage sent from the app_server would contain
> the
> > BView pointer, so you can call (token)->hook() directly. I really think
> the
> > overhead gained would be negligible, compared with the danger to
> stability.
>
> The only place where we could have a dangerous situation is if we still have
> a message in the queue who's token would be of a deleted BView! I'll try to
> resolve that situation!

OK.

CU, Ingo

Other related posts: