Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
知世而放
oceanbase
提交
50933732
O
oceanbase
项目概览
知世而放
/
oceanbase
与 Fork 源项目一致
Fork自
oceanbase / oceanbase
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
oceanbase
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
50933732
编写于
10月 14, 2022
作者:
N
nroskill
提交者:
wangzelin.wzl
10月 14, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[CP] [CP] [CP] [CP] fix link hashmap core
上级
392f40cc
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
65 addition
and
82 deletion
+65
-82
deps/oblib/src/lib/hash/ob_link_hashmap.h
deps/oblib/src/lib/hash/ob_link_hashmap.h
+13
-77
deps/oblib/unittest/lib/hash/test_link_hashmap.cpp
deps/oblib/unittest/lib/hash/test_link_hashmap.cpp
+52
-5
未找到文件。
deps/oblib/src/lib/hash/ob_link_hashmap.h
浏览文件 @
50933732
...
...
@@ -30,6 +30,12 @@ inline int32_t faa_if_positive(int32_t* addr, int32_t x)
return
ov
;
}
inline
static
ObQSync
&
get_global_link_hashmap_qsync
()
{
static
ObQSync
qsync
;
return
qsync
;
}
// DO NOT use me
class
BaseRefHandle
{
public:
...
...
@@ -65,42 +71,6 @@ protected:
uint64_t
qc_slot_
;
};
// fast read, slow del, delay reclaim Value/Node
class
TCRefHandle
final
:
public
BaseRefHandle
{
public:
typedef
RefNode
Node
;
explicit
TCRefHandle
(
RetireStation
&
retire_station
)
:
BaseRefHandle
(
retire_station
)
{}
void
born
(
Node
*
node
)
{
UNUSED
(
get_tcref
().
born
(
&
node
->
uref_
));
}
int32_t
end
(
Node
*
node
)
{
UNUSED
(
get_tcref
().
end
(
&
node
->
uref_
));
return
get_tcref
().
sync
(
&
node
->
uref_
);
}
bool
inc
(
Node
*
node
)
{
int32_t
ref
=
0
;
if
(
TCRef
::
REF_LIMIT
==
(
ref
=
get_tcref
().
inc_ref
(
&
node
->
uref_
)))
{
ref
=
ATOMIC_LOAD
(
&
node
->
uref_
);
}
return
ref
>
TCRef
::
REF_LIMIT
/
2
;
}
int32_t
dec
(
Node
*
node
)
{
return
get_tcref
().
dec_ref
(
&
node
->
uref_
);
}
private:
static
TCRef
&
get_tcref
()
{
static
TCRef
tcref
;
return
tcref
;
}
};
// balanced read/del performance, realtime reclaim Value, batch/delay reclaim Node.
class
RefHandle
final
:
public
BaseRefHandle
{
public:
...
...
@@ -125,45 +95,6 @@ public:
}
};
class
DummyRefHandle
final
:
public
BaseRefHandle
{
public:
typedef
RefNode
Node
;
enum
{
BORN_REF
=
1
};
explicit
DummyRefHandle
(
RetireStation
&
retire_station
)
:
BaseRefHandle
(
retire_station
)
{}
void
enter_critical
()
override
{}
void
leave_critical
()
override
{}
void
retire
(
Node
*
node
,
HazardList
&
reclaim_list
)
override
{
reclaim_list
.
push
(
&
node
->
retire_link_
);
}
void
purge
(
HazardList
&
reclaim_list
)
override
{
UNUSED
(
reclaim_list
);
}
void
born
(
Node
*
node
)
{
UNUSED
(
node
);
}
int32_t
end
(
Node
*
node
)
{
UNUSED
(
node
);
return
0
;
}
bool
inc
(
Node
*
node
)
{
UNUSED
(
node
);
return
true
;
}
int32_t
dec
(
Node
*
node
)
{
UNUSED
(
node
);
return
1
;
}
};
template
<
typename
Key
,
typename
Value
,
typename
AllocHandle
=
AllocHandle
<
Key
,
Value
>,
typename
RefHandle
=
RefHandle
,
int64_t
SHRINK_THRESHOLD
=
8
>
class
ObLinkHashMap
{
...
...
@@ -264,9 +195,13 @@ public:
void
purge
()
{
HazardList
reclaim_list
;
{
CriticalGuard
(
get_global_link_hashmap_qsync
());
get_retire_station
().
purge
(
reclaim_list
);
reclaim_nodes
(
reclaim_list
);
}
WaitQuiescent
(
get_global_link_hashmap_qsync
());
}
int64_t
count
()
const
{
return
hash_
.
count
();
...
...
@@ -344,6 +279,7 @@ public:
HazardList
reclaim_list
;
HashNode
*
node
=
CONTAINER_OF
(
hash_link
,
HashNode
,
hash_link_
);
end_uref
(
node
);
CriticalGuard
(
get_global_link_hashmap_qsync
());
ref_handle_
.
retire
(
node
,
reclaim_list
);
reclaim_nodes
(
reclaim_list
);
count_handle_
.
add
(
-
1
);
...
...
deps/oblib/unittest/lib/hash/test_link_hashmap.cpp
浏览文件 @
50933732
...
...
@@ -66,12 +66,21 @@ static uint64_t node_free CACHE_ALIGNED;
ObMemAttr
attr
(
1001
,
ObNewModIds
::
OB_MEMSTORE
);
static
int64_t
STEP
=
0
;
class
TestAllocHandle
{
typedef
LinkHashNode
<
HashKey
>
Node
;
public:
HashValue
*
alloc_value
()
TestAllocHandle
()
:
is_inited_
(
true
)
{}
~
TestAllocHandle
()
{
ATOMIC_STORE
(
&
is_inited_
,
false
);
}
HashValue
*
alloc_value
()
{
abort_unless
(
ATOMIC_LOAD
(
&
is_inited_
)
==
true
);
ATOMIC_INC
(
&
value_alloc
);
HashValue
*
value
=
(
HashValue
*
)
ob_malloc
(
sizeof
(
HashValue
),
attr
);
new
(
value
)
HashValue
();
...
...
@@ -79,12 +88,14 @@ public:
}
void
free_value
(
HashValue
*
val
)
{
abort_unless
(
ATOMIC_LOAD
(
&
is_inited_
)
==
true
);
ATOMIC_INC
(
&
value_free
);
val
->~
HashValue
();
ob_free
(
val
);
}
Node
*
alloc_node
(
HashValue
*
val
)
{
abort_unless
(
ATOMIC_LOAD
(
&
is_inited_
)
==
true
);
UNUSED
(
val
);
ATOMIC_INC
(
&
node_alloc
);
Node
*
node
=
(
Node
*
)
ob_malloc
(
sizeof
(
Node
),
attr
);
...
...
@@ -93,10 +104,18 @@ public:
}
void
free_node
(
Node
*
node
)
{
if
(
ATOMIC_LOAD
(
&
STEP
)
==
1
)
{
IGNORE_RETURN
ATOMIC_BCAS
(
&
STEP
,
1
,
2
);
usleep
(
1
*
1000
*
1000
);
}
abort_unless
(
ATOMIC_LOAD
(
&
is_inited_
)
==
true
);
ATOMIC_INC
(
&
node_free
);
node
->~
Node
();
ob_free
(
node
);
}
private:
bool
is_inited_
;
};
class
AtomicGetFunctor
{
...
...
@@ -118,9 +137,7 @@ static bool print(HashKey& key, HashValue* value)
return
true
;
}
// typedef ObLinkHashMap<HashKey, HashValue, TestAllocHandle> Hashmap;
typedef
ObLinkHashMap
<
HashKey
,
HashValue
,
TestAllocHandle
,
TCRefHandle
>
Hashmap
;
// typedef ObLinkHashMapWithHazardValue<HashKey, HashValue, TestAllocHandle> Hashmap;
typedef
ObLinkHashMap
<
HashKey
,
HashValue
,
TestAllocHandle
>
Hashmap
;
TEST
(
TestObHashMap
,
Feature
)
{
...
...
@@ -326,7 +343,37 @@ TEST(TestObHashMap, Stress)
EXPECT_EQ
(
node_free
,
node_alloc
);
}
int
main
(
int
argc
,
char
**
argv
)
TEST
(
TestObHashMap
,
Retire
)
{
std
::
thread
*
t
;
{
Hashmap
A
;
HashKey
key
;
HashValue
*
val_ptr
=
nullptr
;
EXPECT_EQ
(
OB_SUCCESS
,
A
.
init
());
key
.
v_
=
1
;
EXPECT_EQ
(
OB_SUCCESS
,
A
.
create
(
key
,
val_ptr
));
A
.
revert
(
val_ptr
);
EXPECT_EQ
(
OB_SUCCESS
,
A
.
del
(
key
));
ATOMIC_INC
(
&
STEP
);
t
=
new
std
::
thread
([
&
]()
{
usleep
(
10
*
1000
);
Hashmap
B
;
HashKey
key
;
EXPECT_EQ
(
OB_SUCCESS
,
B
.
init
());
key
.
v_
=
1
;
EXPECT_EQ
(
OB_SUCCESS
,
B
.
create
(
key
,
val_ptr
));
B
.
revert
(
val_ptr
);
});
while
(
ATOMIC_LOAD
(
&
STEP
)
!=
2
)
;
// ~A()
}
t
->
join
();
delete
t
;
}
int
main
(
int
argc
,
char
**
argv
)
{
testing
::
InitGoogleTest
(
&
argc
,
argv
);
oceanbase
::
common
::
ObLogger
::
get_logger
().
set_file_name
(
"test_link_hashmap.log"
,
true
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录