Skip to content

Commit

Permalink
New operator tp_asvector to speed up vector operations
Browse files Browse the repository at this point in the history
  • Loading branch information
GrieferAtWork committed Jun 2, 2024
1 parent e3e6cc0 commit 3c9f4cc
Show file tree
Hide file tree
Showing 15 changed files with 512 additions and 3 deletions.
26 changes: 26 additions & 0 deletions include/deemon/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -2111,6 +2111,23 @@ struct Dee_type_seq {
WUNUSED_T NONNULL_T((1, 2)) int (DCALL *tp_bounditem_string_len_hash)(DeeObject *self, char const *key, size_t keylen, Dee_hash_t hash);
WUNUSED_T NONNULL_T((1, 2)) int (DCALL *tp_hasitem_string_len_hash)(DeeObject *self, char const *key, size_t keylen, Dee_hash_t hash);

/* Optional helper to help implement `DeeSeq_AsHeapVector()' & friends.
* NOTES:
* - This operator is NOT used to implement stuff above, and will NOT
* be substituted using other operators. This operator gets inherited
* alongside "tp_iter", though its presence does not qualify for that
* operator being present!
* - This operator must NOT produce NULL-elements in "dst". The produced
* vector of items must be equivalent to what would be produced by a
* call to "tp_foreach" (which in turn must be equivalent to "tp_iter").
*
* @return: <= dst_length: Success: the first "return" elements of "dst" were filled with the items of this sequence.
* @return: > dst_length: The given "dst_length" is too short. In this case, "dst" may have been modified,
* but will not contain any object references. You must resize it until it is able
* to hold at least "return" elements, and call this operator again.
* @return: (size_t)-1: Error. */
WUNUSED_T NONNULL_T((1)) size_t (DCALL *tp_asvector)(DeeObject *self, /*out*/ DREF DeeObject **dst, size_t dst_length);

/* All of the following are *always* and *unconditionally* implemented
* when the associated type has the "tp_features & TF_KW" flag set,
* with the exception of `DeeKwds_Type', which has that flag, but does
Expand Down Expand Up @@ -2484,6 +2501,14 @@ myob_hasitem_string_len_hash(MyObject *self, char const *key, size_t keylen, Dee
return DeeError_NOTIMPLEMENTED();
}

PRIVATE WUNUSED NONNULL((1)) size_t DCALL
myob_asvector(MyObject *self, /*out*/ DREF DeeObject **dst, size_t dst_length) {
(void)self;
(void)dst;
(void)dst_length;
return (size_t)DeeError_NOTIMPLEMENTED();
}

