New upstream version 8.1.0
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
#include <common/toolkit/MathTk.h>
|
||||
#include "BuddyMirrorPattern.h"
|
||||
|
||||
bool BuddyMirrorPattern_deserializePattern(StripePattern* this, DeserializeCtx* ctx)
|
||||
{
|
||||
BuddyMirrorPattern* thisCast = (BuddyMirrorPattern*)this;
|
||||
|
||||
RawList mirrorBuddyGroupIDsVec;
|
||||
|
||||
// defaultNumTargets
|
||||
if(!Serialization_deserializeUInt(ctx, &thisCast->defaultNumTargets) )
|
||||
return false;
|
||||
|
||||
// mirrorBuddyGroupIDs
|
||||
if(!Serialization_deserializeUInt16VecPreprocess(ctx, &mirrorBuddyGroupIDsVec) )
|
||||
return false;
|
||||
|
||||
if(!Serialization_deserializeUInt16Vec(&mirrorBuddyGroupIDsVec, &thisCast->mirrorBuddyGroupIDs) )
|
||||
return false;
|
||||
|
||||
// check mirrorBuddyGroupIDs
|
||||
if(!UInt16Vec_length(&thisCast->mirrorBuddyGroupIDs) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t BuddyMirrorPattern_getStripeTargetIndex(StripePattern* this, int64_t pos)
|
||||
{
|
||||
struct BuddyMirrorPattern* p = container_of(this, struct BuddyMirrorPattern, stripePattern);
|
||||
|
||||
return (pos / this->chunkSize) % UInt16Vec_length(&p->mirrorBuddyGroupIDs);
|
||||
}
|
||||
|
||||
uint16_t BuddyMirrorPattern_getStripeTargetID(StripePattern* this, int64_t pos)
|
||||
{
|
||||
BuddyMirrorPattern* thisCast = (BuddyMirrorPattern*)this;
|
||||
|
||||
size_t targetIndex = BuddyMirrorPattern_getStripeTargetIndex(this, pos);
|
||||
|
||||
return UInt16Vec_at(&thisCast->mirrorBuddyGroupIDs, targetIndex);
|
||||
}
|
||||
|
||||
void BuddyMirrorPattern_getStripeTargetIDsCopy(StripePattern* this, UInt16Vec* outTargetIDs)
|
||||
{
|
||||
BuddyMirrorPattern* thisCast = (BuddyMirrorPattern*)this;
|
||||
|
||||
ListTk_copyUInt16ListToVec( (UInt16List*)&thisCast->mirrorBuddyGroupIDs, outTargetIDs);
|
||||
}
|
||||
|
||||
UInt16Vec* BuddyMirrorPattern_getStripeTargetIDs(StripePattern* this)
|
||||
{
|
||||
BuddyMirrorPattern* thisCast = (BuddyMirrorPattern*)this;
|
||||
|
||||
return &thisCast->mirrorBuddyGroupIDs;
|
||||
}
|
||||
|
||||
unsigned BuddyMirrorPattern_getMinNumTargets(StripePattern* this)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned BuddyMirrorPattern_getDefaultNumTargets(StripePattern* this)
|
||||
{
|
||||
BuddyMirrorPattern* thisCast = (BuddyMirrorPattern*)this;
|
||||
|
||||
return thisCast->defaultNumTargets;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
#ifndef BUDDYMIRRORPATTERN_H_
|
||||
#define BUDDYMIRRORPATTERN_H_
|
||||
|
||||
#include <common/toolkit/Serialization.h>
|
||||
#include "StripePattern.h"
|
||||
|
||||
struct BuddyMirrorPattern;
|
||||
typedef struct BuddyMirrorPattern BuddyMirrorPattern;
|
||||
|
||||
|
||||
static inline void BuddyMirrorPattern_init(BuddyMirrorPattern* this,
|
||||
unsigned chunkSize, UInt16Vec* mirrorBuddyGroupIDs, unsigned defaultNumTargets);
|
||||
static inline void BuddyMirrorPattern_initFromChunkSize(BuddyMirrorPattern* this,
|
||||
unsigned chunkSize);
|
||||
static inline BuddyMirrorPattern* BuddyMirrorPattern_construct(
|
||||
unsigned chunkSize, UInt16Vec* mirrorBuddyGroupIDs, unsigned defaultNumTargets);
|
||||
static inline BuddyMirrorPattern* BuddyMirrorPattern_constructFromChunkSize(unsigned chunkSize);
|
||||
static inline void BuddyMirrorPattern_uninit(StripePattern* this);
|
||||
|
||||
static inline void __BuddyMirrorPattern_assignVirtualFunctions(BuddyMirrorPattern* this);
|
||||
|
||||
// virtual functions
|
||||
extern bool BuddyMirrorPattern_deserializePattern(StripePattern* this, DeserializeCtx* ctx);
|
||||
|
||||
extern size_t BuddyMirrorPattern_getStripeTargetIndex(StripePattern* this, int64_t pos);
|
||||
extern uint16_t BuddyMirrorPattern_getStripeTargetID(StripePattern* this, int64_t pos);
|
||||
extern void BuddyMirrorPattern_getStripeTargetIDsCopy(StripePattern* this, UInt16Vec* outTargetIDs);
|
||||
extern UInt16Vec* BuddyMirrorPattern_getStripeTargetIDs(StripePattern* this);
|
||||
extern unsigned BuddyMirrorPattern_getMinNumTargets(StripePattern* this);
|
||||
extern unsigned BuddyMirrorPattern_getDefaultNumTargets(StripePattern* this);
|
||||
|
||||
|
||||
|
||||
struct BuddyMirrorPattern
|
||||
{
|
||||
StripePattern stripePattern;
|
||||
|
||||
UInt16Vec mirrorBuddyGroupIDs;
|
||||
unsigned defaultNumTargets;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param mirrorBuddyGroupIDs will be copied
|
||||
* @param defaultNumTargets default number of targets (0 for app-level default)
|
||||
*/
|
||||
void BuddyMirrorPattern_init(BuddyMirrorPattern* this,
|
||||
unsigned chunkSize, UInt16Vec* mirrorBuddyGroupIDs, unsigned defaultNumTargets)
|
||||
{
|
||||
StripePattern_initFromPatternType( (StripePattern*)this, STRIPEPATTERN_BuddyMirror, chunkSize);
|
||||
|
||||
// assign virtual functions
|
||||
__BuddyMirrorPattern_assignVirtualFunctions(this);
|
||||
|
||||
// init attribs
|
||||
UInt16Vec_init(&this->mirrorBuddyGroupIDs);
|
||||
|
||||
ListTk_copyUInt16ListToVec( (UInt16List*)mirrorBuddyGroupIDs, &this->mirrorBuddyGroupIDs);
|
||||
|
||||
this->defaultNumTargets = defaultNumTargets ? defaultNumTargets : 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: for deserialization only
|
||||
*/
|
||||
void BuddyMirrorPattern_initFromChunkSize(BuddyMirrorPattern* this, unsigned chunkSize)
|
||||
{
|
||||
StripePattern_initFromPatternType( (StripePattern*)this, STRIPEPATTERN_BuddyMirror, chunkSize);
|
||||
|
||||
// assign virtual functions
|
||||
__BuddyMirrorPattern_assignVirtualFunctions(this);
|
||||
|
||||
// init attribs
|
||||
UInt16Vec_init(&this->mirrorBuddyGroupIDs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mirrorBuddyGroupIDs will be copied
|
||||
* @param defaultNumTargets default number of targets (0 for app-level default)
|
||||
*/
|
||||
BuddyMirrorPattern* BuddyMirrorPattern_construct(
|
||||
unsigned chunkSize, UInt16Vec* mirrorBuddyGroupIDs, unsigned defaultNumTargets)
|
||||
{
|
||||
struct BuddyMirrorPattern* this = os_kmalloc(sizeof(*this) );
|
||||
|
||||
BuddyMirrorPattern_init(this, chunkSize, mirrorBuddyGroupIDs, defaultNumTargets);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: for deserialization only
|
||||
*/
|
||||
BuddyMirrorPattern* BuddyMirrorPattern_constructFromChunkSize(unsigned chunkSize)
|
||||
{
|
||||
struct BuddyMirrorPattern* this = os_kmalloc(sizeof(*this) );
|
||||
|
||||
BuddyMirrorPattern_initFromChunkSize(this, chunkSize);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void BuddyMirrorPattern_uninit(StripePattern* this)
|
||||
{
|
||||
BuddyMirrorPattern* thisCast = (BuddyMirrorPattern*)this;
|
||||
|
||||
UInt16Vec_uninit(&thisCast->mirrorBuddyGroupIDs);
|
||||
}
|
||||
|
||||
void __BuddyMirrorPattern_assignVirtualFunctions(BuddyMirrorPattern* this)
|
||||
{
|
||||
( (StripePattern*)this)->uninit = BuddyMirrorPattern_uninit;
|
||||
|
||||
( (StripePattern*)this)->deserializePattern = BuddyMirrorPattern_deserializePattern;
|
||||
|
||||
( (StripePattern*)this)->getStripeTargetIndex = BuddyMirrorPattern_getStripeTargetIndex;
|
||||
( (StripePattern*)this)->getStripeTargetID = BuddyMirrorPattern_getStripeTargetID;
|
||||
( (StripePattern*)this)->getStripeTargetIDsCopy = BuddyMirrorPattern_getStripeTargetIDsCopy;
|
||||
( (StripePattern*)this)->getStripeTargetIDs = BuddyMirrorPattern_getStripeTargetIDs;
|
||||
( (StripePattern*)this)->getMinNumTargets = BuddyMirrorPattern_getMinNumTargets;
|
||||
( (StripePattern*)this)->getDefaultNumTargets = BuddyMirrorPattern_getDefaultNumTargets;
|
||||
}
|
||||
|
||||
#endif /*BUDDYMIRRORPATTERN_H_*/
|
||||
70
client_module/source/common/storage/striping/Raid0Pattern.c
Normal file
70
client_module/source/common/storage/striping/Raid0Pattern.c
Normal file
@@ -0,0 +1,70 @@
|
||||
#include <common/toolkit/MathTk.h>
|
||||
#include "Raid0Pattern.h"
|
||||
|
||||
bool Raid0Pattern_deserializePattern(StripePattern* this, DeserializeCtx* ctx)
|
||||
{
|
||||
Raid0Pattern* thisCast = (Raid0Pattern*)this;
|
||||
|
||||
RawList targetIDsList;
|
||||
|
||||
// defaultNumTargets
|
||||
if(!Serialization_deserializeUInt(ctx, &thisCast->defaultNumTargets) )
|
||||
return false;
|
||||
|
||||
// targetIDs
|
||||
if(!Serialization_deserializeUInt16VecPreprocess(ctx, &targetIDsList) )
|
||||
return false;
|
||||
|
||||
if(!Serialization_deserializeUInt16Vec(&targetIDsList, &thisCast->stripeTargetIDs) )
|
||||
return false;
|
||||
|
||||
// check targetIDs
|
||||
if(!UInt16Vec_length(&thisCast->stripeTargetIDs) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t Raid0Pattern_getStripeTargetIndex(StripePattern* this, int64_t pos)
|
||||
{
|
||||
struct Raid0Pattern* p = container_of(this, struct Raid0Pattern, stripePattern);
|
||||
|
||||
return (pos / this->chunkSize) % UInt16Vec_length(&p->stripeTargetIDs);
|
||||
}
|
||||
|
||||
uint16_t Raid0Pattern_getStripeTargetID(StripePattern* this, int64_t pos)
|
||||
{
|
||||
Raid0Pattern* thisCast = (Raid0Pattern*)this;
|
||||
|
||||
size_t targetIndex = Raid0Pattern_getStripeTargetIndex(this, pos);
|
||||
|
||||
return UInt16Vec_at(&thisCast->stripeTargetIDs, targetIndex);
|
||||
}
|
||||
|
||||
void Raid0Pattern_getStripeTargetIDsCopy(StripePattern* this, UInt16Vec* outTargetIDs)
|
||||
{
|
||||
Raid0Pattern* thisCast = (Raid0Pattern*)this;
|
||||
|
||||
ListTk_copyUInt16ListToVec( (UInt16List*)&thisCast->stripeTargetIDs, outTargetIDs);
|
||||
}
|
||||
|
||||
UInt16Vec* Raid0Pattern_getStripeTargetIDs(StripePattern* this)
|
||||
{
|
||||
Raid0Pattern* thisCast = (Raid0Pattern*)this;
|
||||
|
||||
return &thisCast->stripeTargetIDs;
|
||||
}
|
||||
|
||||
unsigned Raid0Pattern_getMinNumTargets(StripePattern* this)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned Raid0Pattern_getDefaultNumTargets(StripePattern* this)
|
||||
{
|
||||
Raid0Pattern* thisCast = (Raid0Pattern*)this;
|
||||
|
||||
return thisCast->defaultNumTargets;
|
||||
}
|
||||
|
||||
|
||||
124
client_module/source/common/storage/striping/Raid0Pattern.h
Normal file
124
client_module/source/common/storage/striping/Raid0Pattern.h
Normal file
@@ -0,0 +1,124 @@
|
||||
#ifndef RAID0PATTERN_H_
|
||||
#define RAID0PATTERN_H_
|
||||
|
||||
#include <common/toolkit/Serialization.h>
|
||||
#include "StripePattern.h"
|
||||
|
||||
struct Raid0Pattern;
|
||||
typedef struct Raid0Pattern Raid0Pattern;
|
||||
|
||||
|
||||
static inline void Raid0Pattern_init(Raid0Pattern* this,
|
||||
unsigned chunkSize, UInt16Vec* stripeTargetIDs, unsigned defaultNumTargets);
|
||||
static inline void Raid0Pattern_initFromChunkSize(Raid0Pattern* this, unsigned chunkSize);
|
||||
static inline Raid0Pattern* Raid0Pattern_construct(
|
||||
unsigned chunkSize, UInt16Vec* stripeTargetIDs, unsigned defaultNumTargets);
|
||||
static inline Raid0Pattern* Raid0Pattern_constructFromChunkSize(unsigned chunkSize);
|
||||
static inline void Raid0Pattern_uninit(StripePattern* this);
|
||||
|
||||
static inline void __Raid0Pattern_assignVirtualFunctions(Raid0Pattern* this);
|
||||
|
||||
// virtual functions
|
||||
extern bool Raid0Pattern_deserializePattern(StripePattern* this, DeserializeCtx* ctx);
|
||||
|
||||
extern size_t Raid0Pattern_getStripeTargetIndex(StripePattern* this, int64_t pos);
|
||||
extern uint16_t Raid0Pattern_getStripeTargetID(StripePattern* this, int64_t pos);
|
||||
extern void Raid0Pattern_getStripeTargetIDsCopy(StripePattern* this, UInt16Vec* outTargetIDs);
|
||||
extern UInt16Vec* Raid0Pattern_getStripeTargetIDs(StripePattern* this);
|
||||
extern unsigned Raid0Pattern_getMinNumTargets(StripePattern* this);
|
||||
extern unsigned Raid0Pattern_getDefaultNumTargets(StripePattern* this);
|
||||
|
||||
|
||||
|
||||
struct Raid0Pattern
|
||||
{
|
||||
StripePattern stripePattern;
|
||||
|
||||
UInt16Vec stripeTargetIDs;
|
||||
unsigned defaultNumTargets;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param stripeTargetIDs will be copied
|
||||
* @param defaultNumTargets default number of targets (0 for app-level default)
|
||||
*/
|
||||
void Raid0Pattern_init(Raid0Pattern* this,
|
||||
unsigned chunkSize, UInt16Vec* stripeTargetIDs, unsigned defaultNumTargets)
|
||||
{
|
||||
StripePattern_initFromPatternType( (StripePattern*)this, STRIPEPATTERN_Raid0, chunkSize);
|
||||
|
||||
// assign virtual functions
|
||||
__Raid0Pattern_assignVirtualFunctions(this);
|
||||
|
||||
// init attribs
|
||||
UInt16Vec_init(&this->stripeTargetIDs);
|
||||
|
||||
ListTk_copyUInt16ListToVec( (UInt16List*)stripeTargetIDs, &this->stripeTargetIDs);
|
||||
|
||||
this->defaultNumTargets = defaultNumTargets ? defaultNumTargets : 4;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: for deserialization only
|
||||
*/
|
||||
void Raid0Pattern_initFromChunkSize(Raid0Pattern* this, unsigned chunkSize)
|
||||
{
|
||||
StripePattern_initFromPatternType( (StripePattern*)this, STRIPEPATTERN_Raid0, chunkSize);
|
||||
|
||||
// assign virtual functions
|
||||
__Raid0Pattern_assignVirtualFunctions(this);
|
||||
|
||||
// init attribs
|
||||
UInt16Vec_init(&this->stripeTargetIDs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stripeTargetIDs will be copied
|
||||
* @param defaultNumTargets default number of targets (0 for app-level default)
|
||||
*/
|
||||
Raid0Pattern* Raid0Pattern_construct(
|
||||
unsigned chunkSize, UInt16Vec* stripeTargetIDs, unsigned defaultNumTargets)
|
||||
{
|
||||
struct Raid0Pattern* this = os_kmalloc(sizeof(*this) );
|
||||
|
||||
Raid0Pattern_init(this, chunkSize, stripeTargetIDs, defaultNumTargets);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: for deserialization only
|
||||
*/
|
||||
Raid0Pattern* Raid0Pattern_constructFromChunkSize(unsigned chunkSize)
|
||||
{
|
||||
struct Raid0Pattern* this = os_kmalloc(sizeof(*this) );
|
||||
|
||||
Raid0Pattern_initFromChunkSize(this, chunkSize);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void Raid0Pattern_uninit(StripePattern* this)
|
||||
{
|
||||
Raid0Pattern* thisCast = (Raid0Pattern*)this;
|
||||
|
||||
UInt16Vec_uninit(&thisCast->stripeTargetIDs);
|
||||
}
|
||||
|
||||
void __Raid0Pattern_assignVirtualFunctions(Raid0Pattern* this)
|
||||
{
|
||||
( (StripePattern*)this)->uninit = Raid0Pattern_uninit;
|
||||
|
||||
( (StripePattern*)this)->deserializePattern = Raid0Pattern_deserializePattern;
|
||||
|
||||
( (StripePattern*)this)->getStripeTargetIndex = Raid0Pattern_getStripeTargetIndex;
|
||||
( (StripePattern*)this)->getStripeTargetID = Raid0Pattern_getStripeTargetID;
|
||||
( (StripePattern*)this)->getStripeTargetIDsCopy = Raid0Pattern_getStripeTargetIDsCopy;
|
||||
( (StripePattern*)this)->getStripeTargetIDs = Raid0Pattern_getStripeTargetIDs;
|
||||
( (StripePattern*)this)->getMinNumTargets = Raid0Pattern_getMinNumTargets;
|
||||
( (StripePattern*)this)->getDefaultNumTargets = Raid0Pattern_getDefaultNumTargets;
|
||||
}
|
||||
|
||||
#endif /*RAID0PATTERN_H_*/
|
||||
113
client_module/source/common/storage/striping/Raid10Pattern.c
Normal file
113
client_module/source/common/storage/striping/Raid10Pattern.c
Normal file
@@ -0,0 +1,113 @@
|
||||
#include <common/toolkit/MathTk.h>
|
||||
#include "Raid10Pattern.h"
|
||||
|
||||
bool Raid10Pattern_deserializePattern(StripePattern* this, DeserializeCtx* ctx)
|
||||
{
|
||||
Raid10Pattern* thisCast = (Raid10Pattern*)this;
|
||||
|
||||
RawList targetIDsList;
|
||||
RawList mirrorTargetIDsList;
|
||||
|
||||
// defaultNumTargets
|
||||
if(!Serialization_deserializeUInt(ctx, &thisCast->defaultNumTargets) )
|
||||
return false;
|
||||
|
||||
// targetIDs
|
||||
if(!Serialization_deserializeUInt16VecPreprocess(ctx, &targetIDsList) )
|
||||
return false;
|
||||
|
||||
if(!Serialization_deserializeUInt16Vec(&targetIDsList, &thisCast->stripeTargetIDs) )
|
||||
return false;
|
||||
|
||||
// mirrorTargetIDs
|
||||
if(!Serialization_deserializeUInt16VecPreprocess(ctx, &mirrorTargetIDsList) )
|
||||
return false;
|
||||
|
||||
if(!Serialization_deserializeUInt16Vec(&mirrorTargetIDsList, &thisCast->mirrorTargetIDs) )
|
||||
return false;
|
||||
|
||||
// calc stripeSetSize
|
||||
thisCast->stripeSetSize = UInt16Vec_length(
|
||||
&thisCast->stripeTargetIDs) * StripePattern_getChunkSize(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t Raid10Pattern_getStripeTargetIndex(StripePattern* this, int64_t pos)
|
||||
{
|
||||
Raid10Pattern* thisCast = (Raid10Pattern*)this;
|
||||
|
||||
/* the code below is an optimization (wrt division/modulo) of following the two lines:
|
||||
int64_t stripeSetInnerOffset = pos % thisCast->stripeSetSize;
|
||||
int64_t targetIndex = stripeSetInnerOffset / StripePattern_getChunkSize(this); */
|
||||
|
||||
// note: do_div(n64, base32) assigns the result to n64 and returns the remainder!
|
||||
// (do_div is needed for 64bit division on 32bit archs)
|
||||
|
||||
unsigned stripeSetSize = thisCast->stripeSetSize;
|
||||
|
||||
int64_t stripeSetInnerOffset;
|
||||
unsigned chunkSize;
|
||||
size_t targetIndex;
|
||||
|
||||
if(MathTk_isPowerOfTwo(stripeSetSize) )
|
||||
{ // quick path => no modulo needed
|
||||
stripeSetInnerOffset = pos & (stripeSetSize - 1);
|
||||
}
|
||||
else
|
||||
{ // slow path => modulo
|
||||
stripeSetInnerOffset = do_div(pos, thisCast->stripeSetSize);
|
||||
|
||||
// warning: do_div modifies pos! (so do not use it afterwards within this method)
|
||||
}
|
||||
|
||||
chunkSize = StripePattern_getChunkSize(this);
|
||||
|
||||
// this is "a=b/c" written as "a=b>>log2(c)", because chunkSize is a power of two.
|
||||
targetIndex = (stripeSetInnerOffset >> MathTk_log2Int32(chunkSize) );
|
||||
|
||||
return targetIndex;
|
||||
}
|
||||
|
||||
uint16_t Raid10Pattern_getStripeTargetID(StripePattern* this, int64_t pos)
|
||||
{
|
||||
Raid10Pattern* thisCast = (Raid10Pattern*)this;
|
||||
|
||||
size_t targetIndex = Raid10Pattern_getStripeTargetIndex(this, pos);
|
||||
|
||||
return UInt16Vec_at(&thisCast->stripeTargetIDs, targetIndex);
|
||||
}
|
||||
|
||||
void Raid10Pattern_getStripeTargetIDsCopy(StripePattern* this, UInt16Vec* outTargetIDs)
|
||||
{
|
||||
Raid10Pattern* thisCast = (Raid10Pattern*)this;
|
||||
|
||||
ListTk_copyUInt16ListToVec( (UInt16List*)&thisCast->stripeTargetIDs, outTargetIDs);
|
||||
}
|
||||
|
||||
UInt16Vec* Raid10Pattern_getStripeTargetIDs(StripePattern* this)
|
||||
{
|
||||
Raid10Pattern* thisCast = (Raid10Pattern*)this;
|
||||
|
||||
return &thisCast->stripeTargetIDs;
|
||||
}
|
||||
|
||||
UInt16Vec* Raid10Pattern_getMirrorTargetIDs(StripePattern* this)
|
||||
{
|
||||
Raid10Pattern* thisCast = (Raid10Pattern*)this;
|
||||
|
||||
return &thisCast->mirrorTargetIDs;
|
||||
}
|
||||
|
||||
unsigned Raid10Pattern_getMinNumTargets(StripePattern* this)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
unsigned Raid10Pattern_getDefaultNumTargets(StripePattern* this)
|
||||
{
|
||||
Raid10Pattern* thisCast = (Raid10Pattern*)this;
|
||||
|
||||
return thisCast->defaultNumTargets;
|
||||
}
|
||||
|
||||
96
client_module/source/common/storage/striping/Raid10Pattern.h
Normal file
96
client_module/source/common/storage/striping/Raid10Pattern.h
Normal file
@@ -0,0 +1,96 @@
|
||||
#ifndef RAID10PATTERN_H_
|
||||
#define RAID10PATTERN_H_
|
||||
|
||||
#include <common/toolkit/Serialization.h>
|
||||
#include "StripePattern.h"
|
||||
|
||||
struct Raid10Pattern;
|
||||
typedef struct Raid10Pattern Raid10Pattern;
|
||||
|
||||
|
||||
static inline void Raid10Pattern_initFromChunkSize(Raid10Pattern* this, unsigned chunkSize);
|
||||
static inline Raid10Pattern* Raid10Pattern_constructFromChunkSize(unsigned chunkSize);
|
||||
static inline void Raid10Pattern_uninit(StripePattern* this);
|
||||
|
||||
static inline void __Raid10Pattern_assignVirtualFunctions(Raid10Pattern* this);
|
||||
|
||||
// virtual functions
|
||||
extern bool Raid10Pattern_deserializePattern(StripePattern* this, DeserializeCtx* ctx);
|
||||
|
||||
extern size_t Raid10Pattern_getStripeTargetIndex(StripePattern* this, int64_t pos);
|
||||
extern uint16_t Raid10Pattern_getStripeTargetID(StripePattern* this, int64_t pos);
|
||||
extern void Raid10Pattern_getStripeTargetIDsCopy(StripePattern* this, UInt16Vec* outTargetIDs);
|
||||
extern UInt16Vec* Raid10Pattern_getStripeTargetIDs(StripePattern* this);
|
||||
extern UInt16Vec* Raid10Pattern_getMirrorTargetIDs(StripePattern* this);
|
||||
extern unsigned Raid10Pattern_getMinNumTargets(StripePattern* this);
|
||||
extern unsigned Raid10Pattern_getDefaultNumTargets(StripePattern* this);
|
||||
|
||||
|
||||
/**
|
||||
* Note: We don't have the general _construct() and _init() methods implemented, because we just
|
||||
* don't need them at the moment in the client. (We only have the special _constructFrom...() and
|
||||
* _initFrom...() for deserialization.)
|
||||
*/
|
||||
struct Raid10Pattern
|
||||
{
|
||||
StripePattern stripePattern;
|
||||
|
||||
UInt16Vec stripeTargetIDs;
|
||||
UInt16Vec mirrorTargetIDs;
|
||||
unsigned stripeSetSize; // = numStripeTargets * chunkSize
|
||||
unsigned defaultNumTargets;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Note: for deserialization only
|
||||
*/
|
||||
void Raid10Pattern_initFromChunkSize(Raid10Pattern* this, unsigned chunkSize)
|
||||
{
|
||||
StripePattern_initFromPatternType( (StripePattern*)this, STRIPEPATTERN_Raid10, chunkSize);
|
||||
|
||||
// assign virtual functions
|
||||
__Raid10Pattern_assignVirtualFunctions(this);
|
||||
|
||||
// init attribs
|
||||
UInt16Vec_init(&this->stripeTargetIDs);
|
||||
UInt16Vec_init(&this->mirrorTargetIDs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: for deserialization only
|
||||
*/
|
||||
Raid10Pattern* Raid10Pattern_constructFromChunkSize(unsigned chunkSize)
|
||||
{
|
||||
struct Raid10Pattern* this = os_kmalloc(sizeof(*this) );
|
||||
|
||||
Raid10Pattern_initFromChunkSize(this, chunkSize);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void Raid10Pattern_uninit(StripePattern* this)
|
||||
{
|
||||
Raid10Pattern* thisCast = (Raid10Pattern*)this;
|
||||
|
||||
UInt16Vec_uninit(&thisCast->stripeTargetIDs);
|
||||
UInt16Vec_uninit(&thisCast->mirrorTargetIDs);
|
||||
}
|
||||
|
||||
void __Raid10Pattern_assignVirtualFunctions(Raid10Pattern* this)
|
||||
{
|
||||
( (StripePattern*)this)->uninit = Raid10Pattern_uninit;
|
||||
|
||||
( (StripePattern*)this)->deserializePattern = Raid10Pattern_deserializePattern;
|
||||
|
||||
( (StripePattern*)this)->getStripeTargetIndex = Raid10Pattern_getStripeTargetIndex;
|
||||
( (StripePattern*)this)->getStripeTargetID = Raid10Pattern_getStripeTargetID;
|
||||
( (StripePattern*)this)->getStripeTargetIDsCopy = Raid10Pattern_getStripeTargetIDsCopy;
|
||||
( (StripePattern*)this)->getStripeTargetIDs = Raid10Pattern_getStripeTargetIDs;
|
||||
( (StripePattern*)this)->getMirrorTargetIDs = Raid10Pattern_getMirrorTargetIDs;
|
||||
( (StripePattern*)this)->getMinNumTargets = Raid10Pattern_getMinNumTargets;
|
||||
( (StripePattern*)this)->getDefaultNumTargets = Raid10Pattern_getDefaultNumTargets;
|
||||
}
|
||||
|
||||
|
||||
#endif /* RAID10PATTERN_H_ */
|
||||
37
client_module/source/common/storage/striping/SimplePattern.c
Normal file
37
client_module/source/common/storage/striping/SimplePattern.c
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "SimplePattern.h"
|
||||
|
||||
bool SimplePattern_deserializePattern(StripePattern* this, DeserializeCtx* ctx)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t SimplePattern_getStripeTargetIndex(StripePattern* this, int64_t pos)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t SimplePattern_getStripeTargetID(StripePattern* this, int64_t pos)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned SimplePattern_getMinNumTargets(StripePattern* this)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned SimplePattern_getDefaultNumTargets(StripePattern* this)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SimplePattern_getStripeTargetIDsCopy(StripePattern* this, UInt16Vec* outTargetIDs)
|
||||
{
|
||||
// nothing to be done here
|
||||
}
|
||||
|
||||
UInt16Vec* SimplePattern_getStripeTargetIDs(StripePattern* this)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
65
client_module/source/common/storage/striping/SimplePattern.h
Normal file
65
client_module/source/common/storage/striping/SimplePattern.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#ifndef SIMPLEPATTERN_H_
|
||||
#define SIMPLEPATTERN_H_
|
||||
|
||||
#include "StripePattern.h"
|
||||
|
||||
struct SimplePattern;
|
||||
typedef struct SimplePattern SimplePattern;
|
||||
|
||||
|
||||
static inline void SimplePattern_init(SimplePattern* this,
|
||||
unsigned patternType, unsigned chunkSize);
|
||||
static inline SimplePattern* SimplePattern_construct(
|
||||
unsigned patternType, unsigned chunkSize);
|
||||
static inline void SimplePattern_uninit(StripePattern* this);
|
||||
|
||||
// virtual functions
|
||||
extern bool SimplePattern_deserializePattern(StripePattern* this, DeserializeCtx* ctx);
|
||||
|
||||
extern size_t SimplePattern_getStripeTargetIndex(StripePattern* this, int64_t pos);
|
||||
extern uint16_t SimplePattern_getStripeTargetID(StripePattern* this, int64_t pos);
|
||||
extern unsigned SimplePattern_getMinNumTargets(StripePattern* this);
|
||||
extern unsigned SimplePattern_getDefaultNumTargets(StripePattern* this);
|
||||
extern void SimplePattern_getStripeTargetIDsCopy(StripePattern* this, UInt16Vec* outTargetIDs);
|
||||
extern UInt16Vec* SimplePattern_getStripeTargetIDs(StripePattern* this);
|
||||
|
||||
|
||||
|
||||
struct SimplePattern
|
||||
{
|
||||
StripePattern stripePattern;
|
||||
};
|
||||
|
||||
|
||||
void SimplePattern_init(SimplePattern* this,
|
||||
unsigned patternType, unsigned chunkSize)
|
||||
{
|
||||
StripePattern_initFromPatternType( (StripePattern*)this, patternType, chunkSize);
|
||||
|
||||
// assign virtual functions
|
||||
( (StripePattern*)this)->uninit = SimplePattern_uninit;
|
||||
|
||||
( (StripePattern*)this)->deserializePattern = SimplePattern_deserializePattern;
|
||||
|
||||
( (StripePattern*)this)->getStripeTargetIndex = SimplePattern_getStripeTargetIndex;
|
||||
( (StripePattern*)this)->getStripeTargetID = SimplePattern_getStripeTargetID;
|
||||
( (StripePattern*)this)->getStripeTargetIDsCopy = SimplePattern_getStripeTargetIDsCopy;
|
||||
( (StripePattern*)this)->getStripeTargetIDs = SimplePattern_getStripeTargetIDs;
|
||||
( (StripePattern*)this)->getMinNumTargets = SimplePattern_getMinNumTargets;
|
||||
( (StripePattern*)this)->getDefaultNumTargets = SimplePattern_getDefaultNumTargets;
|
||||
}
|
||||
|
||||
SimplePattern* SimplePattern_construct(unsigned patternType, unsigned chunkSize)
|
||||
{
|
||||
struct SimplePattern* this = os_kmalloc(sizeof(struct SimplePattern) );
|
||||
|
||||
SimplePattern_init(this, patternType, chunkSize);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void SimplePattern_uninit(StripePattern* this)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /*SIMPLEPATTERN_H_*/
|
||||
139
client_module/source/common/storage/striping/StripePattern.c
Normal file
139
client_module/source/common/storage/striping/StripePattern.c
Normal file
@@ -0,0 +1,139 @@
|
||||
#include <common/toolkit/Serialization.h>
|
||||
#include "BuddyMirrorPattern.h"
|
||||
#include "Raid0Pattern.h"
|
||||
#include "Raid10Pattern.h"
|
||||
#include "SimplePattern.h"
|
||||
#include "StripePattern.h"
|
||||
|
||||
#define HAS_NO_POOL_FLAG (1 << 24)
|
||||
|
||||
/**
|
||||
* Calls the virtual uninit method and kfrees the object.
|
||||
*/
|
||||
void StripePattern_virtualDestruct(StripePattern* this)
|
||||
{
|
||||
this->uninit(this);
|
||||
kfree(this);
|
||||
}
|
||||
|
||||
|
||||
bool StripePattern_deserializePatternPreprocess(DeserializeCtx* ctx,
|
||||
const char** outPatternStart, uint32_t* outPatternLength)
|
||||
{
|
||||
DeserializeCtx temp = *ctx;
|
||||
|
||||
if(!Serialization_deserializeUInt(&temp, outPatternLength))
|
||||
return false;
|
||||
|
||||
*outPatternStart = ctx->data;
|
||||
|
||||
if (*outPatternLength > ctx->length)
|
||||
return false;
|
||||
|
||||
ctx->data += *outPatternLength;
|
||||
ctx->length -= *outPatternLength;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return outPattern; outPattern->patternType is STRIPEPATTERN_Invalid on error
|
||||
*/
|
||||
StripePattern* StripePattern_createFromBuf(const char* patternStart,
|
||||
uint32_t patternLength)
|
||||
{
|
||||
struct StripePatternHeader patternHeader;
|
||||
StripePattern* pattern;
|
||||
DeserializeCtx ctx = {
|
||||
.data = patternStart,
|
||||
.length = patternLength,
|
||||
};
|
||||
bool deserRes;
|
||||
|
||||
if (!__StripePattern_deserializeHeader(&ctx, &patternHeader))
|
||||
return (StripePattern*)SimplePattern_construct(STRIPEPATTERN_Invalid, 0);
|
||||
|
||||
switch (patternHeader.patternType)
|
||||
{
|
||||
case STRIPEPATTERN_Raid0:
|
||||
{
|
||||
pattern = (StripePattern*)Raid0Pattern_constructFromChunkSize(patternHeader.chunkSize);
|
||||
} break;
|
||||
|
||||
case STRIPEPATTERN_Raid10:
|
||||
{
|
||||
pattern = (StripePattern*)Raid10Pattern_constructFromChunkSize(patternHeader.chunkSize);
|
||||
} break;
|
||||
|
||||
case STRIPEPATTERN_BuddyMirror:
|
||||
{
|
||||
pattern = (StripePattern*)BuddyMirrorPattern_constructFromChunkSize(
|
||||
patternHeader.chunkSize);
|
||||
} break;
|
||||
|
||||
default:
|
||||
{
|
||||
pattern = (StripePattern*)SimplePattern_construct(STRIPEPATTERN_Invalid, 0);
|
||||
return pattern;
|
||||
} break;
|
||||
}
|
||||
|
||||
deserRes = pattern->deserializePattern(pattern, &ctx);
|
||||
if(unlikely(!deserRes) )
|
||||
{ // deserialization failed => discard half-initialized pattern and create new invalid pattern
|
||||
StripePattern_virtualDestruct(pattern);
|
||||
|
||||
pattern = (StripePattern*)SimplePattern_construct(STRIPEPATTERN_Invalid, 0);
|
||||
|
||||
return pattern;
|
||||
}
|
||||
|
||||
return pattern;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool __StripePattern_deserializeHeader(DeserializeCtx* ctx,
|
||||
struct StripePatternHeader* outPatternHeader)
|
||||
{
|
||||
// pattern length
|
||||
if(!Serialization_deserializeUInt(ctx, &outPatternHeader->patternLength) )
|
||||
return false;
|
||||
|
||||
// pattern type
|
||||
if(!Serialization_deserializeUInt(ctx, &outPatternHeader->patternType) )
|
||||
return false;
|
||||
|
||||
// chunkSize
|
||||
if(!Serialization_deserializeUInt(ctx, &outPatternHeader->chunkSize) )
|
||||
return false;
|
||||
|
||||
// storagePoolId
|
||||
if (!(outPatternHeader->patternType & HAS_NO_POOL_FLAG)) {
|
||||
if(!StoragePoolId_deserialize(ctx, &outPatternHeader->storagePoolId) )
|
||||
return false;
|
||||
}
|
||||
|
||||
outPatternHeader->patternType &= ~HAS_NO_POOL_FLAG;
|
||||
|
||||
// check length field
|
||||
if(outPatternHeader->patternLength < STRIPEPATTERN_HEADER_LENGTH)
|
||||
return false;
|
||||
|
||||
// check chunkSize
|
||||
if(!outPatternHeader->chunkSize)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Predefined virtual method returning NULL. Will be overridden by StripePatterns (e.g. Raid10)
|
||||
* that actually do have mirror targets.
|
||||
*
|
||||
* @return NULL for patterns that don't have mirror targets.
|
||||
*/
|
||||
UInt16Vec* StripePattern_getMirrorTargetIDs(StripePattern* this)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
146
client_module/source/common/storage/striping/StripePattern.h
Normal file
146
client_module/source/common/storage/striping/StripePattern.h
Normal file
@@ -0,0 +1,146 @@
|
||||
#ifndef STRIPEPATTERN_H_
|
||||
#define STRIPEPATTERN_H_
|
||||
|
||||
/**
|
||||
* Note: Do not instantiate this "class" directly (it contains pure virtual functions)
|
||||
*/
|
||||
|
||||
#include <common/Common.h>
|
||||
#include <common/storage/StoragePoolId.h>
|
||||
#include <common/toolkit/SerializationTypes.h>
|
||||
#include <common/toolkit/vector/UInt16Vec.h>
|
||||
|
||||
|
||||
// pattern types
|
||||
#define STRIPEPATTERN_Invalid 0
|
||||
#define STRIPEPATTERN_Raid0 1
|
||||
#define STRIPEPATTERN_Raid10 2
|
||||
#define STRIPEPATTERN_BuddyMirror 3
|
||||
|
||||
// minimum allowed stripe pattern chunk size (in bytes)
|
||||
#define STRIPEPATTERN_MIN_CHUNKSIZE (1024*64)
|
||||
|
||||
// pattern serialization defs
|
||||
#define STRIPEPATTERN_HEADER_LENGTH \
|
||||
(sizeof(unsigned) + sizeof(unsigned) + sizeof(unsigned))
|
||||
/* length + type + chunkSize*/
|
||||
|
||||
|
||||
struct StripePatternHeader
|
||||
{
|
||||
// everything in this struct is in host byte order!
|
||||
|
||||
unsigned patternLength; // in bytes
|
||||
unsigned patternType; // the type of pattern, defined as STRIPEPATTERN_x
|
||||
unsigned chunkSize;
|
||||
// storagePoolId is unused in the client at the moment; however we deserialize it to avoid human
|
||||
// errors later
|
||||
StoragePoolId storagePoolId;
|
||||
};
|
||||
|
||||
|
||||
struct StripePattern;
|
||||
typedef struct StripePattern StripePattern;
|
||||
|
||||
|
||||
static inline void StripePattern_initFromPatternType(StripePattern* this,
|
||||
unsigned patternType, unsigned chunkSize);
|
||||
|
||||
extern void StripePattern_virtualDestruct(struct StripePattern* this);
|
||||
|
||||
extern bool StripePattern_deserializePatternPreprocess(DeserializeCtx* ctx,
|
||||
const char** outPatternStart, uint32_t* outPatternLength);
|
||||
extern bool __StripePattern_deserializeHeader(DeserializeCtx* ctx,
|
||||
struct StripePatternHeader* outPatternHeader);
|
||||
|
||||
// static functions
|
||||
extern StripePattern* StripePattern_createFromBuf(const char* patternStart,
|
||||
uint32_t patternLength);
|
||||
|
||||
// virtual functions
|
||||
extern UInt16Vec* StripePattern_getMirrorTargetIDs(StripePattern* this);
|
||||
|
||||
// getters & setters
|
||||
static inline int StripePattern_getPatternType(StripePattern* this);
|
||||
static inline unsigned StripePattern_getChunkSize(StripePattern* this);
|
||||
static inline int64_t StripePattern_getChunkStart(StripePattern* this, int64_t pos);
|
||||
static inline int64_t StripePattern_getNextChunkStart(StripePattern* this, int64_t pos);
|
||||
static inline int64_t StripePattern_getChunkEnd(StripePattern* this, int64_t pos);
|
||||
|
||||
|
||||
struct StripePattern
|
||||
{
|
||||
unsigned patternType; // STRIPEPATTERN_...
|
||||
unsigned chunkSize; // must be a power of two (optimizations rely on it)
|
||||
|
||||
unsigned serialPatternLength; // for (de)serialization
|
||||
|
||||
// virtual functions
|
||||
void (*uninit) (StripePattern* this);
|
||||
|
||||
// (de)serialization
|
||||
bool (*deserializePattern) (StripePattern* this, DeserializeCtx* ctx);
|
||||
|
||||
size_t (*getStripeTargetIndex) (StripePattern* this, int64_t pos);
|
||||
uint16_t (*getStripeTargetID) (StripePattern* this, int64_t pos);
|
||||
void (*getStripeTargetIDsCopy) (StripePattern* this, UInt16Vec* outTargetIDs);
|
||||
UInt16Vec* (*getStripeTargetIDs) (StripePattern* this);
|
||||
UInt16Vec* (*getMirrorTargetIDs) (StripePattern* this);
|
||||
unsigned (*getMinNumTargets) (StripePattern* this);
|
||||
unsigned (*getDefaultNumTargets) (StripePattern* this);
|
||||
};
|
||||
|
||||
|
||||
void StripePattern_initFromPatternType(StripePattern* this, unsigned patternType,
|
||||
unsigned chunkSize)
|
||||
{
|
||||
this->patternType = patternType;
|
||||
this->chunkSize = chunkSize;
|
||||
|
||||
this->serialPatternLength = 0;
|
||||
|
||||
// pre-defined virtual methods
|
||||
this->getMirrorTargetIDs = StripePattern_getMirrorTargetIDs;
|
||||
}
|
||||
|
||||
|
||||
int StripePattern_getPatternType(StripePattern* this)
|
||||
{
|
||||
return this->patternType;
|
||||
}
|
||||
|
||||
unsigned StripePattern_getChunkSize(StripePattern* this)
|
||||
{
|
||||
return this->chunkSize;
|
||||
}
|
||||
|
||||
int64_t StripePattern_getChunkStart(StripePattern* this, int64_t pos)
|
||||
{
|
||||
// the code below is an optimization (wrt division) for the following line:
|
||||
// int64_t chunkStart = pos - (pos % this->chunkSize);
|
||||
|
||||
// "& chunkSize -1" instead of "%", because chunkSize is a power of two
|
||||
unsigned posModChunkSize = pos & (this->chunkSize - 1);
|
||||
|
||||
int64_t chunkStart = pos - posModChunkSize;
|
||||
|
||||
return chunkStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the exact file position where the next chunk starts
|
||||
*/
|
||||
int64_t StripePattern_getNextChunkStart(StripePattern* this, int64_t pos)
|
||||
{
|
||||
return StripePattern_getChunkStart(this, pos) + this->chunkSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the exact file position where the current chunk ends
|
||||
*/
|
||||
int64_t StripePattern_getChunkEnd(StripePattern* this, int64_t pos)
|
||||
{
|
||||
return StripePattern_getNextChunkStart(this, pos) - 1;
|
||||
}
|
||||
|
||||
#endif /*STRIPEPATTERN_H_*/
|
||||
Reference in New Issue
Block a user