Adds a new helper file for raid_sort and raid_insert.

This commit is contained in:
Andrea Mazzoleni 2014-01-10 09:02:12 +01:00
parent 19044d7565
commit 554055e53d
8 changed files with 294 additions and 14 deletions

View file

@ -10,7 +10,7 @@ snapraid_SOURCES = \
raid/x86.c \
raid/intz.c \
raid/x86z.c \
raid/sort.c \
raid/helper.c \
raid/memory.c \
raid/test.c \
raid/tag.c \
@ -43,6 +43,7 @@ mktables_SOURCES = \
noinst_HEADERS = \
raid/raid.h \
raid/helper.h \
raid/internal.h \
raid/cpu.h \
raid/gf.h \

93
raid/helper.c Normal file
View file

@ -0,0 +1,93 @@
/*
* Copyright (C) 2013 Andrea Mazzoleni
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "internal.h"
#define RAID_SWAP(a, b) \
do { \
if (v[a] > v[b]) { \
int t = v[a]; \
v[a] = v[b]; \
v[b] = t; \
} \
} while (0)
void raid_sort(int n, int *v)
{
/* sorting networks generated with Batcher's Merge-Exchange */
switch (n) {
case 2:
RAID_SWAP(0, 1);
break;
case 3:
RAID_SWAP(0, 2);
RAID_SWAP(0, 1);
RAID_SWAP(1, 2);
break;
case 4:
RAID_SWAP(0, 2);
RAID_SWAP(1, 3);
RAID_SWAP(0, 1);
RAID_SWAP(2, 3);
RAID_SWAP(1, 2);
break;
case 5:
RAID_SWAP(0, 4);
RAID_SWAP(0, 2);
RAID_SWAP(1, 3);
RAID_SWAP(2, 4);
RAID_SWAP(0, 1);
RAID_SWAP(2, 3);
RAID_SWAP(1, 4);
RAID_SWAP(1, 2);
RAID_SWAP(3, 4);
break;
case 6:
RAID_SWAP(0, 4);
RAID_SWAP(1, 5);
RAID_SWAP(0, 2);
RAID_SWAP(1, 3);
RAID_SWAP(2, 4);
RAID_SWAP(3, 5);
RAID_SWAP(0, 1);
RAID_SWAP(2, 3);
RAID_SWAP(4, 5);
RAID_SWAP(1, 4);
RAID_SWAP(1, 2);
RAID_SWAP(3, 4);
break;
}
}
void raid_insert(int n, int *v, int i)
{
/* we don't use binary search because this is intended */
/* for very small vectors and we want to optimize the case */
/* of elements inserted already in order */
/* insert at the end */
v[n] = i;
/* swap until in the correct position */
while (n > 0 && v[n-1] > v[n]) {
/* swap */
int t = v[n-1];
v[n-1] = v[n];
v[n] = t;
/* previous position */
--n;
}
}

43
raid/helper.h Normal file
View file

@ -0,0 +1,43 @@
/*
* Copyright (C) 2013 Andrea Mazzoleni
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __RAID_HELPER_H
#define __RAID_HELPER_H
/**
* Inserts an integer in a sorted vector.
*
* This function can be used to insert indexes in order, ready to be used for
* calling raid_rec().
*
* @n Number of integers currently in the vector.
* @v Vector of integers already sorted.
* It must have extra space for the new elemet at the end.
* @i Value to insert.
*/
void raid_insert(int n, int *v, int i);
/**
* Sorts a small vector of integers.
*
* If you have indexes not in order, you can use this function to sort them
* before calling raid_rec().
*
* @n Number of integers. No more than RAID_PARITY_MAX.
* @v Vector of integers.
*/
void raid_sort(int n, int *v);
#endif

View file

@ -22,7 +22,7 @@
#define BUG_ON(a) assert(!(a))
/*
* Includes the main header.
* Includes the headers.
*/
#include "raid.h"

View file

@ -158,16 +158,5 @@ void raid_rec(int nr, int *ir, int nd, int np, size_t size, void **v);
*/
void raid_rec_dataonly(int nr, int *id, int *ip, int nd, size_t size, void **v);
/**
* Sorts a small vector of integers.
*
* If you have block indexes not in order, you can use this function to sort
* them before calling raid_rec().
*
* @n Number of integers. No more than RAID_PARITY_MAX.
* @v Vector of integers.
*/
void raid_sort(int n, int *v);
#endif

