Skip to content

Commit

Permalink
midipp: Resolve sort function.
Browse files Browse the repository at this point in the history
  • Loading branch information
hselasky committed Jan 22, 2017
1 parent 5ee1060 commit 97bcdcf
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 12 deletions.
85 changes: 85 additions & 0 deletions midipp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,91 @@ MppWriteRawFile(const QString &fname, QByteArray *pdata)
return (1);
}

static size_t
MppSortIndex(size_t t)
{
t ^= t >> 1;
t ^= t >> 2;
t ^= t >> 4;
t ^= t >> 8;
t ^= t >> 16;
if (sizeof(t) >= 8)
t ^= t >> 32;
return (t);
}

static int
MppSortXform(void **ptr, size_t n, size_t lim, MppCmp_t *fn, void *arg)
{
#define MPP_XSORT_TABLE_MAX (1 << 4)
size_t x, y, z;
unsigned t, u, v;
size_t p[MPP_XSORT_TABLE_MAX];
int retval = 0;

x = n;
while (1) {
/* optimise */
if (x >= MPP_XSORT_TABLE_MAX)
v = MPP_XSORT_TABLE_MAX;
else if (x >= 2)
v = x;
else
break;

/* divide down */
x /= v;

/* generate ramp table */
for (t = 0; t != v; t++)
p[t] = MppSortIndex(x * (t ^ (t / 2)));

/* bitonic sort */
for (y = 0; y != n; y += (v * x)) {
for (z = 0; z != x; z++) {
size_t w = y + z;

/* insertion sort */
for (t = 1; t != v; t++) {
/* check for arrays which are not power of two */
if ((w ^ p[t]) >= lim)
break;
for (u = t; u != 0; u--) {
void **pa = ptr + (w ^ p[u - 1]);
void **pb = ptr + (w ^ p[u]);

if (fn(arg, pa, pb) > 0) {
void *temp;
temp = *pa;
*pa = *pb;
*pb = temp;
retval = 1;
} else {
break;
}
}
}
}
}
}
return (retval);
}

Q_DECL_EXPORT void
MppSort(void **ptr, size_t n, MppCmp_t *fn, void *arg)
{
size_t max;

if (n <= 1)
return;

for (max = 1; max < n; max <<= 1)
;

while (MppSortXform(ptr, max, n, fn, arg))
;
}

#ifdef HAVE_SCREENSHOT
Q_DECL_EXPORT void
MppScreenShot(QWidget *widget, QApplication &app)
Expand Down
3 changes: 3 additions & 0 deletions midipp.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,9 @@ extern const QString MppChordModChars;
extern const QString MppVersion;
extern const QString MppIconFile;

typedef int (MppCmp_t)(void *, const void *, const void *);
extern void MppSort(void **, size_t, MppCmp_t *, void *);

#ifdef HAVE_SCREENSHOT
extern void MppScreenShot(QWidget *, QApplication &);
#endif
Expand Down
14 changes: 2 additions & 12 deletions midipp_database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,8 @@ tar_match(void *arg, const char *str)
return (1);
}

#ifdef __linux__
static int
tar_compare_r(const void *_pa, const void *_pb, void *arg)
#else
static int
tar_compare_r(void *arg, const void *_pa, const void *_pb)
#endif
{
const union record *const *pa = (const union record *const *)_pa;
const union record *const *pb = (const union record *const *)_pb;
Expand Down Expand Up @@ -341,13 +336,8 @@ MppDataBase :: update_list_view()
}

if (record_count != 0) {
#ifdef __linux__
qsort_r(record_ptr, record_count, sizeof(void *),
&tar_compare_r, &filter);
#else
qsort_r(record_ptr, record_count, sizeof(void *),
&filter, &tar_compare_r);
#endif
MppSort((void **)record_ptr, record_count,
&tar_compare_r, (void *)&filter);
}

result->clear();
Expand Down

0 comments on commit 97bcdcf

Please sign in to comment.