8000 array.c: steel shared array's container when ARY_SHARED_NUM == 1 by funny-falcon · Pull Request #133 · ruby/ruby · GitHub
[go: up one dir, main page]

Skip to content

array.c: steel shared array's container when ARY_SHARED_NUM == 1 #133

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
array.c : make array really suitable for queue
when array is shared (which happens after Array#shift), and
ARY_SHARED_NUM == 1 (which is very often when array used as
queue), then make rb_ary_push push directly into shared array
  • Loading branch information
funny-falcon committed Sep 2, 2012
commit 9f43064d479ed0852ae1567464fdee1386b771e7
48 changes: 40 additions & 8 deletions array.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,38 @@ rb_ary_modify(VAL 8000 UE ary)
}
}

static void
ary_ensure_room_for_push(VALUE ary, long add_len)
{
long new_len = RARRAY_LEN(ary) + add_len;
long capa;

if (ARY_SHARED_P(ary)) {
if (new_len > RARRAY_EMBED_LEN_MAX) {
VALUE shared = ARY_SHARED(ary);
if (ARY_SHARED_NUM(shared) == 1) {
if (RARRAY_PTR(ary) - RARRAY_PTR(shared) + new_len <= RARRAY_LEN(shared)) {
rb_ary_modify_check(ary);
}
else {
/* if array is shared, than it is likely it participate in push/shift pattern */
rb_ary_modify(ary);
capa = ARY_CAPA(ary);
if (new_len > capa - (capa >> 6)) {
ary_double_capa(ary, new_len);
}
}
return;
}
}
}
rb_ary_modify(ary);
capa = ARY_CAPA(ary);
if (new_len > capa) {
ary_double_capa(ary, new_len);
}
}

/*
* call-seq:
* ary.freeze -> ary
Expand Down Expand Up @@ -740,8 +772,6 @@ ary_take_first_or_last(int argc, VALUE *argv, VALUE ary, enum ary_take_pos_flags
return ary_make_partial(ary, rb_cArray, offset, n);
}

static VALUE rb_ary_push_1(VALUE ary, VALUE item);

/*
* call-seq:
* ary << obj -> ary
Expand All @@ -758,8 +788,12 @@ static VALUE rb_ary_push_1(VALUE ary, VALUE item);
VALUE
rb_ary_push(VALUE ary, VALUE item)
{
rb_ary_modify(ary);
return rb_ary_push_1(ary, item);
long idx = RARRAY_LEN(ary);

ary_ensure_room_for_push(ary, 1);
RARRAY_PTR(ary)[idx] = item;
ARY_SET_LEN(ary, idx + 1);
return ary;
}

static VALUE
Expand All @@ -778,11 +812,9 @@ rb_ary_push_1(VALUE ary, VALUE item)
VALUE
rb_ary_cat(VALUE ary, const VALUE *ptr, long len)
{
long oldlen;
long oldlen = RARRAY_LEN(ary);

rb_ary_modify(ary);
oldlen = RARRAY_LEN(ary);
ary_resize_capa(ary, oldlen + len);
ary_ensure_room_for_push(ary, len);
MEMCPY(RARRAY_PTR(ary) + oldlen, ptr, VALUE, len);
ARY_SET_LEN(ary, oldlen + len);
return ary;
Expand Down
0