PRIVATE struct type_seq myob_seq = {
/* .tp_iter = */ (DREF DeeObject *(DCALL *)(DeeObject *__restrict))&myob_iter,
/* .tp_sizeob = */ (DREF DeeObject *(DCALL *)(DeeObject *__restrict))&myob_sizeob,
Expand Down Expand Up @@ -2530,6 +2555,7 @@ PRIVATE struct type_seq myob_seq = {
/* .tp_setitem_string_len_hash = */ (int (DCALL *)(DeeObject *, char const *, size_t, Dee_hash_t, DeeObject *))&myob_setitem_string_len_hash,
/* .tp_bounditem_string_len_hash = */ (int (DCALL *)(DeeObject *, char const *, size_t, Dee_hash_t))&myob_bounditem_string_len_hash,
/* .tp_hasitem_string_len_hash = */ (int (DCALL *)(DeeObject *, char const *, size_t, Dee_hash_t))&myob_hasitem_string_len_hash,
/* .tp_asvector = */ (size_t (DCALL *)(DeeObject *, DREF DeeObject **, size_t))&myob_asvector,
/* .tp_getitemnr = */ (DeeObject *(DCALL *)(DeeObject *__restrict, /*string*/ DeeObject *__restrict))NULL,
/* .tp_getitemnr_string_hash = */ (DeeObject *(DCALL *)(DeeObject *__restrict, char const *__restrict, Dee_hash_t))NULL,
/* .tp_getitemnr_string_len_hash = */ (DeeObject *(DCALL *)(DeeObject *__restrict, char const *__restrict, size_t, Dee_hash_t))NULL,
Expand Down
24 changes: 24 additions & 0 deletions src/deemon/objects/bytes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1406,6 +1406,29 @@ bytes_foreach(Bytes *__restrict self, Dee_foreach_t proc, void *arg) {
return temp;
}

PRIVATE WUNUSED NONNULL((1)) size_t DCALL
bytes_asvector(Bytes *self, /*out*/ DREF DeeObject **dst, size_t dst_length) {
size_t size = DeeBytes_SIZE(self);
if likely(dst_length >= size) {
size_t i;
for (i = 0; i < size; ++i) {
DREF DeeObject *int_value;
byte_t value = DeeBytes_DATA(self)[i];
#ifdef DeeInt_8bit
int_value = (DREF DeeObject *)(DeeInt_8bit + value);
Dee_Incref(int_value);
#else /* DeeInt_8bit */
int_value = DeeInt_NewUInt8(value);
if unlikely(!int_value) {
Dee_Decrefv(dst, i);
return (size_t)-1;
}
#endif /* !DeeInt_8bit */
dst[i] = int_value; /* Inherit reference */
}
}
return size;
}

PRIVATE struct type_nsi tpconst bytes_nsi = {
/* .nsi_class = */ TYPE_SEQX_CLASS_SEQ,
Expand Down Expand Up @@ -1482,6 +1505,7 @@ PRIVATE struct type_seq bytes_seq = {
/* .tp_setitem_string_len_hash = */ NULL,
/* .tp_bounditem_string_len_hash = */ NULL,
/* .tp_hasitem_string_len_hash = */ NULL,
/* .tp_asvector = */ (size_t (DCALL *)(DeeObject *, DREF DeeObject **, size_t))&bytes_asvector,
};


Expand Down
1 change: 1 addition & 0 deletions src/deemon/objects/cached-dict.c
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,7 @@ PRIVATE struct type_seq cdict_seq = {
/* .tp_setitem_string_len_hash = */ NULL,
/* .tp_bounditem_string_len_hash = */ (int (DCALL *)(DeeObject *, char const *, size_t, Dee_hash_t))&cdict_bounditem_string_len_hash,
/* .tp_hasitem_string_len_hash = */ NULL,
/* .tp_asvector = */ NULL,
/* .tp_getitemnr = */ (DeeObject *(DCALL *)(DeeObject *__restrict, /*string*/ DeeObject *__restrict))&cdict_getitemnr,
/* .tp_getitemnr_string_hash = */ (DeeObject *(DCALL *)(DeeObject *__restrict, char const *__restrict, Dee_hash_t))&cdict_getitemnr_string_hash,
/* .tp_getitemnr_string_len_hash = */ (DeeObject *(DCALL *)(DeeObject *__restrict, char const *__restrict, size_t, Dee_hash_t))&cdict_getitemnr_string_len_hash,
Expand Down
21 changes: 21 additions & 0 deletions src/deemon/objects/hashset.c
Original file line number Diff line number Diff line change
Expand Up @@ -1847,6 +1847,26 @@ hashset_printrepr(HashSet *__restrict self,
return temp;
}

PRIVATE WUNUSED NONNULL((1)) size_t DCALL
hashset_asvector(HashSet *self, /*out*/ DREF DeeObject **dst, size_t dst_length) {
size_t result;
DeeHashSet_LockRead(self);
result = self->hs_used;
if likely(dst_length >= result) {
struct hashset_item *iter, *end;
end = (iter = self->hs_elem) + (self->hs_mask + 1);
for (; iter < end; ++iter) {
DeeObject *key = iter->hsi_key;
if (key == NULL || key == dummy)
continue;
Dee_Incref(key);
*dst++ = key;
}
}
DeeHashSet_LockEndRead(self);
return result;
}

PRIVATE struct type_nsi tpconst hashset_nsi = {
/* .nsi_class = */ TYPE_SEQX_CLASS_SET,
/* .nsi_flags = */ TYPE_SEQX_FMUTABLE | TYPE_SEQX_FRESIZABLE,
Expand Down Expand Up @@ -1903,6 +1923,7 @@ PRIVATE struct type_seq hashset_seq = {
/* .tp_setitem_string_len_hash = */ NULL,
/* .tp_bounditem_string_len_hash = */ NULL,
/* .tp_hasitem_string_len_hash = */ NULL,
/* .tp_asvector = */ (size_t (DCALL *)(DeeObject *, DREF DeeObject **, size_t))&hashset_asvector,
};

PRIVATE WUNUSED NONNULL((1)) int DCALL
Expand Down
11 changes: 11 additions & 0 deletions src/deemon/objects/list.c
Original file line number Diff line number Diff line change
Expand Up @@ -2105,6 +2105,16 @@ list_enumerate_index(List *self, Dee_enumerate_index_t proc,
return temp;
}

PRIVATE WUNUSED NONNULL((1)) size_t DCALL
list_asvector(List *self, /*out*/ DREF DeeObject **dst, size_t dst_length) {
size_t realsize;
DeeList_LockRead(self);
realsize = self->l_list.ol_elemc;
if likely(dst_length >= realsize)
Dee_Movrefv(dst, self->l_list.ol_elemv, realsize);
DeeList_LockEndRead(self);
return realsize;
}

PRIVATE struct type_nsi tpconst list_nsi = {
/* .nsi_class = */ TYPE_SEQX_CLASS_SEQ,
Expand Down Expand Up @@ -2173,6 +2183,7 @@ PRIVATE struct type_seq list_seq = {
/* .tp_setitem_string_len_hash = */ NULL,
/* .tp_bounditem_string_len_hash = */ NULL,
/* .tp_hasitem_string_len_hash = */ NULL,
/* .tp_asvector = */ (size_t (DCALL *)(DeeObject *, DREF DeeObject **, size_t))&list_asvector,
};

PRIVATE WUNUSED NONNULL((1, 2)) int DCALL
Expand Down
1 change: 1 addition & 0 deletions src/deemon/objects/rodict.c
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,7 @@ PRIVATE struct type_seq rodict_seq = {
/* .tp_setitem_string_len_hash = */ NULL,
/* .tp_bounditem_string_len_hash = */ NULL,
/* .tp_hasitem_string_len_hash = */ (int (DCALL *)(DeeObject *, char const *, size_t, Dee_hash_t))&rodict_hasitem_string_len_hash,
/* .tp_asvector = */ NULL,
/* .tp_getitemnr = */ (DeeObject *(DCALL *)(DeeObject *__restrict, /*string*/ DeeObject *__restrict))&rodict_getitemnr,
/* .tp_getitemnr_string_hash = */ (DeeObject *(DCALL *)(DeeObject *__restrict, char const *__restrict, Dee_hash_t))&rodict_getitemnr_string_hash,
/* .tp_getitemnr_string_len_hash = */ (DeeObject *(DCALL *)(DeeObject *__restrict, char const *__restrict, size_t, Dee_hash_t))&rodict_getitemnr_string_len_hash,
Expand Down
17 changes: 17 additions & 0 deletions src/deemon/objects/roset.c
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,22 @@ roset_foreach(RoSet *self, Dee_foreach_t proc, void *arg) {
return temp;
}

PRIVATE WUNUSED NONNULL((1)) size_t DCALL
roset_asvector(RoSet *self, /*out*/ DREF DeeObject **dst, size_t dst_length) {
if likely(dst_length >= self->rs_size) {
struct roset_item *iter, *end;
end = (iter = self->rs_elem) + (self->rs_mask + 1);
for (; iter < end; ++iter) {
DeeObject *key = iter->rsi_key;
if (key == NULL)
continue;
Dee_Incref(key);
*dst++ = key;
}
}
return self->rs_size;
}

PRIVATE struct type_seq roset_seq = {
/* .tp_iter = */ (DREF DeeObject *(DCALL *)(DeeObject *__restrict))&roset_iter,
/* .tp_sizeob = */ NULL,
Expand Down Expand Up @@ -547,6 +563,7 @@ PRIVATE struct type_seq roset_seq = {
/* .tp_setitem_string_len_hash = */ NULL,
/* .tp_bounditem_string_len_hash = */ NULL,
/* .tp_hasitem_string_len_hash = */ NULL,
/* .tp_asvector = */ (size_t (DCALL *)(DeeObject *, DREF DeeObject **, size_t))&roset_asvector,
};

PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL
Expand Down
Loading

0 comments on commit 3c9f4cc

Please sign in to comment.