Hi,
I've just implemented support for
h[ cKey ] => cKey
when cKey does not exists in hash array and of course it gives
optimal speed.
It can be enabled by setting hash array flags by hb_hSet*()
function.
Do you mean this? :
h := hb_hSetReturnKeyIfKeyDoesNotExistInHash({=>}, .T.)
? h["aaa"] // prints "aaa"
h["aaa"] := "bbb"
? h["aaa"] // prints "bbb"
I do not want to be stopper for new ideas, but I do not see this flag
(and possibility to return key value, if hash does not contain this key)
useful for general hash usage. Ok, it's good for i18n translation, but
do we know any other places it could be usefull? We will need to write
some i18n C code, this h[cKey] => cKey behaviour could be implemented in
i18n_gettext() function.
Syntax h[ @cKey ] gives possibility to test if array index is passed by
reference in virtual machine, but I think it's alien syntax. User can
never guess that passing by reference imply default return of value cKey.
I see the only useful (natural, widely used) extension for hashes. It is
HB_HGET() extension:
HB_HGET( hHash, xKey [, xDefaultValue ] )
It could be used not only in i18n context: HB_HGET( hHash, cKey, cKey ),
but also in other places. For example, if I store .ini file content in
hash, and want to get some application settings:
nPort := HB_HGET( hIni, "Port", 80 ),
nW := HB_HGET( hIni, "DefaultScreenWidth", 1280 ),
etc.
Of cause, HB_HGET( hHash, cKey, cKey ) is not speed optimal (cKey
parameters is passed twice), but if we want to chase for i18n string
lookup speed, we will need to implement i18n_gettext() in C anyway. So,
.prg level function HB_HGET() will not be used in implementation.
The side effect is
that we will not be able to return original key value, f.e.:
h := hb_hSetCastMatch( {=>}, .F. )
h[ "Mindaugas" ] := "Kavaliauskas"
for each v in h
? v:__enumKey(), v
next
will show:
MINDAUGAS Kavaliauskas
but I think it's worth to pay. If other developers will agree
with me then I'll change internal hash representation so keys
will be hashed when added and then always sorted in binary form.
I do not use case INsensitive hashes, but I think it's good idea! This
way we will not hide internal key value, that is actually used for key
comparison.
If I need case insensitive hash, I can always construct it using UPPER()
function.
h[UPPER(cKey)] := xValue
? h[UPPER(cKey)]
So, you proposal seems natural to me.
There is one related subject I wanted to talk about long ago.
Adding pointer items to hash keys introduced one side effect:
when pointer item is collectible item then it will never be freed
untill it exists as hash key. For some code it maybe interesting
feature because the address in memory will never be freed so new
pointer item with the same address should not appear but for some
other code it can cause problems when pointer item is still "alive"
as hash key and its detractor is not executed when all other instances
are out of scope. We can easy change it by translating collectible
pointer items to normal pointer items when they are stored as hash
keys. But I still do not know what is better so I would like to hear
other developers opinion.
The idea of collectible pointer is that Harbour internals tracks pointer
count and frees resources if pointer is not used. So, user can use code:
// aWndTitles is hash { window_collectable_pointer => title }
FOREACH cTitle IN aWndTitles
SetWindowText( cTitle:__enumKey, cTitle )
NEXT
I think we should not allow to user avoid tracking of collectible
pointers by default.
If user has a special needs and wants to avoid tracking of hash key
pointer, a function could be written to convert collectible pointer to
simple pointer. And hash could be created:
aWndTitles[ HB_SIMPLEPOINTER( window ) ] := "Some title"
But this will also have a side effect, if we add some typed C pointers
and support method calls for it. In this case usage of simple pointer
does not allows to use:
FOREACH cTitle IN aWndTitles
cTitle:__enumKey:SetWindowText( cTitle )
NEXT
So, I guess we should not convert collectible pointers to simple
pointers by default.
Best regards,
Mindaugas
_______________________________________________
Harbour mailing list
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour