/////////////
// seg_tree.c
/////////////
/* Return the number of segments in the segment tree */
unsigned long seg_tree_count(struct seg_tree* seg_tree)
{
seg_tree_rdlock(seg_tree);
unsigned long count = seg_tree->count;
seg_tree_unlock(seg_tree);
return count;
}
/* Return the maximum ending logical offset in the tree */
unsigned long seg_tree_max(struct seg_tree* seg_tree)
{
seg_tree_rdlock(seg_tree);
unsigned long max = seg_tree->max;
seg_tree_unlock(seg_tree);
return max;
}
////////////////
// extent_tree.c
////////////////
/* Return the number of segments in the segment tree */
unsigned long extent_tree_count(struct extent_tree* extent_tree)
{
extent_tree_rdlock(extent_tree);
unsigned long count = extent_tree->count;
extent_tree_unlock(extent_tree);
return count;
}
/* Return the maximum ending logical offset in the tree */
unsigned long extent_tree_max_offset(struct extent_tree* extent_tree)
{
extent_tree_rdlock(extent_tree);
unsigned long max = extent_tree->max;
extent_tree_unlock(extent_tree);
return max;
}
/////////////
// seg_tree.c
/////////////
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
static int
compare_func(struct seg_tree_node* node1, struct seg_tree_node* node2)
{
if (node1->start > node2->end) {
return 1;
} else if (node1->end < node2->start) {
return -1;
} else {
return 0;
}
}
////////////////
// extent_tree.c
////////////////
#undef MIN
#define MIN(a, b) (a < b ? a : b)
#undef MAX
#define MAX(a, b) (a > b ? a : b)
int compare_func(
struct extent_tree_node* node1,
struct extent_tree_node* node2)
{
if (node1->start > node2->end) {
return 1;
} else if (node1->end < node2->start) {
return -1;
} else {
return 0;
}
}
//////////////////
// unifyfs_inode.c
//////////////////
/**
* @brief read lock the inode for ro access.
*
* @param ino inode structure to get access
*
* @return 0 on success, errno otherwise
*/
static inline
int unifyfs_inode_rdlock(struct unifyfs_inode* ino)
{
return pthread_rwlock_rdlock(&ino->rwlock);
}
/**
* @brief write lock the inode for w+r access.
*
* @param ino inode structure to get access
*
* @return 0 on success, errno otherwise
*/
static inline
int unifyfs_inode_wrlock(struct unifyfs_inode* ino)
{
return pthread_rwlock_wrlock(&ino->rwlock);
}
/**
* @brief unlock the inode.
*
* @param ino inode structure to unlock
*/
static inline
void unifyfs_inode_unlock(struct unifyfs_inode* ino)
{
pthread_rwlock_unlock(&ino->rwlock);
}
////////////////
// extent_tree.c
////////////////
/*
* Lock a extent_tree for reading. This should only be used for calling
* extent_tree_iter(). All the other extent_tree functions provide their
* own locking.
*/
void extent_tree_rdlock(struct extent_tree* extent_tree)
{
int rc = pthread_rwlock_rdlock(&extent_tree->rwlock);
if (rc) {
LOGERR("pthread_rwlock_rdlock() failed - rc=%d", rc);
}
}
/*
* Lock a extent_tree for read/write. This should only be used for calling
* extent_tree_iter(). All the other extent_tree functions provide their
* own locking.
*/
void extent_tree_wrlock(struct extent_tree* extent_tree)
{
int rc = pthread_rwlock_wrlock(&extent_tree->rwlock);
if (rc) {
LOGERR("pthread_rwlock_wrlock() failed - rc=%d", rc);
}
}
/*
* Unlock a extent_tree for read/write. This should only be used for calling
* extent_tree_iter(). All the other extent_tree functions provide their
* own locking.
*/
void extent_tree_unlock(struct extent_tree* extent_tree)
{
int rc = pthread_rwlock_unlock(&extent_tree->rwlock);
if (rc) {
LOGERR("pthread_rwlock_unlock() failed - rc=%d", rc);
}
}
/////////////
// seg_tree.c
/////////////
/*
* Lock a seg_tree for reading. This should only be used for calling
* seg_tree_iter(). All the other seg_tree functions provide their
* own locking.
*/
void
seg_tree_rdlock(struct seg_tree* seg_tree)
{
int rc = pthread_rwlock_rdlock(&seg_tree->rwlock);
if (rc) {
LOGERR("pthread_rwlock_rdlock() failed - rc=%d", rc);
}
}
/*
* Lock a seg_tree for read/write. This should only be used for calling
* seg_tree_iter(). All the other seg_tree functions provide their
* own locking.
*/
void
seg_tree_wrlock(struct seg_tree* seg_tree)
{
int rc = pthread_rwlock_wrlock(&seg_tree->rwlock);
if (rc) {
LOGERR("pthread_rwlock_wrlock() failed - rc=%d", rc);
}
}
/*
* Unlock a seg_tree for read/write. This should only be used for calling
* seg_tree_iter(). All the other seg_tree functions provide their
* own locking.
*/
void
seg_tree_unlock(struct seg_tree* seg_tree)
{
int rc = pthread_rwlock_unlock(&seg_tree->rwlock);
if (rc) {
LOGERR("pthread_rwlock_unlock() failed - rc=%d", rc);
}
}
////////////////
// extent_tree.c
////////////////
/*
* Given a range tree and a starting node, iterate though all the nodes
* in the tree, returning the next one each time. If start is NULL, then
* start with the first node in the tree.
*
* This is meant to be called in a loop, like:
*
* extent_tree_rdlock(extent_tree);
*
* struct extent_tree_node *node = NULL;
* while ((node = extent_tree_iter(extent_tree, node))) {
* printf("[%d-%d]", node->start, node->end);
* }
*
* extent_tree_unlock(extent_tree);
*
* Note: this function does no locking, and assumes you're properly locking
* and unlocking the extent_tree before doing the iteration (see
* extent_tree_rdlock()/extent_tree_wrlock()/extent_tree_unlock()).
*/
struct extent_tree_node* extent_tree_iter(
struct extent_tree* extent_tree,
struct extent_tree_node* start)
{
struct extent_tree_node* next = NULL;
if (start == NULL) {
/* Initial case, no starting node */
next = RB_MIN(inttree, &extent_tree->head);
return next;
}
/*
* We were given a valid start node. Look it up to start our traversal
* from there.
*/
next = RB_FIND(inttree, &extent_tree->head, start);
if (!next) {
/* Some kind of error */
return NULL;
}
/* Look up our next node */
next = RB_NEXT(inttree, &extent_tree->head, start);
return next;
}
/////////////
// seg_tree.c
/////////////
/*
* Given a range tree and a starting node, iterate though all the nodes
* in the tree, returning the next one each time. If start is NULL, then
* start with the first node in the tree.
*
* This is meant to be called in a loop, like:
*
* seg_tree_rdlock(seg_tree);
*
* struct seg_tree_node *node = NULL;
* while ((node = seg_tree_iter(seg_tree, node))) {
* printf("[%d-%d]", node->start, node->end);
* }
*
* seg_tree_unlock(seg_tree);
*
* Note: this function does no locking, and assumes you're properly locking
* and unlocking the seg_tree before doing the iteration (see
* seg_tree_rdlock()/seg_tree_wrlock()/seg_tree_unlock()).
*/
struct seg_tree_node*
seg_tree_iter(struct seg_tree* seg_tree, struct seg_tree_node* start)
{
struct seg_tree_node* next = NULL;
struct seg_tree_node* tmp = NULL;
if (start == NULL) {
/* Initial case, no starting node */
next = RB_MIN(inttree, &seg_tree->head);
return next;
}
/*
* We were given a valid start node. Look it up to start our traversal
* from there.
*/
tmp = RB_FIND(inttree, &seg_tree->head, start);
if (!tmp) {
/* Some kind of error */
return NULL;
}
/* Look up our next node */
next = RB_NEXT(inttree, &seg_tree->head, start);
return next;
}
/////////////
// seg_tree.c
/////////////
/*
* Remove all nodes in seg_tree, but keep it initialized so you can
* seg_tree_add() to it.
*/
void seg_tree_clear(struct seg_tree* seg_tree)
{
struct seg_tree_node* node = NULL;
struct seg_tree_node* oldnode = NULL;
seg_tree_wrlock(seg_tree);
if (RB_EMPTY(&seg_tree->head)) {
/* seg_tree is empty, nothing to do */
seg_tree_unlock(seg_tree);
return;
}
/* Remove and free each node in the tree */
while ((node = seg_tree_iter(seg_tree, node))) {
if (oldnode) {
RB_REMOVE(inttree, &seg_tree->head, oldnode);
free(oldnode);
}
oldnode = node;
}
if (oldnode) {
RB_REMOVE(inttree, &seg_tree->head, oldnode);
free(oldnode);
}
seg_tree->count = 0;
seg_tree->max = 0;
seg_tree_unlock(seg_tree);
}
////////////////
// extent_tree.c
////////////////
/*
* Remove all nodes in extent_tree, but keep it initialized so you can
* extent_tree_add() to it.
*/
void extent_tree_clear(struct extent_tree* extent_tree)
{
struct extent_tree_node* node = NULL;
struct extent_tree_node* oldnode = NULL;
extent_tree_wrlock(extent_tree);
if (RB_EMPTY(&extent_tree->head)) {
/* extent_tree is empty, nothing to do */
extent_tree_unlock(extent_tree);
return;
}
/* Remove and free each node in the tree */
while ((node = extent_tree_iter(extent_tree, node))) {
if (oldnode) {
RB_REMOVE(inttree, &extent_tree->head, oldnode);
free(oldnode);
}
oldnode = node;
}
if (oldnode) {
RB_REMOVE(inttree, &extent_tree->head, oldnode);
free(oldnode);
}
extent_tree->count = 0;
extent_tree->max = 0;
extent_tree_unlock(extent_tree);
}
///////////////////////
// unifyfs_inode_tree.c
///////////////////////
/* Returns 0 on success, positive non-zero error code otherwise */
int unifyfs_inode_tree_init(
struct unifyfs_inode_tree* tree)
{
int ret = 0;
if (!tree) {
return EINVAL;
}
memset(tree, 0, sizeof(*tree));
ret = pthread_rwlock_init(&tree->rwlock, NULL);
RB_INIT(&tree->head);
return ret;
}
////////////////
// extent_tree.c
////////////////
/* Returns 0 on success, positive non-zero error code otherwise */
int extent_tree_init(struct extent_tree* extent_tree)
{
memset(extent_tree, 0, sizeof(*extent_tree));
pthread_rwlock_init(&extent_tree->rwlock, NULL);
RB_INIT(&extent_tree->head);
return 0;
}
/////////////
// seg_tree.c
/////////////
/* Returns 0 on success, positive non-zero error code otherwise */
int seg_tree_init(struct seg_tree* seg_tree)
{
memset(seg_tree, 0, sizeof(*seg_tree));
pthread_rwlock_init(&seg_tree->rwlock, NULL);
RB_INIT(&seg_tree->head);
return 0;
}