Permalink
Browse files

re-use ruby strings in sorted array

  • Loading branch information...
1 parent 35e1a57 commit e633f5358636007c6f7caa2d18e8603672cfc30b @tmm1 tmm1 committed Nov 14, 2012
@@ -26,18 +26,20 @@ rb_sort(VALUE obj, VALUE list)
long len = RARRAY_LEN(list);
long i;
char **c_list = calloc(len, sizeof(char *));
+ int *ordering;
VALUE rb_str, dest;
for (i = 0; i < len; i++) {
rb_str = rb_ary_entry(list, i);
c_list[i] = StringValuePtr(rb_str);
}
- version_sorter_sort(c_list, len);
+ ordering = version_sorter_sort(c_list, len);
dest = rb_ary_new2(len);
for (i = 0; i < len; i++) {
- rb_ary_store(dest, i, rb_str_new2(c_list[i]));
+ rb_ary_store(dest, i, rb_ary_entry(list, ordering[i]));
}
+ free(ordering);
return dest;
}
@@ -14,7 +14,7 @@
#include "version_sorter.h"
-static VersionSortingItem * version_sorting_item_init(const char *);
+static VersionSortingItem * version_sorting_item_init(const char *, int);
static void version_sorting_item_free(VersionSortingItem *);
static void version_sorting_item_add_piece(VersionSortingItem *, char *);
static void parse_version_word(VersionSortingItem *);
@@ -24,7 +24,7 @@ static enum scan_state scan_state_get(const char);
VersionSortingItem *
-version_sorting_item_init(const char *original)
+version_sorting_item_init(const char *original, int idx)
{
VersionSortingItem *vsi = malloc(sizeof(VersionSortingItem));
if (vsi == NULL) {
@@ -36,6 +36,7 @@ version_sorting_item_init(const char *original)
vsi->widest_len = 0;
vsi->original = original;
vsi->original_len = strlen(original);
+ vsi->original_idx = idx;
vsi->normalized = NULL;
parse_version_word(vsi);
@@ -178,15 +179,16 @@ compare_by_version(const void *a, const void *b)
return strcmp((*(const VersionSortingItem **)a)->normalized, (*(const VersionSortingItem **)b)->normalized);
}
-void
+int*
version_sorter_sort(char **list, size_t list_len)
{
int i, widest_len = 0;
VersionSortingItem *vsi;
VersionSortingItem **sorting_list = calloc(list_len, sizeof(VersionSortingItem *));
+ int *ordering = calloc(list_len, sizeof(int));
for (i = 0; i < list_len; i++) {
- vsi = version_sorting_item_init(list[i]);
+ vsi = version_sorting_item_init(list[i], i);
if (vsi->widest_len > widest_len) {
widest_len = vsi->widest_len;
}
@@ -202,8 +204,10 @@ version_sorter_sort(char **list, size_t list_len)
for (i = 0; i < list_len; i++) {
vsi = sorting_list[i];
list[i] = (char *) vsi->original;
+ ordering[i] = vsi->original_idx;
version_sorting_item_free(vsi);
}
free(sorting_list);
+ return ordering;
}
@@ -43,6 +43,7 @@ typedef struct _VersionSortingItem {
char *normalized;
const char *original;
size_t original_len;
+ int original_idx;
} VersionSortingItem;
typedef struct _VersionPiece {
@@ -55,6 +56,6 @@ enum scan_state {
digit, alpha, other
};
-extern void version_sorter_sort(char **, size_t);
+extern int* version_sorter_sort(char **, size_t);
#endif /* _VERSION_SORTER_H */
@@ -12,6 +12,13 @@ def test_sorts_verisons_correctly
assert_equal sorted_versions, sort(versions)
end
+ def test_returns_same_object
+ versions = %w( 2.0 1.0 0.5 )
+ sorted = sort(versions)
+
+ assert_equal versions[2].object_id, sorted[0].object_id
+ end
+
def test_reverse_sorts_verisons_correctly
versions = %w(1.0.9 1.0.10 2.0 3.1.4.2 1.0.9a)
sorted_versions = %w( 3.1.4.2 2.0 1.0.10 1.0.9a 1.0.9 )

0 comments on commit e633f53

Please sign in to comment.