From b7a8858233b46d67734987b7075d28aa7af9e62d Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Sat, 28 Dec 2013 17:07:00 +0100 Subject: [PATCH] Adds a new sort functions for RAID. --- Makefile.am | 1 + raid/raid.h | 29 ++++++++++++++------- raid/sort.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 9 deletions(-) create mode 100644 raid/sort.c diff --git a/Makefile.am b/Makefile.am index e5adddf0..336ec460 100644 --- a/Makefile.am +++ b/Makefile.am @@ -10,6 +10,7 @@ snapraid_SOURCES = \ raid/x86.c \ raid/intz.c \ raid/x86z.c \ + raid/sort.c \ snapraid.c \ tommy.c \ util.c \ diff --git a/raid/raid.h b/raid/raid.h index 35ba9118..227889e1 100644 --- a/raid/raid.h +++ b/raid/raid.h @@ -83,13 +83,13 @@ void raid_waste(void *zero); * * \param nd Number of data disks. * \param np Number of parities to compute. - * \param size Size of the blocks pointed by vv. It must be a multipler of 64. - * \param vv Vector of pointers to the blocks for disks and parities. + * \param size Size of the blocks pointed by ::v. It must be a multipler of 64. + * \param v Vector of pointers to the blocks for disks and parities. * It has (::nd + ::np) elements. The first elements are the blocks for * data, following with the parity blocks. * Each blocks has ::size bytes. */ -void raid_par(int nd, int np, size_t size, void **vv); +void raid_par(int nd, int np, size_t size, void **v); /** * Recovers failures of data and parity blocks. @@ -112,13 +112,13 @@ void raid_par(int nd, int np, size_t size, void **vv); * not recomputed. * \param nd Number of data disks. * \param np Number of parity disks. - * \param size Size of the blocks pointed by vv. It must be a multipler of 64. - * \param vv Vector of pointers to the blocks for disks and parities. + * \param size Size of the blocks pointed by ::v. It must be a multipler of 64. + * \param v Vector of pointers to the blocks for disks and parities. * It has (::nd + ::np) elements. The first elements are the blocks * for data, following with the parity blocks. * Each blocks has ::size bytes. */ -void raid_rec(int nrd, const int *id, int nrp, int *ip, int nd, int np, size_t size, void **vv); +void raid_rec(int nrd, const int *id, int nrp, int *ip, int nd, int np, size_t size, void **v); /** * Recovers failures of data blocks using the specified parities. @@ -135,13 +135,24 @@ void raid_rec(int nrd, const int *id, int nrp, int *ip, int nd, int np, size_t s * \param ip[] Vector of ::nr indexes of the parity disks to use for recovering. * The indexes start from 0. They must be in order. * \param nd Number of data disks. - * \param size Size of the blocks pointed by vv. It must be a multipler of 64. - * \param vv Vector of pointers to the blocks for disks and parities. + * \param size Size of the blocks pointed by ::v. It must be a multipler of 64. + * \param v Vector of pointers to the blocks for disks and parities. * It has (::nd + ::ip[::nr - 1] + 1) elements. The first elements are the * blocks for data, following with the parity blocks. * Each blocks has ::size bytes. */ -void raid_rec_dataonly(int nr, const int *id, const int *ip, int nd, size_t size, void **vv); +void raid_rec_dataonly(int nr, const int *id, const 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 callign raid_rec(). + * + * \param n Number of integers. No more than RAID_PARITY_MAX. + * \paran v Vector of integers. + */ +void raid_sort(int n, int* v); #endif diff --git a/raid/sort.c b/raid/sort.c new file mode 100644 index 00000000..226789ae --- /dev/null +++ b/raid/sort.c @@ -0,0 +1,75 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#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 the Batcher's Merge-Exchange algorithm */ + 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; + } +} +