119
raid/tag.c Normal file
View file

@ -0,0 +1,119 @@
/*
* Copyright (C) 2013 Andrea Mazzoleni
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "internal.h"
static struct raid_func {
const char *name;
void *p;
} RAID_FUNC[] = {
{ "int8", raid_gen3_int8 },
{ "int8", raid_gen4_int8 },
{ "int8", raid_gen5_int8 },
{ "int8", raid_gen6_int8 },
{ "int32", raid_gen1_int32 },
{ "int64", raid_gen1_int64 },
{ "int32", raid_gen2_int32 },
{ "int64", raid_gen2_int64 },
{ "int32", raid_genz_int32 },
{ "int64", raid_genz_int64 },
{ "int8", raid_rec1_int8 },
{ "int8", raid_rec2_int8 },
{ "int8", raid_recX_int8 },
#ifdef CONFIG_X86
{ "sse2", raid_gen1_sse2 },
{ "sse2", raid_gen2_sse2 },
{ "sse2", raid_genz_sse2 },
{ "ssse3", raid_gen3_ssse3 },
{ "ssse3", raid_gen4_ssse3 },
{ "ssse3", raid_gen5_ssse3 },
{ "ssse3", raid_gen6_ssse3 },
{ "ssse3", raid_rec1_ssse3 },
{ "ssse3", raid_rec2_ssse3 },
{ "ssse3", raid_recX_ssse3 },
#endif
#ifdef CONFIG_X86_64
{ "sse2e", raid_gen2_sse2ext },
{ "sse2e", raid_genz_sse2ext },
{ "ssse3e", raid_gen3_ssse3ext },
{ "ssse3e", raid_gen4_ssse3ext },
{ "ssse3e", raid_gen5_ssse3ext },
{ "ssse3e", raid_gen6_ssse3ext },
#endif
{ 0, 0 }
};
static const char *raid_tag(void *func)
{
struct raid_func *i = RAID_FUNC;
while (i->name != 0) {
if (i->p == func)
return i->name;
++i;
}
return "unknown";
}
const char *raid_gen1_tag(void)
{
return raid_tag(raid_gen_ptr[0]);
}
const char *raid_gen2_tag(void)
{
return raid_tag(raid_gen_ptr[1]);
}
const char *raid_genz_tag(void)
{
return raid_tag(raid_genz_ptr);
}
const char *raid_gen3_tag(void)
{
return raid_tag(raid_gen_ptr[2]);
}
const char *raid_gen4_tag(void)
{
return raid_tag(raid_gen_ptr[3]);
}
const char *raid_gen5_tag(void)
{
return raid_tag(raid_gen_ptr[4]);
}
const char *raid_gen6_tag(void)
{
return raid_tag(raid_gen_ptr[5]);
}
const char *raid_rec1_tag(void)
{
return raid_tag(raid_rec_ptr[0]);
}
const char *raid_rec2_tag(void)
{
return raid_tag(raid_rec_ptr[1]);
}
const char *raid_recX_tag(void)
{
return raid_tag(raid_rec_ptr[2]);
}

View file

@ -13,6 +13,7 @@
*/
#include "internal.h"
#include "helper.h"
#include "cpu.h"
#include "combo.h"
#include "memory.h"
@ -76,6 +77,31 @@ int raid_test_combo(void)
return 0;
}
int raid_test_insert(void)
{
int p[RAID_PARITY_MAX];
int r;
for (r = 1; r <= RAID_PARITY_MAX; ++r) {
permutation_first(r, RAID_PARITY_MAX, p);
do {
int i[RAID_PARITY_MAX];
int j;
/* insert in order */
for (j = 0; j < r; ++j)
raid_insert(j, i, p[j]);
/* check order */
for (j = 1; j < r; ++j)
if (i[j-1] > i[j])
return -1;
} while (permutation_next(r, RAID_PARITY_MAX, p));
}
return 0;
}
int raid_test_sort(void)
{
int p[RAID_PARITY_MAX];

View file

@ -16,7 +16,16 @@
#define __RAID_TEST_H
/**
* Tests sorting functions.
* Tests insertion function.
*
* Test raid_insert() with all the possible combinations of elements to insert.
*
* Returns 0 on success.
*/
int raid_test_insert(void);
/**
* Tests sorting function.
*
* Test raid_sort() with all the possible combinations of elements to sort.
*