Skip to content

Commit

Permalink
Fixed cache flag not honored in compat mode
Browse files Browse the repository at this point in the history
  • Loading branch information
ohler55 committed Jul 8, 2021
1 parent 6d285b2 commit 3b110dc
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 26 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,10 @@
# CHANGELOG

## 3.12.1 - 2021-07-09

- Fixed `:cache_keys` not being honored in compat mode.
- Increased the cache size.

## 3.12.0 - 2021-07-05

- Added string and symbol caching options that give Oj about a 20% parse performance boost.
Expand Down
36 changes: 22 additions & 14 deletions ext/oj/compat.c
Expand Up @@ -26,22 +26,30 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);

if (Qundef == rkey) {
VALUE *slot;

if (Yes == pi->options.sym_key) {
if (Qnil == (rkey = oj_sym_hash_get(key, klen, &slot))) {
rkey = rb_str_new(key, klen);
rkey = oj_encode(rkey);
rkey = rb_str_intern(rkey);
*slot = rkey;
rb_gc_register_address(slot);
if (Yes != pi->options.cache_keys) {
rkey = rb_str_new(key, klen);
rkey = oj_encode(rkey);
if (Yes == pi->options.sym_key) {
rkey = rb_str_intern(rkey);
}
} else {
if (Qnil == (rkey = oj_str_hash_get(key, klen, &slot))) {
rkey = rb_str_new(key, klen);
rkey = oj_encode(rkey);
*slot = rkey;
rb_gc_register_address(slot);
VALUE *slot;

if (Yes == pi->options.sym_key) {
if (Qnil == (rkey = oj_sym_hash_get(key, klen, &slot))) {
rkey = rb_str_new(key, klen);
rkey = oj_encode(rkey);
rkey = rb_str_intern(rkey);
*slot = rkey;
rb_gc_register_address(slot);
}
} else {
if (Qnil == (rkey = oj_str_hash_get(key, klen, &slot))) {
rkey = rb_str_new(key, klen);
rkey = oj_encode(rkey);
*slot = rkey;
rb_gc_register_address(slot);
}
}
}
}
Expand Down
34 changes: 28 additions & 6 deletions ext/oj/hash.c
Expand Up @@ -5,8 +5,8 @@

#include <stdint.h>

#define HASH_MASK 0x000003FF
#define HASH_SLOT_CNT 1024
#define HASH_SLOT_CNT ((uint32_t)8192)
#define HASH_MASK (HASH_SLOT_CNT - 1)

typedef struct _keyVal {
struct _keyVal *next;
Expand Down Expand Up @@ -104,8 +104,8 @@ static VALUE hash_get(Hash hash, const char *key, size_t len, VALUE **slotp, VAL
}

void oj_hash_print() {
int i;
KeyVal b;
uint32_t i;
KeyVal b;

for (i = 0; i < HASH_SLOT_CNT; i++) {
printf("%4d:", i);
Expand All @@ -116,6 +116,29 @@ void oj_hash_print() {
}
}

void oj_hash_sizes() {
uint32_t i;
KeyVal b;
int max = 0;
int min = 1000000;

for (i = 0; i < HASH_SLOT_CNT; i++) {
int cnt = 0;

for (b = str_hash.slots + i; 0 != b && 0 != b->key; b = b->next) {
cnt++;
}
// printf(" %4d\n", cnt);
if (max < cnt) {
max = cnt;
}
if (cnt < min) {
min = cnt;
}
}
printf("min: %d max: %d\n", min, max);
}

VALUE
oj_class_hash_get(const char *key, size_t len, VALUE **slotp) {
return hash_get(&class_hash, key, len, slotp, Qnil);
Expand All @@ -131,8 +154,7 @@ oj_sym_hash_get(const char *key, size_t len, VALUE **slotp) {
return hash_get(&sym_hash, key, len, slotp, Qnil);
}

ID
oj_attr_hash_get(const char *key, size_t len, ID **slotp) {
ID oj_attr_hash_get(const char *key, size_t len, ID **slotp) {
return (ID)hash_get(&intern_hash, key, len, (VALUE **)slotp, 0);
}

Expand Down
9 changes: 8 additions & 1 deletion ext/oj/oj.c
Expand Up @@ -1673,13 +1673,20 @@ extern VALUE oj_optimize_rails(VALUE self);

/*
extern void oj_hash_test();
static VALUE
hash_test(VALUE self) {
oj_hash_test();
return Qnil;
}
*/
/*
extern void oj_hash_sizes();
static VALUE
hash_test(VALUE self) {
oj_hash_sizes();
return Qnil;
}
*/

static VALUE protect_require(VALUE x) {
rb_require("time");
Expand Down
15 changes: 11 additions & 4 deletions ext/oj/wab.c
Expand Up @@ -293,7 +293,7 @@ void oj_dump_wab_val(VALUE obj, int depth, Out out) {

///// load functions /////

static VALUE oj_hash_key(Val parent) {
static VALUE calc_hash_key(ParseInfo pi, Val parent) {
volatile VALUE rkey = parent->key_val;

if (Qundef != rkey) {
Expand All @@ -302,6 +302,13 @@ static VALUE oj_hash_key(Val parent) {

return rkey;
}
if (Yes != pi->options.cache_keys) {
rkey = rb_str_new(parent->key, parent->klen);
rkey = oj_encode(rkey);
rkey = rb_str_intern(rkey);

return rkey;
}
VALUE *slot;

if (Qnil == (rkey = oj_sym_hash_get(parent->key, parent->klen, &slot))) {
Expand Down Expand Up @@ -509,7 +516,7 @@ static VALUE start_hash(ParseInfo pi) {
static void hash_set_cstr(ParseInfo pi, Val parent, const char *str, size_t len, const char *orig) {
volatile VALUE rval = cstr_to_rstr(pi, str, len);

rb_hash_aset(stack_peek(&pi->stack)->val, oj_hash_key(parent), rval);
rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), rval);
if (Yes == pi->options.trace) {
oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
}
Expand All @@ -522,14 +529,14 @@ static void hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
}
rval = oj_num_as_value(ni);
rb_hash_aset(stack_peek(&pi->stack)->val, oj_hash_key(parent), rval);
rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), rval);
if (Yes == pi->options.trace) {
oj_trace_parse_call("set_number", pi, __FILE__, __LINE__, rval);
}
}

static void hash_set_value(ParseInfo pi, Val parent, VALUE value) {
rb_hash_aset(stack_peek(&pi->stack)->val, oj_hash_key(parent), value);
rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), value);
if (Yes == pi->options.trace) {
oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/oj/version.rb
@@ -1,5 +1,5 @@

module Oj
# Current version of the module.
VERSION = '3.12.0'
VERSION = '3.12.1'
end

0 comments on commit 3b110dc

Please sign in to comment.