mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-12-02 11:57:43 +08:00
fixed bugs in acl_dlink.c for adding continuous integers;
acl_dlink.c supports for adding negative integers.
This commit is contained in:
parent
3d864ea148
commit
8ada09778c
@ -1,6 +1,10 @@
|
||||
修改历史列表:
|
||||
|
||||
------------------------------------------------------------------------
|
||||
608) 2017.9.13
|
||||
608.1) bugfix: acl_dlink.c 二分块算法当添加两个连续的数据块时,应该进行合并
|
||||
608.2) feature: acl_dlink.c 二分块算法支持添加负整数
|
||||
|
||||
607) 2017.9.6
|
||||
607.1) bugfix: acl_mylog.c 内部的线程锁采用递归锁,否则,当记日志时收到信号再
|
||||
记日志时会造成死锁
|
||||
|
@ -13,8 +13,8 @@ extern "C" {
|
||||
* 二分块数据链元素类型定义
|
||||
*/
|
||||
typedef struct {
|
||||
acl_uint64 begin;
|
||||
acl_uint64 end;
|
||||
acl_int64 begin;
|
||||
acl_int64 end;
|
||||
void *pnode;
|
||||
} ACL_DITEM;
|
||||
|
||||
@ -72,69 +72,69 @@ ACL_API ACL_DITEM *acl_dlink_lookup2_by_item(const ACL_DLINK *plink,
|
||||
/**
|
||||
* 从二分块数据链中查询某个值所对应的数据块元素地址
|
||||
* @param plink {const ACL_DLINK*} 二分块数据链对象指针
|
||||
* @param n {acl_uint64} 查询值
|
||||
* @param n {acl_int64} 查询值
|
||||
* @return {ACL_DITEM*} 数据块元素
|
||||
*/
|
||||
ACL_API ACL_DITEM *acl_dlink_lookup(const ACL_DLINK *plink, acl_uint64 n);
|
||||
ACL_API ACL_DITEM *acl_dlink_lookup(const ACL_DLINK *plink, acl_int64 n);
|
||||
|
||||
/**
|
||||
* 从二分块数据链中查询某个值所对应的数据块元素地址并记录其下标位置
|
||||
* @param plink {const ACL_DLINK*} 二分块数据链对象指针
|
||||
* @param n {acl_uint64} 查询值
|
||||
* @param n {acl_int64} 查询值
|
||||
* @param pidx {int*} 存储查询数据元素结果在二分数据链中的下标位置
|
||||
* @return {ACL_DITEM*} 数据块元素
|
||||
*/
|
||||
ACL_API ACL_DITEM *acl_dlink_lookup2(const ACL_DLINK *plink,
|
||||
acl_uint64 n, int *pidx);
|
||||
acl_int64 n, int *pidx);
|
||||
|
||||
/**
|
||||
* 从二分块数据链中查询某个范围的数据块元素地址并记录其下标位置
|
||||
* @param plink {const ACL_DLINK*} 二分块数据链对象指针
|
||||
* @param begin {acl_uint64} 查询范围的起始位置值
|
||||
* @param end {acl_uint64} 查询范围的结束位置值
|
||||
* @param begin {acl_int64} 查询范围的起始位置值
|
||||
* @param end {acl_int64} 查询范围的结束位置值
|
||||
* @param pidx {int*} 存储查询数据元素结果在二分数据链中的下标位置
|
||||
* @return {ACL_DITEM*} 数据块元素
|
||||
*/
|
||||
ACL_API ACL_DITEM *acl_dlink_lookup_range(const ACL_DLINK *plink,
|
||||
acl_uint64 begin, acl_uint64 end, int *pidx);
|
||||
acl_int64 begin, acl_int64 end, int *pidx);
|
||||
|
||||
/**
|
||||
* 从二分块数据链中查询第一个大于某个给定值的数据块元素并记录下标位置
|
||||
* @param plink {const ACL_DLINK*} 二分块数据链对象指针
|
||||
* @param off {acl_uint64} 给定比较值
|
||||
* @param off {acl_int64} 给定比较值
|
||||
* @param pidx {int*} 存储查询数据元素结果在二分数据链中的下标位置
|
||||
* @return {ACL_DITEM*} 数据块元素
|
||||
*/
|
||||
ACL_API ACL_DITEM *acl_dlink_lookup_larger(const ACL_DLINK *plink,
|
||||
acl_uint64 off, int *pidx);
|
||||
acl_int64 off, int *pidx);
|
||||
|
||||
/**
|
||||
* 从二分块数据链中查询第一个小于某个给定值的数据块元素并记录下标位置
|
||||
* @param plink {const ACL_DLINK*} 二分块数据链对象指针
|
||||
* @param off {acl_uint64} 给定比较值
|
||||
* @param off {acl_int64} 给定比较值
|
||||
* @param pidx {int*} 存储查询数据元素结果在二分数据链中的下标位置
|
||||
* @return {ACL_DITEM*} 数据块元素
|
||||
*/
|
||||
ACL_API ACL_DITEM *acl_dlink_lookup_lower(const ACL_DLINK *plink,
|
||||
acl_uint64 off, int *pidx);
|
||||
acl_int64 off, int *pidx);
|
||||
|
||||
/**
|
||||
* 向二分块数据链中添加起始、结束数据块
|
||||
* @param plink {ACL_DLINK*} 二分块数据链对象指针
|
||||
* @param begin {acl_uint64} 给定起始位置值
|
||||
* @param end {acl_uint64} 给定结束位置值
|
||||
* @param begin {acl_int64} 给定起始位置值
|
||||
* @param end {acl_int64} 给定结束位置值
|
||||
* @return {ACL_DITEM*} 新创建的数据块元素
|
||||
*/
|
||||
ACL_API ACL_DITEM *acl_dlink_insert(ACL_DLINK *plink,
|
||||
acl_uint64 begin, acl_uint64 end);
|
||||
acl_int64 begin, acl_int64 end);
|
||||
|
||||
/**
|
||||
* 从二分块数据链中删除包含某个给定值的数据块元素
|
||||
* @param plink {ACL_DLINK*} 二分块数据链对象指针
|
||||
* @param n {acl_uint64} 给定位置值
|
||||
* @param n {acl_int64} 给定位置值
|
||||
* @return {int} 0:表示OK,-1: 表示输入参数非法或不存在
|
||||
*/
|
||||
ACL_API int acl_dlink_delete(ACL_DLINK *plink, acl_uint64 n);
|
||||
ACL_API int acl_dlink_delete(ACL_DLINK *plink, acl_int64 n);
|
||||
|
||||
/**
|
||||
* 根据数据块元素从二分块数据链中删除该数据块元素
|
||||
@ -149,18 +149,18 @@ ACL_API int acl_dlink_delete_by_item(ACL_DLINK *plink, ACL_DITEM *pitem);
|
||||
* @deprecated 此函数将来也许不再提供
|
||||
*/
|
||||
ACL_API ACL_DITEM *acl_dlink_modify(ACL_DLINK *plink,
|
||||
acl_uint64 begin, acl_uint64 end);
|
||||
acl_int64 begin, acl_int64 end);
|
||||
|
||||
/**
|
||||
* 从二分数据链中删除某个数值范围的数据块集合,
|
||||
* 删除后有可能会在内部增加新的数据块元素
|
||||
* @param plink {ACL_DLINK*} 二分块数据链对象指针
|
||||
* @param begin {acl_uint64} 需要删除范围的起始位置
|
||||
* @param end {acl_uint64} 需要删除范围的结束位置
|
||||
* @param begin {acl_int64} 需要删除范围的起始位置
|
||||
* @param end {acl_int64} 需要删除范围的结束位置
|
||||
* @return {int} 0:表示OK,-1: 表示输入参数非法
|
||||
*/
|
||||
ACL_API int acl_dlink_delete_range(ACL_DLINK *plink,
|
||||
acl_uint64 begin, acl_uint64 end);
|
||||
acl_int64 begin, acl_int64 end);
|
||||
|
||||
/**
|
||||
* 返回某下标位置的数据块元素地址
|
||||
|
@ -5,12 +5,55 @@ static ACL_DLINK *build(void)
|
||||
const char *myname = "build";
|
||||
ACL_DLINK *dlink = acl_dlink_create(100);
|
||||
|
||||
acl_dlink_insert(dlink, 0, 10);
|
||||
printf("add: -10 -- -10\r\n");
|
||||
acl_dlink_insert(dlink, -10, -10);
|
||||
printf("add: -9 -- -9\r\n");
|
||||
acl_dlink_insert(dlink, -9, -9);
|
||||
printf("add: -8 -- -7\r\n");
|
||||
acl_dlink_insert(dlink, -8, -7);
|
||||
printf("\r\n");
|
||||
|
||||
printf("add: -4 -- -4\r\n");
|
||||
acl_dlink_insert(dlink, -4, -4);
|
||||
printf("\r\n");
|
||||
|
||||
printf("add: -2 -- -1\r\n");
|
||||
acl_dlink_insert(dlink, -2, -1);
|
||||
printf("add: 0 -- 7\r\n");
|
||||
acl_dlink_insert(dlink, 0, 7);
|
||||
printf("add: 8 -- 10\r\n");
|
||||
acl_dlink_insert(dlink, 8, 10);
|
||||
printf("add: 11 -- 10\r\n");
|
||||
acl_dlink_insert(dlink, 11, 10);
|
||||
printf("add: 12 -- 14\r\n");
|
||||
acl_dlink_insert(dlink, 12, 12);
|
||||
printf("add: 13 -- 14\r\n");
|
||||
acl_dlink_insert(dlink, 13, 14);
|
||||
printf("add: 15 -- 16\r\n");
|
||||
acl_dlink_insert(dlink, 15, 16);
|
||||
printf("add: 17 -- 18\r\n");
|
||||
acl_dlink_insert(dlink, 17, 18);
|
||||
printf("add: 15 -- 18\r\n");
|
||||
acl_dlink_insert(dlink, 15, 18);
|
||||
printf("\r\n");
|
||||
|
||||
printf("add: 20 -- 21\r\n");
|
||||
acl_dlink_insert(dlink, 20, 21);
|
||||
printf("add: 21 -- 28\r\n");
|
||||
acl_dlink_insert(dlink, 21, 28);
|
||||
acl_dlink_insert(dlink, 31, 38);
|
||||
printf("\r\n");
|
||||
|
||||
printf("add: 31 -- 40\r\n");
|
||||
acl_dlink_insert(dlink, 31, 40);
|
||||
printf("add: 32 -- 40\r\n");
|
||||
acl_dlink_insert(dlink, 32, 40);
|
||||
printf("add: 33 -- 35\r\n");
|
||||
acl_dlink_insert(dlink, 33, 35);
|
||||
printf("add: 41 -- 48\r\n");
|
||||
acl_dlink_insert(dlink, 41, 48);
|
||||
printf("\r\n");
|
||||
|
||||
printf("add: 51 -- 58\r\n");
|
||||
acl_dlink_insert(dlink, 51, 58);
|
||||
|
||||
printf("\r\n%s:\r\n", myname);
|
||||
@ -99,6 +142,10 @@ static void test(void)
|
||||
}
|
||||
int main(int argc acl_unused, char *argv[] acl_unused)
|
||||
{
|
||||
acl_dlink_free(build());
|
||||
printf("Enter any key to continue ...\r\n");
|
||||
getchar();
|
||||
|
||||
test();
|
||||
return (0);
|
||||
}
|
||||
|
0
lib_acl/samples/dlink/valgrind.sh
Normal file → Executable file
0
lib_acl/samples/dlink/valgrind.sh
Normal file → Executable file
@ -49,7 +49,7 @@ static void dlink_free_callback(void *arg)
|
||||
* if idx > 0 && idx <= a->count - 1 -----> 说明在数组的中间的某一位置
|
||||
* if idx > a->count - 1 -----> 说明在数组的最后一位置添加
|
||||
*/
|
||||
static int scope_pos(const ACL_ARRAY *a, acl_uint64 n)
|
||||
static int scope_pos(const ACL_ARRAY *a, acl_int64 n)
|
||||
{
|
||||
ACL_DITEM *pitem_left, *pitem_right;
|
||||
int lidx, hidx, midx, ridx, idx;
|
||||
@ -108,19 +108,19 @@ static int scope_pos(const ACL_ARRAY *a, acl_uint64 n)
|
||||
return idx;
|
||||
}
|
||||
|
||||
static int begin_pos(const ACL_ARRAY *a, acl_uint64 n)
|
||||
static int begin_pos(const ACL_ARRAY *a, acl_int64 n)
|
||||
{
|
||||
return scope_pos(a, n);
|
||||
}
|
||||
|
||||
static int end_pos(const ACL_ARRAY *a, acl_uint64 n)
|
||||
static int end_pos(const ACL_ARRAY *a, acl_int64 n)
|
||||
{
|
||||
return scope_pos(a, n);
|
||||
}
|
||||
|
||||
#ifdef _USE_PRED_INSERT_
|
||||
static ACL_DITEM *dlink_pred_insert(ACL_ARRAY *a, int idx_position,
|
||||
acl_uint64 begin, acl_uint64 end)
|
||||
acl_int64 begin, acl_int64 end)
|
||||
{
|
||||
ACL_DITEM *pitem;
|
||||
int ret;
|
||||
@ -142,7 +142,7 @@ static ACL_DITEM *dlink_pred_insert(ACL_ARRAY *a, int idx_position,
|
||||
#endif
|
||||
|
||||
static ACL_DITEM *dlink_succ_insert(ACL_ARRAY *a, int idx_position,
|
||||
acl_uint64 begin, acl_uint64 end)
|
||||
acl_int64 begin, acl_int64 end)
|
||||
{
|
||||
ACL_DITEM *pitem;
|
||||
int ret;
|
||||
@ -162,7 +162,7 @@ static ACL_DITEM *dlink_succ_insert(ACL_ARRAY *a, int idx_position,
|
||||
return pitem;
|
||||
}
|
||||
|
||||
static ACL_DITEM *dlink_append(ACL_ARRAY *a, acl_uint64 begin, acl_uint64 end)
|
||||
static ACL_DITEM *dlink_append(ACL_ARRAY *a, acl_int64 begin, acl_int64 end)
|
||||
{
|
||||
ACL_DITEM *pitem;
|
||||
int ret;
|
||||
@ -182,7 +182,7 @@ static ACL_DITEM *dlink_append(ACL_ARRAY *a, acl_uint64 begin, acl_uint64 end)
|
||||
return pitem;
|
||||
}
|
||||
|
||||
static ACL_DITEM *dlink_prepend(ACL_ARRAY *a, acl_uint64 begin, acl_uint64 end)
|
||||
static ACL_DITEM *dlink_prepend(ACL_ARRAY *a, acl_int64 begin, acl_int64 end)
|
||||
{
|
||||
ACL_DITEM *pitem;
|
||||
int ret;
|
||||
@ -216,7 +216,7 @@ static int dlink_node_merge(ACL_ARRAY *a, int idx_obj_begin, int idx_src_begin)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ACL_DITEM *dlink_add(ACL_ARRAY *a, acl_uint64 begin, acl_uint64 end)
|
||||
static ACL_DITEM *dlink_add(ACL_ARRAY *a, acl_int64 begin, acl_int64 end)
|
||||
{
|
||||
ACL_DITEM *pitem_right, *pitem_left, *pitem;
|
||||
int idx_begin, idx_end;
|
||||
@ -228,7 +228,7 @@ static ACL_DITEM *dlink_add(ACL_ARRAY *a, acl_uint64 begin, acl_uint64 end)
|
||||
return NULL;
|
||||
|
||||
idx_begin = begin_pos(a, begin);
|
||||
if(idx_begin < 0 || idx_begin >= acl_array_size(a)) /* an error happened */
|
||||
if(idx_begin < 0 || idx_begin >= acl_array_size(a)) /* an error happened */
|
||||
return NULL;
|
||||
|
||||
idx_end = end_pos(a, end);
|
||||
@ -255,7 +255,7 @@ static ACL_DITEM *dlink_add(ACL_ARRAY *a, acl_uint64 begin, acl_uint64 end)
|
||||
* this is to say the begin and end is on the same d-link
|
||||
*/
|
||||
|
||||
if (end < pitem_left->begin) {
|
||||
if (end + 1 < pitem_left->begin) {
|
||||
/*
|
||||
* here idx_begin == idx_end must be equal to 0
|
||||
* the begin and the end must be less
|
||||
@ -266,7 +266,7 @@ static ACL_DITEM *dlink_add(ACL_ARRAY *a, acl_uint64 begin, acl_uint64 end)
|
||||
return pitem;
|
||||
}
|
||||
|
||||
if (begin > pitem_left->end) {
|
||||
if (begin > pitem_left->end + 1) {
|
||||
/*
|
||||
* this is to say begin and end
|
||||
* between the current node's end
|
||||
@ -321,7 +321,7 @@ static ACL_DITEM *dlink_add(ACL_ARRAY *a, acl_uint64 begin, acl_uint64 end)
|
||||
* begin < pitem_right->begin;
|
||||
*/
|
||||
|
||||
if(begin < pitem_left->begin) {
|
||||
if (begin < pitem_left->begin) {
|
||||
/*
|
||||
* in the first position of the array
|
||||
* idx_begin == 0 and idx_end >= 1
|
||||
@ -339,7 +339,7 @@ static ACL_DITEM *dlink_add(ACL_ARRAY *a, acl_uint64 begin, acl_uint64 end)
|
||||
* ===> <= end
|
||||
*/
|
||||
|
||||
if(begin <= pitem_left->end) {
|
||||
if (begin <= pitem_left->end + 1) {
|
||||
/*
|
||||
* ===> pitem_left->begin
|
||||
* ===> <= begin
|
||||
@ -347,17 +347,18 @@ static ACL_DITEM *dlink_add(ACL_ARRAY *a, acl_uint64 begin, acl_uint64 end)
|
||||
* ===> < pitem_right->begin
|
||||
* ===> <= end
|
||||
* ===> so, just merge the nodes between the
|
||||
* ===> pitem_left node and the pitem_right node, and include both of them
|
||||
* ===> pitem_left node and the pitem_right node,
|
||||
* ===> and include both of them
|
||||
*/
|
||||
|
||||
/*
|
||||
* merge the pitem_left node, begin ---> end into pitem_right node,
|
||||
* and merge all nodes into one node which are between
|
||||
* merge the pitem_left node, begin ---> end into pitem_right
|
||||
* node, and merge all nodes into one node which are between
|
||||
* the pitem_left node and the pitem_right node,
|
||||
* include both of pitem_left node and pitem_right node
|
||||
*/
|
||||
|
||||
if(end > pitem_right->end) {
|
||||
if (end > pitem_right->end) {
|
||||
/*
|
||||
* ===> pitem_left->begin
|
||||
* ===> <= begin
|
||||
@ -401,7 +402,7 @@ static ACL_DITEM *dlink_add(ACL_ARRAY *a, acl_uint64 begin, acl_uint64 end)
|
||||
* include idx_begin + 1 node and pitem_righ node
|
||||
*/
|
||||
|
||||
if(end > pitem_right->end) {
|
||||
if (end > pitem_right->end) {
|
||||
/*
|
||||
* ===> pitem_left->begin
|
||||
* ===> <= pitem_left->end
|
||||
@ -503,12 +504,12 @@ ACL_DITEM *acl_dlink_lookup2_by_item(const ACL_DLINK *plink, ACL_DITEM *pitem, i
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ACL_DITEM *acl_dlink_lookup(const ACL_DLINK *plink, acl_uint64 n)
|
||||
ACL_DITEM *acl_dlink_lookup(const ACL_DLINK *plink, acl_int64 n)
|
||||
{
|
||||
return acl_dlink_lookup2(plink, n, NULL);
|
||||
}
|
||||
|
||||
ACL_DITEM *acl_dlink_lookup2(const ACL_DLINK *plink, acl_uint64 n, int *pidx)
|
||||
ACL_DITEM *acl_dlink_lookup2(const ACL_DLINK *plink, acl_int64 n, int *pidx)
|
||||
{
|
||||
int lidx, midx, hidx;
|
||||
|
||||
@ -535,8 +536,8 @@ ACL_DITEM *acl_dlink_lookup2(const ACL_DLINK *plink, acl_uint64 n, int *pidx)
|
||||
return NULL; /*not in the d_link scope */
|
||||
}
|
||||
|
||||
ACL_DITEM *acl_dlink_lookup_range(const ACL_DLINK *plink, acl_uint64 begin,
|
||||
acl_uint64 end, int *pidx)
|
||||
ACL_DITEM *acl_dlink_lookup_range(const ACL_DLINK *plink, acl_int64 begin,
|
||||
acl_int64 end, int *pidx)
|
||||
{
|
||||
ACL_DITEM *ditem;
|
||||
|
||||
@ -551,7 +552,7 @@ ACL_DITEM *acl_dlink_lookup_range(const ACL_DLINK *plink, acl_uint64 begin,
|
||||
}
|
||||
|
||||
ACL_DITEM *acl_dlink_lookup_larger(const ACL_DLINK *plink,
|
||||
acl_uint64 off, int *pidx)
|
||||
acl_int64 off, int *pidx)
|
||||
{
|
||||
int i, size;
|
||||
|
||||
@ -571,7 +572,7 @@ ACL_DITEM *acl_dlink_lookup_larger(const ACL_DLINK *plink,
|
||||
}
|
||||
|
||||
ACL_DITEM *acl_dlink_lookup_lower(const ACL_DLINK *plink,
|
||||
acl_uint64 off, int *pidx)
|
||||
acl_int64 off, int *pidx)
|
||||
{
|
||||
int i, size;
|
||||
|
||||
@ -590,10 +591,10 @@ ACL_DITEM *acl_dlink_lookup_lower(const ACL_DLINK *plink,
|
||||
return NULL; /*not in the d_link scope */
|
||||
}
|
||||
|
||||
ACL_DITEM *acl_dlink_insert(ACL_DLINK *plink, acl_uint64 begin, acl_uint64 end)
|
||||
ACL_DITEM *acl_dlink_insert(ACL_DLINK *plink, acl_int64 begin, acl_int64 end)
|
||||
{
|
||||
if (begin > end) {
|
||||
acl_uint64 tmp;
|
||||
acl_int64 tmp;
|
||||
/* swap the begin and end if end < begin */
|
||||
tmp = begin;
|
||||
begin = end;
|
||||
@ -609,7 +610,7 @@ ACL_DITEM *acl_dlink_insert(ACL_DLINK *plink, acl_uint64 begin, acl_uint64 end)
|
||||
return dlink_add(plink->parray, begin, end);
|
||||
}
|
||||
|
||||
int acl_dlink_delete(ACL_DLINK *plink, acl_uint64 n)
|
||||
int acl_dlink_delete(ACL_DLINK *plink, acl_int64 n)
|
||||
{
|
||||
const ACL_DITEM *ditem;
|
||||
int idx;
|
||||
@ -631,7 +632,7 @@ int acl_dlink_delete_by_item(ACL_DLINK *plink, ACL_DITEM *pitem)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acl_dlink_delete_range(ACL_DLINK *plink, acl_uint64 begin, acl_uint64 end)
|
||||
int acl_dlink_delete_range(ACL_DLINK *plink, acl_int64 begin, acl_int64 end)
|
||||
{
|
||||
ACL_ARRAY *parray = plink->parray;
|
||||
ACL_DITEM *pitem, *pitem_low;
|
||||
@ -671,7 +672,7 @@ int acl_dlink_delete_range(ACL_DLINK *plink, acl_uint64 begin, acl_uint64 end)
|
||||
return 0;
|
||||
} else if (end < pitem->end) {
|
||||
/* pitem->begin < begin <= end < pitem->end */
|
||||
acl_uint64 tmp_begin, tmp_end;
|
||||
acl_int64 tmp_begin, tmp_end;
|
||||
|
||||
tmp_begin = end + 1;
|
||||
tmp_end = pitem->end;
|
||||
@ -746,10 +747,10 @@ int acl_dlink_delete_range(ACL_DLINK *plink, acl_uint64 begin, acl_uint64 end)
|
||||
return acl_array_delete_range(parray, low, high, dlink_free_callback);
|
||||
}
|
||||
|
||||
ACL_DITEM *acl_dlink_modify(ACL_DLINK *plink, acl_uint64 begin, acl_uint64 end)
|
||||
ACL_DITEM *acl_dlink_modify(ACL_DLINK *plink, acl_int64 begin, acl_int64 end)
|
||||
{
|
||||
if (begin > end) {
|
||||
acl_uint64 tmp;
|
||||
acl_int64 tmp;
|
||||
/* swap the begin andend if end < begin */
|
||||
tmp = begin;
|
||||
begin = end;
|
||||
|
Loading…
Reference in New Issue
Block a user