Nп/п : 37 из 100
 От   : wij                                 2:5075/128        21 авг 23 19:11:29
 К    : Lew Pitcher                                           21 авг 23 05:15:02
 Тема : Re: Question about hsearch(3) ENTER method
----------------------------------------------------------------------------------
                                                                                 
@MSGID:
<dc2163fa-b747-4298-aaab-1b4be80389een@googlegroups.com> ce54c33d
@REPLY: 2@dont-email.me> 6047cfae
@REPLYADDR wij <wyniijj5@gmail.com>
@REPLYTO 2:5075/128 wij
@CHRS: CP866 2
@RFC: 1 0
@RFC-References:
<40b905c7-54ae-4e9f-bd6c-990f8e0e804an@googlegroups.com> 1@dont-email.me>
<124e2b02-b26c-48be-9d84-d18bc2322b86n@googlegroups.com> 2@dont-email.me>
@RFC-Message-ID:
<dc2163fa-b747-4298-aaab-1b4be80389een@googlegroups.com>
@TZUTC: -0700
@PID: G2/1.0
@TID: FIDOGATE-5.12-ge4e8b94
On Monday, August 21, 2023 at 10:14:10 PM UTC+8, Lew Pitcher wrote:
> On Mon, 21 Aug 2023 06:30:04 -0700, wij wrote: 

> > On Monday, August 21, 2023 at 8:28:18 PM UTC+8, Lew Pitcher wrote: 
> >> On Sun, 20 Aug 2023 23:05:31 -0700, wij wrote: 
> >> 
> >> > manpage of hsearch(3) says: 
> >> > ... 
> >> > The argument action determines what hsearch() does after an unsuccess- 
> >> > ful search. This argument must either have the value ENTER, meaning 
> >> > insert a copy of item (and return a pointer to the new hash table entry 
> >> > as the function result), or the value FIND, meaning that NULL should be 
> >> > returned. (If action is FIND, then data is ignored.) 
> >> > ... 
> >> > 
 > >> > When I want to insert an item into the hash table, I
invokes hsearch(item,ENTER). 
 > >> > But I only want to insert the item when it is not in
the hash table. How can I 
 > >> > do (Only invokes hsearch once. The manpage seems not
mentioning the condition I 
> >> > am looking for)?
> >[snip]
> >> It seems pretty clear: hsearch() will either 
> >> a) find the matching entry in the hash table, and return a pointer to the 
> >> struct entry that defines the key and data of the matching entry, or 
 > >> b) not find the matching entry, and return NULL (when ACTION
is set to FIND), or 
> >> c) not find the matching entry, insert the supplied struct entry into the 
> >> hash table, and return a pointer to it (when ACTION is set to ENTER) 
> >> 
> >> I believe that you are looking for the (c) behaviour; set ACTION to ENTER 
 > >> when you "want to insert an item into the hash table", and
to FIND when you 
> >> want to retrieve it. 

> >
> > None of the a,b,c option would work.
> Let me make sure that I understand the issue here
> > The usecase is like I am writting some kind of interpreter: 
> > 
> > Type a=1; 
> > Type a=2; 
> > 
> > When the first "a=1" is encountered, I ENTER "a" into the hash table.
> So, at the first call to hsearch(,ENTER), you supply a pointer to a 
> struct entry { 
> char *key; 
> void *data; 
> } something; 
> initialized so that something.key points to the name "a", and something.data 
> points to the data you want to set "a" to (presumably, 1). That hsearch() 
> function returns a non-NULL value (which should be a pointer to your 
> struct entry something;) indicating that it saved the given hashtable entry.
 > > When the second "a=2" is encountered, the ENTER (because the
parser saw `Type`) 
> > should fail because it declares the same name of variable twice.
 > Here, you should either first FIND, and decide what to do if
FIND is successful, 
> or ENTER and just re-use the struct entry * that hsearch() returned to you. 

> I guess the choice depends on what your interpreter is expecting to do: 
> If 
> Type a=2; 
> is supposed to define a new something, and fail if that something already 
> exists, then you should hsearch(,FIND), and fail if FIND succeeded (or, 
> alternately, hsearch(,ENTER), and check whether the returned pointer has 
> a ->data that differs from the value you prepared for the hsearch() call). 

> OTOH, if 
> Type a=2; 
> is permitted to update/replace/overwrite the prior 
> Type a=1; 
> then you just hsearch(,ENTER) and update the returned ->data with the 
> new value for the key "a".
> HTH 
> -- 
> Lew Pitcher 
> "In Skills We Trust"

class HSearch {
    ::hsearch data m htab;
    size t m maxe;

  public:
    //....

    template
    WY  WARNRET   Errno declare(const char* key, T data) {
      static assert(sizeof(T)<=sizeof(void*));
      static char kbuf[256];
      if(key==NULL) {
        WY RETURN( EFAULT );
      }
      if(m maxe==0) { 
        WY RETURN( EBADF);
      }
      const size t klen= strlen(key);
      if(klen>=sizeof(kbuf)) {
        WY RETURN( ENAMETOOLONG );
      }
      memcpy(kbuf,key,klen);
      kbuf[klen]=0;
      ::ENTRY item,*retv;
      item.key= const cast(kbuf);
      if(::hsearch r(item, ENTER,&retv,&m htab)==0) {
        WY RETURN(errno);
      }
      if(retv->key!=kbuf) {
        WY RETURN(EEXIST);
      }
      union {
        void * ptr;
        T val;
      } tt;
      tt.val=data;
      retv->key= const cast(key);    
      retv->data= tt.ptr;
      return Ok;
    };

};

I think hsearch can`t do what I want (directly). The work-around is copy the
key to a static buffer. The overhead is equ. to a single strcmp, so, fine.
The limit is string length.
I think the implement of declare(..) should comply with the spec. of hsearch 
(to be exactly, hsearch r), though such compliance is not explicitly stated.
How do you think?
--- G2/1.0
 * Origin: usenet.network (2:5075/128)
SEEN-BY: 5001/100 5005/49 5010/352 5015/255 5019/40
5020/715 848 1042 4441
SEEN-BY: 5020/12000 5030/49 1081 5075/128
@PATH: 5075/128 5020/1042 4441



   GoldED+ VK   │                                                 │   09:55:30    
                                                                                
В этой области больше нет сообщений.

Остаться здесь
Перейти к списку сообщений
Перейти к списку эх