Skip to content

Commit

Permalink
Introduce njs_atom_atomize_key().
Browse files Browse the repository at this point in the history
  • Loading branch information
VadimZhestikov committed Nov 5, 2024
1 parent 96e261e commit 88807fd
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 1 deletion.
84 changes: 84 additions & 0 deletions src/njs_atom.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,87 @@ njs_atom_hash_init()
return;
};


/*
* value is always key: string or number or symbol.
*
* symbol always contians atom_id by construction. do nothing;
* number if short number it is atomized by "| 0x80000000";
* string if represents short number it is atomized by "| 0x80000000";
*
* for string and symbol atom_ids common range is uint32_t < 0x80000000.
*/

njs_int_t
njs_atom_atomize_key(njs_vm_t *vm, njs_value_t *value)
{
double num;
uint32_t hash_id;
njs_int_t ret;
njs_value_t val_str;
const njs_value_t *entry;

switch (value->type) {
case NJS_STRING:
num = njs_key_to_index(value);
if (njs_fast_path(njs_key_is_integer_index(num, value)) &&
((uint32_t) num) < 0x80000000)
{
value->atom_id = ((uint32_t) num) | 0x80000000;

} else {
hash_id = njs_djb_hash(value->string.data->start,
value->string.data->size);

entry = njs_lexer_keyword_find(vm, value->string.data->start,
value->string.data->size,
value->string.data->length,
hash_id);
if (njs_slow_path(entry == NULL)) {
return NJS_ERROR;
}

/* TODO: if (<<value is string>>) <<try release>>(string) */
*value = *entry;
}
break;

case NJS_NUMBER:
num = value->data.u.number;
if (njs_fast_path(njs_key_is_integer_index(num, value)) &&
((uint32_t) num) < 0x80000000)
{
value->atom_id = ((uint32_t) num) | 0x80000000;

} else {
/* convert num to string, and atomize it. */
ret = njs_number_to_string(vm, &val_str, value);
if (ret != NJS_OK) {
return ret;
}

if (val_str.atom_id == 0) {
hash_id = njs_djb_hash(val_str.string.data->start,
val_str.string.data->size);

entry = njs_lexer_keyword_find(vm, val_str.string.data->start,
val_str.string.data->size,
val_str.string.data->length,
hash_id);
if (njs_slow_path(entry == NULL)) {
return NJS_ERROR;
}

value->atom_id = entry->atom_id;

} else {
value->atom_id = val_str.atom_id;
}
}
break;
default:
/* NJS_SYMBOL: do nothing. */
}

return NJS_OK;
}
2 changes: 2 additions & 0 deletions src/njs_atom.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ typedef struct {


void njs_atom_hash_init(void);
njs_int_t njs_atom_atomize_key(njs_vm_t *vm, njs_value_t *value);


extern njs_atom_values_t njs_atom;
extern njs_flathsh_t njs_atom_hash;
extern uint32_t njs_atom_hash_atom_id;


#endif /* _NJS_ATOM_H_INCLUDED_ */
2 changes: 1 addition & 1 deletion src/njs_lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ njs_lexer_hash_test(njs_lvlhsh_query_t *lhq, void *data)
}


static njs_value_t *
njs_value_t *
njs_lexer_keyword_find(njs_vm_t *vm, u_char *key, size_t size, size_t length,
uint32_t hash)
{
Expand Down
2 changes: 2 additions & 0 deletions src/njs_lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,8 @@ njs_int_t njs_lexer_in_stack_push(njs_lexer_t *lexer);
void njs_lexer_in_stack_pop(njs_lexer_t *lexer);
void njs_lexer_in_fail_set(njs_lexer_t *lexer, njs_int_t flag);
njs_int_t njs_lexer_in_fail_get(njs_lexer_t *lexer);
njs_value_t *njs_lexer_keyword_find(njs_vm_t *vm, u_char *key, size_t size,
size_t length, uint32_t hash);


const njs_lexer_keyword_entry_t *njs_lexer_keyword(const u_char *key,
Expand Down

0 comments on commit 88807fd

Please sign in to comment.