Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
FDD-WEB
oceanbase
提交
44d430d9
O
oceanbase
项目概览
FDD-WEB
/
oceanbase
与 Fork 源项目一致
Fork自
DP.peng / oceanbase
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
oceanbase
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
44d430d9
编写于
10月 31, 2022
作者:
O
obdev
提交者:
wangzelin.wzl
10月 31, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
delete unused code & sys parameters
上级
ae138ca6
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
0 addition
and
1601 deletion
+0
-1601
deps/oblib/src/lib/hash/ob_array_hash_map.h
deps/oblib/src/lib/hash/ob_array_hash_map.h
+0
-15
deps/oblib/src/lib/hash/ob_ext_iter_hashset.h
deps/oblib/src/lib/hash/ob_ext_iter_hashset.h
+0
-307
deps/oblib/src/lib/hash/ob_fixed_hash.h
deps/oblib/src/lib/hash/ob_fixed_hash.h
+0
-164
deps/oblib/src/lib/hash/ob_pre_alloc_link_hashmap.h
deps/oblib/src/lib/hash/ob_pre_alloc_link_hashmap.h
+0
-379
deps/oblib/unittest/lib/CMakeLists.txt
deps/oblib/unittest/lib/CMakeLists.txt
+0
-2
deps/oblib/unittest/lib/hash/test_ext_iter_hashset.cpp
deps/oblib/unittest/lib/hash/test_ext_iter_hashset.cpp
+0
-360
deps/oblib/unittest/lib/hash/test_pre_alloc_link_hashmap.cpp
deps/oblib/unittest/lib/hash/test_pre_alloc_link_hashmap.cpp
+0
-373
src/logservice/libobcdc/src/ob_log_trans_ctx.h
src/logservice/libobcdc/src/ob_log_trans_ctx.h
+0
-1
未找到文件。
deps/oblib/src/lib/hash/ob_array_hash_map.h
浏览文件 @
44d430d9
...
...
@@ -119,21 +119,6 @@ public:
size_
=
0
;
}
int
shrink_size
(
int64_t
size
)
{
LockGuard
guard
(
lock_
);
int
ret
=
OB_SUCCESS
;
if
(
size
<=
0
||
size
>
capacity_
)
{
ret
=
OB_INVALID_ARGUMENT
;
COMMON_LOG
(
WARN
,
"invalid argument"
,
K
(
size
),
K_
(
capacity
));
}
else
if
(
size
*
2
<=
capacity_
)
{
capacity_
=
size
*
2
;
}
else
{
capacity_
=
size
;
}
return
ret
;
}
void
print
()
const
{
COMMON_LOG
(
INFO
,
"array_hash dump begin:"
,
K
(
this
));
...
...
deps/oblib/src/lib/hash/ob_ext_iter_hashset.h
已删除
100644 → 0
浏览文件 @
ae138ca6
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#ifndef OCEANBASE_LIB_HASH_OB_EXT_ITER_HASHSET_H__
#define OCEANBASE_LIB_HASH_OB_EXT_ITER_HASHSET_H__
#include "lib/hash/ob_iteratable_hashset.h" // ObIteratableHashSet
#include "lib/utility/ob_print_utils.h"
namespace
oceanbase
{
namespace
common
{
namespace
hash
{
template
<
class
K
,
uint64_t
N
,
class
Allocator
>
class
ObExtIterHashSet
;
///////////////////////////////////// ObExtIterHashSet Iterator /////////////////////////////////////
template
<
class
HashSet
>
class
ObExtIterHashSetConstIterator
{
public:
typedef
typename
HashSet
::
const_key_ref_t
const_key_ref_t
;
typedef
ObExtIterHashSetConstIterator
<
HashSet
>
SelfType
;
typedef
typename
HashSet
::
HashSetBucket
BucketType
;
typedef
typename
HashSet
::
InnerHashSetIter
InnerIter
;
public:
ObExtIterHashSetConstIterator
(
const
HashSet
*
set
,
const
BucketType
*
bucket
,
const
InnerIter
&
iter
)
:
hash_set_
(
set
),
bucket_
(
bucket
),
iter_
(
iter
)
{}
ObExtIterHashSetConstIterator
(
const
SelfType
&
other
)
:
hash_set_
(
other
.
hash_set_
),
bucket_
(
other
.
bucket_
),
iter_
(
other
.
iter_
)
{}
~
ObExtIterHashSetConstIterator
()
{}
public:
ObExtIterHashSetConstIterator
&
operator
=
(
const
SelfType
&
other
)
{
if
(
this
!=
&
other
)
{
hash_set_
=
other
.
hash_set_
;
bucket_
=
other
.
bucket_
;
iter_
=
other
.
iter_
;
}
return
*
this
;
}
ObExtIterHashSetConstIterator
&
operator
=
(
SelfType
&&
other
)
=
default
;
bool
operator
==
(
const
SelfType
&
other
)
const
{
return
other
.
hash_set_
==
hash_set_
&&
other
.
bucket_
==
bucket_
&&
other
.
iter_
==
iter_
;
}
bool
operator
!=
(
const
SelfType
&
other
)
const
{
return
other
.
hash_set_
!=
hash_set_
||
other
.
bucket_
!=
bucket_
||
other
.
iter_
!=
iter_
;
}
SelfType
&
operator
++
()
{
if
(
NULL
==
hash_set_
||
NULL
==
bucket_
)
{
LIB_LOG
(
ERROR
,
"err hash set, iter or bucket"
,
K
(
hash_set_
),
K
(
bucket_
));
}
else
{
// if current bucket is not null, fetch next one.
if
(
iter_
!=
bucket_
->
hash_set_
.
end
())
{
++
iter_
;
}
// if reach end of current bucket, step to the next bucket.
if
(
iter_
==
bucket_
->
hash_set_
.
end
()
&&
NULL
!=
bucket_
->
next_
)
{
bucket_
=
bucket_
->
next_
;
iter_
=
bucket_
->
hash_set_
.
begin
();
}
}
return
*
this
;
}
const_key_ref_t
operator
*
()
const
{
if
(
NULL
==
hash_set_
||
NULL
==
bucket_
)
{
LIB_LOG
(
ERROR
,
"err hash set, iter or bucket"
,
K
(
hash_set_
),
K
(
bucket_
));
}
return
*
iter_
;
}
private:
const
HashSet
*
hash_set_
;
const
BucketType
*
bucket_
;
InnerIter
iter_
;
};
///////////////////////////////////// ObExtIterHashSet /////////////////////////////////////
template
<
class
K
,
uint64_t
N
=
1031
,
class
Allocator
=
ObIAllocator
>
class
ObExtIterHashSet
{
public:
typedef
const
K
&
const_key_ref_t
;
typedef
ObIteratableHashSet
<
K
,
N
>
BaseHashSet
;
typedef
ObExtIterHashSet
<
K
,
N
,
Allocator
>
SelfType
;
typedef
ObExtIterHashSetConstIterator
<
SelfType
>
const_iterator_t
;
typedef
typename
BaseHashSet
::
const_iterator_t
InnerHashSetIter
;
struct
HashSetBucket
{
BaseHashSet
hash_set_
;
HashSetBucket
*
next_
;
HashSetBucket
()
:
hash_set_
(),
next_
(
NULL
)
{}
~
HashSetBucket
()
{}
void
reset
()
{
hash_set_
.
reset
();
next_
=
NULL
;
}
};
public:
explicit
ObExtIterHashSet
(
Allocator
&
allocator
);
virtual
~
ObExtIterHashSet
();
public:
/**
* @retval OB_SUCCESS insert successfully
* @retval OB_HASH_EXIST key exists
* @retval other ret failed
*/
int
set_refactored
(
const
K
&
key
);
/**
* @retval OB_HASH_EXIST key exists
* @retval OB_HASH_NOT_EXIST key not exists
*/
int
exist_refactored
(
const
K
&
key
)
const
{
return
is_exist_
(
key
)
?
OB_HASH_EXIST
:
OB_HASH_NOT_EXIST
;
}
void
reset
();
void
clear
()
{
reset
();
}
const_iterator_t
begin
()
const
{
return
const_iterator_t
(
this
,
&
buckets_
,
buckets_
.
hash_set_
.
begin
());
}
const_iterator_t
end
()
const
{
return
const_iterator_t
(
this
,
buckets_tail_
,
buckets_tail_
->
hash_set_
.
end
());
}
int64_t
count
()
const
{
return
count_
;
}
public:
DECLARE_TO_STRING
;
private:
bool
is_exist_
(
const
K
&
key
)
const
;
bool
is_full_
()
const
{
return
count_
>=
bucket_num_
*
static_cast
<
int64_t
>
(
N
);
}
int
add_bucket_
();
private:
int64_t
count_
;
// count of object
int64_t
bucket_num_
;
// count of bucket
Allocator
&
allocator_
;
// allocator
HashSetBucket
buckets_
;
// bucket lists
HashSetBucket
*
buckets_tail_
;
// bucket lists tail
private:
template
<
class
HashSet
>
friend
class
ObExtIterHashSetConstIterator
;
private:
DISALLOW_COPY_AND_ASSIGN
(
ObExtIterHashSet
);
};
template
<
class
K
,
uint64_t
N
,
class
Allocator
>
ObExtIterHashSet
<
K
,
N
,
Allocator
>::
ObExtIterHashSet
(
Allocator
&
allocator
)
:
count_
(
0
),
bucket_num_
(
1
),
allocator_
(
allocator
),
buckets_
(),
buckets_tail_
(
&
buckets_
)
{}
template
<
class
K
,
uint64_t
N
,
class
Allocator
>
ObExtIterHashSet
<
K
,
N
,
Allocator
>::~
ObExtIterHashSet
()
{
reset
();
}
template
<
class
K
,
uint64_t
N
,
class
Allocator
>
int
ObExtIterHashSet
<
K
,
N
,
Allocator
>::
set_refactored
(
const
K
&
key
)
{
int
ret
=
OB_SUCCESS
;
bool
exist
=
is_exist_
(
key
);
if
(
exist
)
{
ret
=
OB_HASH_EXIST
;
}
else
if
(
is_full_
()
&&
OB_FAIL
(
add_bucket_
()))
{
LIB_LOG
(
WARN
,
"add_bucket_ fail"
,
K
(
ret
));
}
else
{
// keep inserting successful
if
(
NULL
==
buckets_tail_
)
{
ret
=
OB_ERR_UNEXPECTED
;
LIB_LOG
(
WARN
,
"err bucket tail"
,
K
(
ret
));
}
else
if
(
OB_FAIL
(
buckets_tail_
->
hash_set_
.
set_refactored
(
key
)))
{
LIB_LOG
(
WARN
,
"set key into hash set fail"
,
K
(
ret
));
}
else
{
count_
++
;
}
}
return
ret
;
}
template
<
class
K
,
uint64_t
N
,
class
Allocator
>
bool
ObExtIterHashSet
<
K
,
N
,
Allocator
>::
is_exist_
(
const
K
&
key
)
const
{
bool
exist
=
false
;
const
HashSetBucket
*
item
=
&
buckets_
;
while
(
!
exist
&&
NULL
!=
item
)
{
if
(
OB_HASH_EXIST
==
item
->
hash_set_
.
exist_refactored
(
key
))
{
exist
=
true
;
break
;
}
else
{
item
=
item
->
next_
;
}
}
return
exist
;
}
template
<
class
K
,
uint64_t
N
,
class
Allocator
>
int
ObExtIterHashSet
<
K
,
N
,
Allocator
>::
add_bucket_
()
{
int
ret
=
OB_SUCCESS
;
HashSetBucket
*
bucket
=
(
HashSetBucket
*
)
allocator_
.
alloc
(
sizeof
(
HashSetBucket
));
if
(
NULL
==
bucket
)
{
LIB_LOG
(
WARN
,
"allocate memory for bucket fail"
,
"bucket_size"
,
sizeof
(
HashSetBucket
));
ret
=
OB_ALLOCATE_MEMORY_FAILED
;
}
else
{
new
(
bucket
)
HashSetBucket
();
bucket
->
next_
=
NULL
;
buckets_tail_
->
next_
=
bucket
;
buckets_tail_
=
bucket
;
bucket_num_
++
;
LIB_LOG
(
DEBUG
,
"add bucket"
,
K
(
bucket_num_
),
K
(
count_
),
K
(
bucket
));
}
return
ret
;
}
template
<
class
K
,
uint64_t
N
,
class
Allocator
>
void
ObExtIterHashSet
<
K
,
N
,
Allocator
>::
reset
()
{
HashSetBucket
*
bucket
=
buckets_
.
next_
;
while
(
NULL
!=
bucket
)
{
HashSetBucket
*
next
=
bucket
->
next_
;
bucket
->~
HashSetBucket
();
allocator_
.
free
((
void
*
)
bucket
);
bucket
=
next
;
}
bucket
=
NULL
;
buckets_
.
reset
();
buckets_tail_
=
&
buckets_
;
bucket_num_
=
1
;
count_
=
0
;
}
template
<
class
K
,
uint64_t
N
,
class
Allocator
>
int64_t
ObExtIterHashSet
<
K
,
N
,
Allocator
>::
to_string
(
char
*
buf
,
const
int64_t
buf_len
)
const
{
int64_t
pos
=
0
;
J_ARRAY_START
();
const_iterator_t
beg
=
begin
();
for
(
const_iterator_t
it
=
beg
;
it
!=
end
();
++
it
)
{
if
(
it
!=
beg
)
{
J_COMMA
();
}
BUF_PRINTO
(
*
it
);
}
J_ARRAY_END
();
return
pos
;
}
}
// namespace hash
}
// namespace common
}
// namespace oceanbase
#endif
deps/oblib/src/lib/hash/ob_fixed_hash.h
已删除
100644 → 0
浏览文件 @
ae138ca6
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#ifndef OCEANBASE_HASH_OB_FIXED_HASH_H_
#define OCEANBASE_HASH_OB_FIXED_HASH_H_
#include "lib/ob_define.h"
#include "lib/queue/ob_link.h"
#include "lib/hash/ob_hash.h"
namespace
oceanbase
{
namespace
common
{
template
<
typename
key_t
>
class
FixedHash
{
public:
typedef
ObLink
Link
;
struct
node_t
:
public
Link
{
node_t
()
:
hash_
(
0
),
key_
()
{}
explicit
node_t
(
key_t
key
)
:
key_
(
key
)
{
hash_
=
hash_map_calc_hash
(
key_
);
}
~
node_t
()
{}
static
uint64_t
hash_map_calc_hash
(
key_t
key
)
{
return
calc_hash
(
key
)
|
1
;
}
node_t
*
set
(
key_t
key
)
{
hash_
=
hash_map_calc_hash
(
key
);
key_
=
key
;
return
this
;
}
bool
is_dummy_node
()
{
return
0
==
(
hash_
&
1
);
}
int
compare
(
node_t
*
that
)
{
int
ret
=
0
;
if
(
this
->
hash_
>
that
->
hash_
)
{
ret
=
1
;
}
else
if
(
this
->
hash_
<
that
->
hash_
)
{
ret
=
-
1
;
}
else
if
(
this
->
is_dummy_node
())
{
ret
=
0
;
}
else
{
ret
=
common
::
compare
(
this
->
key_
,
that
->
key_
);
}
return
ret
;
}
node_t
*
set_as_bucket
(
uint64_t
idx
)
{
hash_
=
bitrev
(
idx
);
return
this
;
}
uint64_t
get_spk
()
{
return
bitrev
(
hash_
);
}
uint64_t
hash_
;
key_t
key_
;
};
FixedHash
(
void
*
buf
,
int64_t
size
)
:
nodes_
((
node_t
*
)
buf
),
limit_
(
last2n
(
size
/
sizeof
(
node_t
)))
{
init_buckets
(
nodes_
,
limit_
);
}
~
FixedHash
()
{}
int
insert
(
key_t
key
,
node_t
*
node
)
{
node_t
key_node
(
key
);
return
ol_insert
(
get_pre
(
&
key_node
),
node
->
set
(
key
));
}
int
del
(
key_t
key
,
node_t
*&
node
)
{
node_t
key_node
(
key
);
return
ol_del
(
get_pre
(
&
key_node
),
&
key_node
,
node
);
}
int
get
(
key_t
key
,
node_t
*&
node
)
{
node_t
key_node
(
key
);
return
ol_get
(
get_pre
(
&
key_node
),
&
key_node
,
node
);
}
node_t
*
next
(
node_t
*
node
)
{
while
(
NULL
!=
(
node
=
next_node
(
node
))
&&
node
->
is_dummy_node
())
;
return
node
;
}
private:
node_t
*
next_node
(
node_t
*
node
)
{
node_t
*
next
=
NULL
;
if
(
NULL
==
node
)
{
next
=
nodes_
;
}
else
if
(
is_last_bit_set
((
uint64_t
)(
next
=
(
node_t
*
)
ATOMIC_LOAD
(
&
node
->
next_
))))
{
next
=
get_pre
(
node
);
}
return
next
;
}
static
uint64_t
last2n
(
const
uint64_t
x
)
{
return
x
==
0
?
0
:
(
1UL
<<
63
)
>>
(
__builtin_clzll
(
x
));
}
static
uint64_t
bitrev
(
uint64_t
x
)
{
x
=
(((
x
&
0xaaaaaaaaaaaaaaaaUL
)
>>
1
)
|
((
x
&
0x5555555555555555UL
)
<<
1
));
x
=
(((
x
&
0xccccccccccccccccUL
)
>>
2
)
|
((
x
&
0x3333333333333333UL
)
<<
2
));
x
=
(((
x
&
0xf0f0f0f0f0f0f0f0UL
)
>>
4
)
|
((
x
&
0x0f0f0f0f0f0f0f0fUL
)
<<
4
));
x
=
(((
x
&
0xff00ff00ff00ff00UL
)
>>
8
)
|
((
x
&
0x00ff00ff00ff00ffUL
)
<<
8
));
x
=
(((
x
&
0xffff0000ffff0000UL
)
>>
16
)
|
((
x
&
0x0000ffff0000ffff
)
<<
16
));
return
((
x
>>
32
)
|
(
x
<<
32
));
}
static
uint64_t
get_idx
(
uint64_t
spk
,
uint64_t
bcnt
)
{
return
bcnt
==
0
?
0
:
(
spk
&
(
bcnt
-
1
));
}
node_t
*
get_pre
(
node_t
*
key_node
)
{
return
nodes_
+
get_idx
(
key_node
->
get_spk
(),
limit_
);
}
static
uint64_t
get_bucket_pre_idx
(
uint64_t
idx
)
{
return
idx
&
~
last2n
(
idx
);
}
static
int
init_buckets
(
node_t
*
nodes
,
int64_t
limit
)
{
int
err
=
0
;
new
(
nodes
)
node_t
[
limit
];
nodes
[
0
].
set_as_bucket
(
0
);
for
(
int64_t
i
=
1
;
0
==
err
&&
i
<
limit
;
i
++
)
{
node_t
*
node
=
nodes
+
i
;
node
->
set_as_bucket
(
i
);
err
=
ol_insert
(
nodes
+
get_bucket_pre_idx
(
i
),
node
);
}
return
err
;
}
private:
node_t
*
nodes_
;
int64_t
limit_
;
};
};
// end namespace common
};
// end namespace oceanbase
#endif
/* OCEANBASE_HASH_OB_FIXED_HASH_H_ */
deps/oblib/src/lib/hash/ob_pre_alloc_link_hashmap.h
已删除
100644 → 0
浏览文件 @
ae138ca6
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#ifndef SRC_LIBRARY_SRC_LIB_HASH_OB_MEMLESS_LINK_HASHMAP_H_
#define SRC_LIBRARY_SRC_LIB_HASH_OB_MEMLESS_LINK_HASHMAP_H_
#include "lib/ob_define.h"
#include "lib/hash/ob_hashutils.h"
#include "lib/atomic/ob_atomic.h"
#include "lib/utility/ob_print_utils.h"
#include "lib/container/ob_array.h"
#include "lib/lock/ob_bucket_lock.h"
namespace
oceanbase
{
namespace
common
{
namespace
hash
{
// ObMemLessLinkHashMap is convenient for reuse of node.
// there is a simple allocator in the map.
// memory of node should be pre-allocated.
// use of storage of table and meta block.
template
<
class
KEY
,
class
ITEM
>
struct
ObPreAllocLinkHashNode
{
explicit
ObPreAllocLinkHashNode
(
ITEM
&
item
)
:
item_
(
item
)
{}
virtual
~
ObPreAllocLinkHashNode
()
{
}
virtual
OB_INLINE
bool
equals
(
const
ObPreAllocLinkHashNode
&
node
)
{
return
equals
(
node
.
get_key
());
}
virtual
OB_INLINE
bool
equals
(
const
KEY
&
key
)
{
return
get_key
()
==
key
;
}
//derived class should override static uint64_t hash(const uint64_t &key);
virtual
const
KEY
&
get_key
()
const
=
0
;
VIRTUAL_TO_STRING_KV
(
KP
(
this
),
K_
(
item
));
ITEM
&
item_
;
};
template
<
class
KEY
,
class
ITEM
,
class
NODE
,
class
ITEM_PROTECTOR
>
class
ObPreAllocLinkHashMap
{
public:
class
ForeachFunctor
{
public:
virtual
int
operator
()(
ITEM
&
item
,
bool
&
is_full
)
=
0
;
};
class
EraseChecker
{
public:
virtual
int
operator
()(
ITEM
&
item
)
=
0
;
};
class
GetFunctor
{
public:
virtual
int
operator
()(
ITEM
&
item
)
=
0
;
};
class
Iterator
{
public:
explicit
Iterator
(
ObPreAllocLinkHashMap
&
map
)
:
items_
(),
item_idx_
(
0
),
bucket_pos_
(
0
),
map_
(
map
)
{
}
virtual
~
Iterator
()
{
release_items
();
}
int
get_next
(
ITEM
*&
item
)
{
int
ret
=
OB_SUCCESS
;
item
=
NULL
;
while
(
OB_SUCC
(
ret
))
{
if
(
item_idx_
<
items_
.
count
())
{
item
=
items_
.
at
(
item_idx_
);
++
item_idx_
;
break
;
}
else
if
(
bucket_pos_
>=
map_
.
buckets_count_
)
{
ret
=
OB_ITER_END
;
}
else
{
item_idx_
=
0
;
release_items
();
ObBucketRLockGuard
guard
(
map_
.
buckets_lock_
,
bucket_pos_
);
if
(
NULL
!=
map_
.
buckets_
[
bucket_pos_
])
{
NODE
*
node
=
map_
.
buckets_
[
bucket_pos_
];
while
(
OB_SUCC
(
ret
)
&&
NULL
!=
node
)
{
ITEM_PROTECTOR
::
hold
(
node
->
item_
);
if
(
OB_FAIL
(
items_
.
push_back
(
&
node
->
item_
)))
{
COMMON_LOG
(
WARN
,
"Failed to add item"
,
K
(
ret
));
ITEM_PROTECTOR
::
release
(
node
->
item_
);
}
else
{
node
=
node
->
next_
;
}
}
}
++
bucket_pos_
;
}
}
return
ret
;
}
private:
void
release_items
()
{
for
(
int64_t
i
=
0
;
i
<
items_
.
count
();
++
i
)
{
ITEM_PROTECTOR
::
release
(
*
items_
.
at
(
i
));
}
items_
.
reuse
();
}
common
::
ObArray
<
ITEM
*>
items_
;
int64_t
item_idx_
;
int64_t
bucket_pos_
;
ObPreAllocLinkHashMap
&
map_
;
DISALLOW_COPY_AND_ASSIGN
(
Iterator
);
};
ObPreAllocLinkHashMap
()
:
is_inited_
(
false
),
buckets_lock_
(),
count_
(),
buckets_
(
NULL
),
buckets_count_
(
1
),
allocator_
()
{
}
virtual
~
ObPreAllocLinkHashMap
()
{
destroy
();
}
void
destroy
()
{
for
(
uint64_t
bucket_pos
=
0
;
NULL
!=
buckets_
&&
bucket_pos
<
buckets_count_
;
++
bucket_pos
)
{
ObBucketRLockGuard
bucket_guard
(
buckets_lock_
,
bucket_pos
);
NODE
*
cur
=
buckets_
[
bucket_pos
];
NODE
*
next
=
NULL
;
while
(
NULL
!=
cur
)
{
next
=
cur
->
next_
;
free_node
(
cur
);
cur
=
next
;
}
}
is_inited_
=
false
;
buckets_lock_
.
destroy
();
count_
=
0
;
ob_free
(
buckets_
);
buckets_
=
NULL
;
buckets_count_
=
1
;
}
int
init
(
const
int64_t
buckets_count
,
const
uint32_t
latch_id
,
const
lib
::
ObLabel
&
label
)
{
int
ret
=
OB_SUCCESS
;
ObMemAttr
mem_attr
(
OB_SERVER_TENANT_ID
,
label
);
const
int64_t
real_buckets_count
=
hash
::
cal_next_prime
(
buckets_count
);
if
(
is_inited_
)
{
ret
=
OB_INIT_TWICE
;
COMMON_LOG
(
WARN
,
"cannot init twice"
,
K
(
ret
));
}
else
if
(
real_buckets_count
<=
0
||
buckets_count
<=
0
)
{
ret
=
OB_INVALID_ARGUMENT
;
COMMON_LOG
(
WARN
,
"invalid bucket count"
,
K
(
ret
),
K
(
real_buckets_count
),
K
(
buckets_count
));
}
else
if
(
OB_FAIL
(
buckets_lock_
.
init
(
real_buckets_count
,
latch_id
,
label
)))
{
COMMON_LOG
(
WARN
,
"failed to init buckets lock"
,
K
(
ret
));
}
else
if
(
OB_ISNULL
(
buckets_
=
reinterpret_cast
<
NODE
**>
(
ob_malloc
(
sizeof
(
NODE
*
)
*
real_buckets_count
,
mem_attr
))))
{
ret
=
OB_ALLOCATE_MEMORY_FAILED
;
COMMON_LOG
(
WARN
,
"failed to alloc buckets"
,
K
(
ret
),
K
(
real_buckets_count
));
}
else
{
allocator_
.
set_label
(
label
);
MEMSET
(
buckets_
,
0
,
sizeof
(
NODE
*
)
*
real_buckets_count
);
COMMON_LOG
(
INFO
,
"init hashmap"
,
K
(
buckets_count
),
K
(
real_buckets_count
),
"buf_size"
,
sizeof
(
NODE
*
)
*
real_buckets_count
,
K
(
latch_id
),
K
(
label
));
count_
=
0
;
buckets_count_
=
real_buckets_count
;
is_inited_
=
true
;
}
return
ret
;
}
uint64_t
get_count
()
const
{
return
ATOMIC_LOAD
(
&
count_
);
}
uint64_t
get_buckets_count
()
const
{
return
buckets_count_
;
}
NODE
*
alloc_node
(
ITEM
&
item
)
{
return
allocator_
.
alloc
(
item
);
}
void
free_node
(
NODE
*&
node
)
{
allocator_
.
free
(
node
);
node
=
NULL
;
}
int
put
(
NODE
&
node
)
{
int
ret
=
OB_SUCCESS
;
if
(
!
is_inited_
)
{
ret
=
OB_NOT_INIT
;
COMMON_LOG
(
WARN
,
"not inited"
,
K
(
ret
));
}
else
{
const
uint64_t
bucket_pos
=
NODE
::
hash
(
node
.
get_key
())
%
buckets_count_
;
ObBucketWLockGuard
bucket_guard
(
buckets_lock_
,
bucket_pos
);
NODE
*
cur
=
buckets_
[
bucket_pos
];
while
(
NULL
!=
cur
)
{
if
(
cur
->
equals
(
node
))
{
break
;
}
else
{
cur
=
cur
->
next_
;
}
}
if
(
NULL
!=
cur
)
{
ret
=
OB_HASH_EXIST
;
}
else
{
node
.
next_
=
buckets_
[
bucket_pos
];
buckets_
[
bucket_pos
]
=
&
node
;
ATOMIC_INC
(
&
count_
);
}
}
return
ret
;
}
// delete node which has common key
int
erase
(
const
KEY
&
key
,
ITEM
*&
del_item
,
EraseChecker
*
checker
=
NULL
)
{
int
ret
=
OB_SUCCESS
;
del_item
=
NULL
;
if
(
!
is_inited_
)
{
ret
=
OB_NOT_INIT
;
COMMON_LOG
(
WARN
,
"not inited"
,
K
(
ret
));
}
else
{
const
uint64_t
bucket_pos
=
NODE
::
hash
(
key
)
%
buckets_count_
;
ObBucketWLockGuard
bucket_guard
(
buckets_lock_
,
bucket_pos
);
NODE
*
cur
=
buckets_
[
bucket_pos
];
NODE
*
prev
=
NULL
;
while
(
NULL
!=
cur
)
{
if
(
cur
->
equals
(
key
))
{
break
;
}
else
{
prev
=
cur
;
cur
=
cur
->
next_
;
}
}
if
(
NULL
==
cur
)
{
ret
=
OB_HASH_NOT_EXIST
;
}
else
if
(
NULL
!=
checker
&&
OB_FAIL
((
*
checker
)(
cur
->
item_
)))
{
// cannot erase now
}
else
{
if
(
NULL
!=
prev
)
{
prev
->
next_
=
cur
->
next_
;
}
else
{
buckets_
[
bucket_pos
]
=
cur
->
next_
;
}
cur
->
next_
=
NULL
;
del_item
=
&
cur
->
item_
;
free_node
(
cur
);
ATOMIC_DEC
(
&
count_
);
}
}
return
ret
;
}
// delete node which has common key
int
erase
(
const
KEY
&
key
)
{
int
ret
=
OB_SUCCESS
;
ITEM
*
del_item
=
NULL
;
if
(
OB_FAIL
(
erase
(
key
,
del_item
)))
{
COMMON_LOG
(
WARN
,
"failed to erase ndoe"
,
K
(
ret
),
K
(
key
));
}
return
ret
;
}
int
exist
(
const
KEY
&
key
)
{
ITEM
*
item
=
NULL
;
int
ret
=
get
(
key
,
item
);
if
(
OB_SUCCESS
==
ret
)
{
ret
=
OB_HASH_EXIST
;
}
return
ret
;
}
int
get
(
const
KEY
&
key
,
GetFunctor
&
functor
)
{
ITEM
*
item
=
NULL
;
return
get
(
key
,
item
,
&
functor
);
}
int
get
(
const
KEY
&
key
,
ITEM
*&
item
,
GetFunctor
*
functor
=
NULL
)
{
int
ret
=
OB_SUCCESS
;
item
=
NULL
;
if
(
!
is_inited_
)
{
ret
=
OB_NOT_INIT
;
COMMON_LOG
(
WARN
,
"not inited"
,
K
(
ret
));
}
else
{
const
uint64_t
bucket_pos
=
NODE
::
hash
(
key
)
%
buckets_count_
;
ObBucketRLockGuard
bucket_guard
(
buckets_lock_
,
bucket_pos
);
NODE
*
cur
=
buckets_
[
bucket_pos
];
while
(
NULL
!=
cur
)
{
if
(
cur
->
equals
(
key
))
{
break
;
}
else
{
cur
=
cur
->
next_
;
}
}
if
(
NULL
==
cur
)
{
ret
=
OB_HASH_NOT_EXIST
;
}
else
if
(
NULL
!=
functor
&&
OB_FAIL
((
*
functor
)(
cur
->
item_
)))
{
COMMON_LOG
(
WARN
,
"failed to do get functor"
,
K
(
ret
),
K
(
*
cur
));
}
else
{
item
=
&
cur
->
item_
;
}
}
return
ret
;
}
int
foreach
(
ForeachFunctor
&
functor
)
{
int
ret
=
OB_SUCCESS
;
bool
is_full
=
false
;
if
(
!
is_inited_
)
{
ret
=
OB_NOT_INIT
;
COMMON_LOG
(
WARN
,
"not inited"
,
K
(
ret
));
}
else
{
for
(
uint64_t
bucket_pos
=
0
;
OB_SUCC
(
ret
)
&&
!
is_full
&&
bucket_pos
<
buckets_count_
;
++
bucket_pos
)
{
ObBucketRLockGuard
bucket_guard
(
buckets_lock_
,
bucket_pos
);
NODE
*
cur
=
buckets_
[
bucket_pos
];
while
(
OB_SUCC
(
ret
)
&&
NULL
!=
cur
&&
!
is_full
)
{
if
(
OB_FAIL
(
functor
(
cur
->
item_
,
is_full
)))
{
COMMON_LOG
(
WARN
,
"failed to do foreach functor"
,
K
(
ret
));
}
else
{
cur
=
cur
->
next_
;
}
}
}
}
return
ret
;
}
private:
bool
is_inited_
;
mutable
common
::
ObBucketLock
buckets_lock_
;
uint64_t
count_
;
NODE
**
buckets_
;
uint64_t
buckets_count_
;
SimpleAllocer
<
NODE
>
allocator_
;
DISALLOW_COPY_AND_ASSIGN
(
ObPreAllocLinkHashMap
);
};
}
// hash
}
// common
}
// oceanbase
#endif
/* SRC_LIBRARY_SRC_LIB_HASH_OB_MEMLESS_LINK_HASHMAP_H_ */
deps/oblib/unittest/lib/CMakeLists.txt
浏览文件 @
44d430d9
...
...
@@ -47,7 +47,6 @@ oblib_addtest(hash/test_array_index_hash_set.cpp)
oblib_addtest
(
hash/test_build_in_hashmap.cpp
)
oblib_addtest
(
hash/test_concurrent_hash_map.cpp
)
oblib_addtest
(
hash/test_cuckoo_hashmap.cpp
)
oblib_addtest
(
hash/test_ext_iter_hashset.cpp
)
oblib_addtest
(
hash/test_hashmap.cpp
)
oblib_addtest
(
hash/test_fnv_hash.cpp
)
oblib_addtest
(
hash/test_hashset.cpp
)
...
...
@@ -57,7 +56,6 @@ oblib_addtest(hash/test_link_hashmap.cpp)
oblib_addtest
(
hash/test_linear_hash_map.cpp
)
oblib_addtest
(
hash/test_placement_hashset.cpp
)
oblib_addtest
(
hash/test_pointer_hashmap.cpp
)
oblib_addtest
(
hash/test_pre_alloc_link_hashmap.cpp
)
oblib_addtest
(
hash/test_simpleallocer.cpp
)
oblib_addtest
(
json/test_json_print_utils.cpp
)
oblib_addtest
(
json/test_yson.cpp
)
...
...
deps/oblib/unittest/lib/hash/test_ext_iter_hashset.cpp
已删除
100644 → 0
浏览文件 @
ae138ca6
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#include "lib/hash/ob_ext_iter_hashset.h"
#include "lib/allocator/ob_malloc.h"
#include <gtest/gtest.h>
using
namespace
oceanbase
::
common
;
using
namespace
oceanbase
::
common
::
hash
;
class
ObExtIterHashSetTest
:
public
::
testing
::
Test
{
public:
ObExtIterHashSetTest
();
virtual
~
ObExtIterHashSetTest
();
virtual
void
SetUp
();
virtual
void
TearDown
();
public:
ObArenaAllocator
allocator_
;
private:
// disallow copy
ObExtIterHashSetTest
(
const
ObExtIterHashSetTest
&
other
);
ObExtIterHashSetTest
&
operator
=
(
const
ObExtIterHashSetTest
&
other
);
protected:
// data members
};
ObExtIterHashSetTest
::
ObExtIterHashSetTest
()
:
allocator_
(
ObModIds
::
TEST
)
{
}
ObExtIterHashSetTest
::~
ObExtIterHashSetTest
()
{
}
void
ObExtIterHashSetTest
::
SetUp
()
{
}
void
ObExtIterHashSetTest
::
TearDown
()
{
allocator_
.
reset
();
}
TEST_F
(
ObExtIterHashSetTest
,
basic_test
)
{
static
const
int64_t
N
=
256
;
static
const
int64_t
BUCKET_NUM
=
8
;
ObExtIterHashSet
<
int64_t
,
N
>
set
(
allocator_
);
for
(
int
round
=
0
;
round
<
5
;
++
round
)
{
ASSERT_EQ
(
0
,
set
.
count
());
ASSERT_EQ
(
set
.
begin
(),
set
.
end
());
ASSERT_EQ
(
++
(
set
.
begin
()),
set
.
end
());
// insert data
for
(
int64_t
index
=
0
;
index
<
N
*
BUCKET_NUM
;
index
++
)
{
int64_t
value
=
index
+
1
;
ASSERT_EQ
(
OB_HASH_NOT_EXIST
,
set
.
exist_refactored
(
value
));
ASSERT_EQ
(
OB_SUCCESS
,
set
.
set_refactored
(
value
));
ASSERT_EQ
(
OB_HASH_EXIST
,
set
.
exist_refactored
(
value
));
ASSERT_EQ
(
index
+
1
,
set
.
count
());
}
// verify data
ObExtIterHashSet
<
int64_t
,
N
>::
const_iterator_t
it
=
set
.
begin
();
for
(
int64_t
value
=
1
;
it
!=
set
.
end
();
++
it
,
value
++
)
{
ASSERT_EQ
(
value
,
*
it
);
}
set
.
clear
();
ASSERT_EQ
(
0
,
set
.
count
());
}
}
TEST_F
(
ObExtIterHashSetTest
,
single_N
)
{
ObExtIterHashSet
<
int64_t
,
1
>
hashset
(
allocator_
);
ObExtIterHashSet
<
int64_t
,
1
>::
const_iterator_t
iter
=
hashset
.
begin
();
ASSERT_EQ
(
iter
,
hashset
.
end
());
ASSERT_EQ
(
++
iter
,
hashset
.
end
());
ASSERT_EQ
(
0
,
hashset
.
count
());
ASSERT_EQ
(
OB_SUCCESS
,
hashset
.
set_refactored
(
1
));
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
set_refactored
(
1
));
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
exist_refactored
(
1
));
ASSERT_EQ
(
1
,
hashset
.
count
());
ASSERT_EQ
(
OB_SUCCESS
,
hashset
.
set_refactored
(
2
));
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
exist_refactored
(
2
));
ASSERT_EQ
(
2
,
hashset
.
count
());
iter
=
hashset
.
begin
();
ASSERT_NE
(
iter
,
hashset
.
end
());
ASSERT_EQ
(
1
,
*
iter
);
ASSERT_NE
(
++
iter
,
hashset
.
end
());
ASSERT_EQ
(
2
,
*
iter
);
ASSERT_EQ
(
++
iter
,
hashset
.
end
());
ASSERT_EQ
(
++
iter
,
hashset
.
end
());
}
TEST_F
(
ObExtIterHashSetTest
,
many_N_single_bucket
)
{
const
uint64_t
N
=
10345
;
int64_t
value
=
0
;
ObExtIterHashSet
<
int64_t
,
N
>
hashset
(
allocator_
);
ObExtIterHashSet
<
int64_t
,
N
>::
const_iterator_t
iter
=
hashset
.
begin
();
ASSERT_EQ
(
iter
,
hashset
.
end
());
ASSERT_EQ
(
++
iter
,
hashset
.
end
());
for
(
uint64_t
i
=
0
;
i
<
N
;
i
++
)
{
ASSERT_EQ
(
OB_HASH_NOT_EXIST
,
hashset
.
exist_refactored
(
i
));
}
for
(
uint64_t
i
=
0
;
i
<
N
;
i
++
)
{
ASSERT_EQ
(
OB_SUCCESS
,
hashset
.
set_refactored
(
i
));
}
ASSERT_EQ
(
OB_SUCCESS
,
hashset
.
set_refactored
(
N
));
for
(
uint64_t
i
=
0
;
i
<
N
;
i
++
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
exist_refactored
(
i
));
}
for
(
uint64_t
i
=
0
;
i
<
N
;
i
++
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
set_refactored
(
i
));
}
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
set_refactored
(
N
));
for
(
uint64_t
i
=
0
;
i
<
N
;
i
++
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
exist_refactored
(
i
));
}
ASSERT_EQ
(
N
+
1
,
hashset
.
count
());
for
(
value
=
0
,
iter
=
hashset
.
begin
();
iter
!=
hashset
.
end
();
++
iter
,
value
++
)
{
ASSERT_EQ
(
value
,
*
iter
);
}
hashset
.
clear
();
iter
=
hashset
.
begin
();
ASSERT_EQ
(
iter
,
hashset
.
end
());
ASSERT_EQ
(
++
iter
,
hashset
.
end
());
for
(
uint64_t
i
=
0
;
i
<
N
;
i
++
)
{
ASSERT_EQ
(
OB_HASH_NOT_EXIST
,
hashset
.
exist_refactored
(
i
));
}
for
(
uint64_t
i
=
0
;
i
<
N
;
i
++
)
{
ASSERT_EQ
(
OB_SUCCESS
,
hashset
.
set_refactored
(
i
));
}
ASSERT_EQ
(
OB_SUCCESS
,
hashset
.
set_refactored
(
N
));
for
(
uint64_t
i
=
0
;
i
<
N
;
i
++
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
exist_refactored
(
i
));
}
for
(
uint64_t
i
=
0
;
i
<
N
;
i
++
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
set_refactored
(
i
));
}
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
set_refactored
(
N
));
for
(
uint64_t
i
=
0
;
i
<
N
;
i
++
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
exist_refactored
(
i
));
}
ASSERT_EQ
(
N
+
1
,
hashset
.
count
());
for
(
value
=
0
,
iter
=
hashset
.
begin
();
iter
!=
hashset
.
end
();
++
iter
,
value
++
)
{
ASSERT_EQ
(
value
,
*
iter
);
}
}
TEST_F
(
ObExtIterHashSetTest
,
many_N_single_buckets2
)
{
const
uint64_t
N
=
10345
;
int64_t
value
=
0
;
ObExtIterHashSet
<
int64_t
,
N
>
hashset
(
allocator_
);
ObExtIterHashSet
<
int64_t
,
N
>::
const_iterator_t
iter
=
hashset
.
begin
();
ASSERT_EQ
(
iter
,
hashset
.
end
());
ASSERT_EQ
(
++
iter
,
hashset
.
end
());
for
(
uint64_t
i
=
N
;
i
>
0
;
i
--
)
{
ASSERT_EQ
(
OB_HASH_NOT_EXIST
,
hashset
.
exist_refactored
(
i
));
}
for
(
uint64_t
i
=
N
;
i
>
0
;
i
--
)
{
ASSERT_EQ
(
OB_SUCCESS
,
hashset
.
set_refactored
(
i
));
}
ASSERT_EQ
(
OB_SUCCESS
,
hashset
.
set_refactored
(
0
));
for
(
uint64_t
i
=
N
;
i
>
0
;
i
--
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
exist_refactored
(
i
));
}
for
(
uint64_t
i
=
N
;
i
>
0
;
i
--
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
set_refactored
(
i
));
}
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
set_refactored
(
0
));
for
(
uint64_t
i
=
N
;
i
>
0
;
i
--
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
exist_refactored
(
i
));
}
ASSERT_EQ
(
N
+
1
,
hashset
.
count
());
for
(
value
=
N
,
iter
=
hashset
.
begin
();
iter
!=
hashset
.
end
();
++
iter
,
value
--
)
{
ASSERT_EQ
(
value
,
*
iter
);
}
hashset
.
clear
();
iter
=
hashset
.
begin
();
ASSERT_EQ
(
iter
,
hashset
.
end
());
ASSERT_EQ
(
++
iter
,
hashset
.
end
());
for
(
uint64_t
i
=
N
;
i
>
0
;
i
--
)
{
ASSERT_EQ
(
OB_HASH_NOT_EXIST
,
hashset
.
exist_refactored
(
i
));
}
for
(
uint64_t
i
=
N
;
i
>
0
;
i
--
)
{
ASSERT_EQ
(
OB_SUCCESS
,
hashset
.
set_refactored
(
i
));
}
ASSERT_EQ
(
OB_SUCCESS
,
hashset
.
set_refactored
(
0
));
for
(
uint64_t
i
=
N
;
i
>
0
;
i
--
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
exist_refactored
(
i
));
}
for
(
uint64_t
i
=
N
;
i
>
0
;
i
--
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
set_refactored
(
i
));
}
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
set_refactored
(
0
));
for
(
uint64_t
i
=
N
;
i
>
0
;
i
--
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
exist_refactored
(
i
));
}
ASSERT_EQ
(
N
+
1
,
hashset
.
count
());
for
(
value
=
N
,
iter
=
hashset
.
begin
();
iter
!=
hashset
.
end
();
++
iter
,
value
--
)
{
ASSERT_EQ
(
value
,
*
iter
);
}
}
TEST_F
(
ObExtIterHashSetTest
,
many_N_many_buckets
)
{
static
const
uint64_t
N
=
16
;
static
const
uint64_t
BUCKET_NUM
=
100
;
static
const
uint64_t
ELEMENT_NUM
=
N
*
BUCKET_NUM
;
int64_t
value
=
0
;
ObExtIterHashSet
<
int64_t
,
N
>
hashset
(
allocator_
);
ObExtIterHashSet
<
int64_t
,
N
>::
const_iterator_t
iter
=
hashset
.
begin
();
ASSERT_EQ
(
iter
,
hashset
.
end
());
ASSERT_EQ
(
++
iter
,
hashset
.
end
());
for
(
uint64_t
i
=
0
;
i
<
ELEMENT_NUM
;
i
++
)
{
ASSERT_EQ
(
OB_HASH_NOT_EXIST
,
hashset
.
exist_refactored
(
i
));
}
for
(
uint64_t
i
=
0
;
i
<
ELEMENT_NUM
;
i
++
)
{
ASSERT_EQ
(
OB_SUCCESS
,
hashset
.
set_refactored
(
i
));
}
for
(
uint64_t
i
=
0
;
i
<
ELEMENT_NUM
;
i
++
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
exist_refactored
(
i
));
}
for
(
uint64_t
i
=
0
;
i
<
ELEMENT_NUM
;
i
++
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
set_refactored
(
i
));
}
for
(
uint64_t
i
=
0
;
i
<
ELEMENT_NUM
;
i
++
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
exist_refactored
(
i
));
}
ASSERT_EQ
(
ELEMENT_NUM
,
hashset
.
count
());
for
(
value
=
0
,
iter
=
hashset
.
begin
();
iter
!=
hashset
.
end
();
++
iter
,
value
++
)
{
ASSERT_EQ
(
value
,
*
iter
);
}
hashset
.
clear
();
iter
=
hashset
.
begin
();
ASSERT_EQ
(
iter
,
hashset
.
end
());
ASSERT_EQ
(
++
iter
,
hashset
.
end
());
for
(
uint64_t
i
=
0
;
i
<
ELEMENT_NUM
;
i
++
)
{
ASSERT_EQ
(
OB_HASH_NOT_EXIST
,
hashset
.
exist_refactored
(
i
));
}
for
(
uint64_t
i
=
0
;
i
<
ELEMENT_NUM
;
i
++
)
{
ASSERT_EQ
(
OB_SUCCESS
,
hashset
.
set_refactored
(
i
));
}
for
(
uint64_t
i
=
0
;
i
<
ELEMENT_NUM
;
i
++
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
exist_refactored
(
i
));
}
for
(
uint64_t
i
=
0
;
i
<
ELEMENT_NUM
;
i
++
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
set_refactored
(
i
));
}
for
(
uint64_t
i
=
0
;
i
<
ELEMENT_NUM
;
i
++
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
exist_refactored
(
i
));
}
ASSERT_EQ
(
ELEMENT_NUM
,
hashset
.
count
());
for
(
value
=
0
,
iter
=
hashset
.
begin
();
iter
!=
hashset
.
end
();
++
iter
,
value
++
)
{
ASSERT_EQ
(
value
,
*
iter
);
}
}
TEST_F
(
ObExtIterHashSetTest
,
many_N_many_buckets2
)
{
static
const
uint64_t
N
=
128
;
static
const
uint64_t
BUCKET_NUM
=
10
;
static
const
uint64_t
ELEMENT_NUM
=
N
*
BUCKET_NUM
;
int64_t
value
=
0
;
ObExtIterHashSet
<
int64_t
,
N
>
hashset
(
allocator_
);
ObExtIterHashSet
<
int64_t
,
N
>::
const_iterator_t
iter
=
hashset
.
begin
();
ASSERT_EQ
(
iter
,
hashset
.
end
());
ASSERT_EQ
(
++
iter
,
hashset
.
end
());
for
(
uint64_t
i
=
ELEMENT_NUM
;
i
>
0
;
i
--
)
{
ASSERT_EQ
(
OB_HASH_NOT_EXIST
,
hashset
.
exist_refactored
(
i
));
}
for
(
uint64_t
i
=
ELEMENT_NUM
;
i
>
0
;
i
--
)
{
ASSERT_EQ
(
OB_SUCCESS
,
hashset
.
set_refactored
(
i
));
}
for
(
uint64_t
i
=
ELEMENT_NUM
;
i
>
0
;
i
--
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
exist_refactored
(
i
));
}
for
(
uint64_t
i
=
ELEMENT_NUM
;
i
>
0
;
i
--
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
set_refactored
(
i
));
}
for
(
uint64_t
i
=
ELEMENT_NUM
;
i
>
0
;
i
--
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
exist_refactored
(
i
));
}
ASSERT_EQ
(
ELEMENT_NUM
,
hashset
.
count
());
for
(
value
=
ELEMENT_NUM
,
iter
=
hashset
.
begin
();
iter
!=
hashset
.
end
();
++
iter
,
value
--
)
{
ASSERT_EQ
(
value
,
*
iter
);
}
hashset
.
clear
();
iter
=
hashset
.
begin
();
ASSERT_EQ
(
iter
,
hashset
.
end
());
ASSERT_EQ
(
++
iter
,
hashset
.
end
());
for
(
uint64_t
i
=
ELEMENT_NUM
;
i
>
0
;
i
--
)
{
ASSERT_EQ
(
OB_HASH_NOT_EXIST
,
hashset
.
exist_refactored
(
i
));
}
for
(
uint64_t
i
=
ELEMENT_NUM
;
i
>
0
;
i
--
)
{
ASSERT_EQ
(
OB_SUCCESS
,
hashset
.
set_refactored
(
i
));
}
for
(
uint64_t
i
=
ELEMENT_NUM
;
i
>
0
;
i
--
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
exist_refactored
(
i
));
}
for
(
uint64_t
i
=
ELEMENT_NUM
;
i
>
0
;
i
--
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
set_refactored
(
i
));
}
for
(
uint64_t
i
=
ELEMENT_NUM
;
i
>
0
;
i
--
)
{
ASSERT_EQ
(
OB_HASH_EXIST
,
hashset
.
exist_refactored
(
i
));
}
ASSERT_EQ
(
ELEMENT_NUM
,
hashset
.
count
());
for
(
value
=
ELEMENT_NUM
,
iter
=
hashset
.
begin
();
iter
!=
hashset
.
end
();
++
iter
,
value
--
)
{
ASSERT_EQ
(
value
,
*
iter
);
}
}
int
main
(
int
argc
,
char
**
argv
)
{
OB_LOGGER
.
set_log_level
(
"INFO"
);
::
testing
::
InitGoogleTest
(
&
argc
,
argv
);
return
RUN_ALL_TESTS
();
}
deps/oblib/unittest/lib/hash/test_pre_alloc_link_hashmap.cpp
已删除
100644 → 0
浏览文件 @
ae138ca6
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include "lib/hash/ob_pre_alloc_link_hashmap.h"
#include "lib/allocator/ob_malloc.h"
#include "gtest/gtest.h"
using
namespace
oceanbase
;
using
namespace
oceanbase
::
common
;
using
namespace
oceanbase
::
common
::
hash
;
struct
Item
{
int64_t
key_
;
int64_t
value_
;
int64_t
ref_
;
Item
()
:
key_
(
0
),
value_
(
0
),
ref_
(
0
)
{}
Item
(
const
int64_t
key
,
const
int64_t
value
,
const
int64_t
ref
)
:
key_
(
key
),
value_
(
value
),
ref_
(
ref
)
{}
TO_STRING_KV
(
K_
(
key
),
K_
(
value
));
};
struct
Node
:
public
ObPreAllocLinkHashNode
<
int64_t
,
Item
>
{
explicit
Node
(
Item
&
item
)
:
ObPreAllocLinkHashNode
(
item
),
next_
(
NULL
)
{}
virtual
~
Node
()
{
}
static
uint64_t
hash
(
int64_t
key
)
{
return
key
;
}
virtual
uint64_t
hash
()
const
{
return
hash
(
item_
.
key_
);
}
virtual
const
int64_t
&
get_key
()
const
{
return
item_
.
key_
;
}
Node
*
next_
;
};
class
ItemProtector
{
public:
static
void
hold
(
Item
&
item
)
{
++
item
.
ref_
;
}
static
void
release
(
Item
&
item
)
{
--
item
.
ref_
;
}
};
typedef
common
::
hash
::
ObPreAllocLinkHashMap
<
int64_t
,
Item
,
Node
,
ItemProtector
>
TestMap
;
struct
TestForeachFinder
:
public
TestMap
::
ForeachFunctor
{
TestForeachFinder
()
:
count_
(
0
)
{}
virtual
~
TestForeachFinder
()
{}
virtual
int
operator
()(
Item
&
item
,
bool
&
is_full
)
{
int
ret
=
OB_SUCCESS
;
if
(
count_
>=
MAX_COUNT
)
{
is_full
=
true
;
}
else
if
(
item
.
value_
==
0
)
{
items_
[
count_
++
]
=
&
item
;
}
else
if
(
item
.
value_
==
2
)
{
ret
=
OB_ERR_SYS
;
}
return
ret
;
}
static
const
int64_t
MAX_COUNT
=
3
;
Item
*
items_
[
MAX_COUNT
];
int64_t
count_
;
};
struct
TestForeachCheckRef
:
public
TestMap
::
ForeachFunctor
{
TestForeachCheckRef
()
:
count_
(
0
)
{}
virtual
~
TestForeachCheckRef
()
{}
virtual
int
operator
()(
Item
&
item
,
bool
&
is_full
)
{
int
ret
=
OB_SUCCESS
;
is_full
=
false
;
++
count_
;
if
(
item
.
ref_
!=
0
)
{
COMMON_LOG
(
ERROR
,
"ref not zero"
,
K
(
item
.
ref_
),
K
(
item
.
key_
));
ret
=
OB_ERR_SYS
;
}
return
ret
;
}
int64_t
count_
;
};
class
TestEraseChecker
:
public
TestMap
::
EraseChecker
{
public:
virtual
~
TestEraseChecker
()
{}
virtual
int
operator
()(
Item
&
item
)
{
int
ret
=
OB_SUCCESS
;
if
(
item
.
value_
!=
0
)
{
ret
=
OB_EAGAIN
;
}
return
ret
;
}
};
class
TestGetFunctor
:
public
TestMap
::
GetFunctor
{
public:
TestGetFunctor
()
:
item_
(
NULL
)
{}
virtual
~
TestGetFunctor
()
{}
virtual
int
operator
()(
Item
&
item
)
override
{
int
ret
=
OB_SUCCESS
;
item_
=
NULL
;
if
(
item
.
value_
==
3
)
{
ret
=
OB_ERR_SYS
;
}
else
{
item_
=
&
item
;
}
return
ret
;
}
Item
*
item_
;
private:
DISALLOW_COPY_AND_ASSIGN
(
TestGetFunctor
);
};
TEST
(
TestObMemLessLinkHashMap
,
basic
)
{
TestMap
map
;
int64_t
buckets_count
=
0
;
uint32_t
latch_id
=
1
;
const
lib
::
ObLabel
&
label
=
"1"
;
Item
item1
=
{
1
,
0
,
0
};
Node
*
node1
=
map
.
alloc_node
(
item1
);
COMMON_LOG
(
INFO
,
"dump"
,
K
(
item1
),
K
(
node1
->
item_
),
KP
(
&
item1
),
KP
(
&
node1
->
item_
));
TestForeachFinder
finder
;
ASSERT_EQ
(
OB_NOT_INIT
,
map
.
put
(
*
node1
));
ASSERT_EQ
(
OB_INVALID_ARGUMENT
,
map
.
init
(
buckets_count
,
latch_id
,
label
));
ASSERT_EQ
(
OB_INVALID_ARGUMENT
,
map
.
init
(
buckets_count
,
latch_id
,
label
));
buckets_count
=
100
;
ASSERT_EQ
(
OB_SUCCESS
,
map
.
init
(
buckets_count
,
latch_id
,
label
));
ASSERT_EQ
(
OB_INIT_TWICE
,
map
.
init
(
buckets_count
,
latch_id
,
label
));
ASSERT_EQ
(
0
,
map
.
get_count
());
ASSERT_EQ
(
OB_SUCCESS
,
map
.
put
(
*
node1
));
ASSERT_EQ
(
OB_HASH_EXIST
,
map
.
put
(
*
node1
));
ASSERT_EQ
(
1
,
map
.
get_count
());
Item
item2
=
{
1
,
0
,
0
};
Node
node2
(
item2
);
ASSERT_EQ
(
OB_HASH_EXIST
,
map
.
put
(
node2
));
ASSERT_EQ
(
1
,
map
.
get_count
());
Item
*
get_item
=
NULL
;
ASSERT_EQ
(
OB_SUCCESS
,
map
.
get
(
1
,
get_item
));
ASSERT_EQ
(
&
item1
,
get_item
);
ASSERT_EQ
(
OB_SUCCESS
,
map
.
foreach
(
finder
));
ASSERT_EQ
(
1
,
finder
.
count_
);
COMMON_LOG
(
INFO
,
"dump"
,
K
(
node1
),
K
(
finder
.
items_
[
0
]));
ASSERT_EQ
(
&
item1
,
finder
.
items_
[
0
]);
Item
*
del_item
=
NULL
;
ASSERT_EQ
(
OB_SUCCESS
,
map
.
erase
(
1
,
del_item
));
ASSERT_EQ
(
&
item1
,
del_item
);
ASSERT_EQ
(
OB_HASH_NOT_EXIST
,
map
.
erase
(
1
,
del_item
));
ASSERT_EQ
(
OB_HASH_NOT_EXIST
,
map
.
get
(
1
,
del_item
));
}
TEST
(
TestObMemLessLinkHashMap
,
same_hash
)
{
TestMap
map
;
int64_t
buckets_count
=
1
;
uint32_t
latch_id
=
1
;
const
lib
::
ObLabel
&
label
=
"1"
;
Item
item1
=
{
1
,
0
,
0
};
ASSERT_EQ
(
OB_SUCCESS
,
map
.
init
(
buckets_count
,
latch_id
,
label
));
buckets_count
=
map
.
get_buckets_count
();
Node
*
node1
=
map
.
alloc_node
(
item1
);
Item
item2
=
{
1
+
buckets_count
,
0
,
0
};
Node
*
node2
=
map
.
alloc_node
(
item2
);
ASSERT_EQ
(
OB_SUCCESS
,
map
.
put
(
*
node1
));
ASSERT_EQ
(
OB_SUCCESS
,
map
.
put
(
*
node2
));
ASSERT_EQ
(
2
,
map
.
get_count
());
Item
*
got_item
=
NULL
;
ASSERT_EQ
(
OB_SUCCESS
,
map
.
get
(
1
,
got_item
));
ASSERT_EQ
(
&
item1
,
got_item
);
ASSERT_EQ
(
OB_SUCCESS
,
map
.
get
(
item2
.
key_
,
got_item
));
ASSERT_EQ
(
&
item2
,
got_item
);
Item
*
del_item
=
NULL
;
ASSERT_EQ
(
OB_SUCCESS
,
map
.
erase
(
item2
.
key_
,
del_item
));
ASSERT_EQ
(
&
item2
,
del_item
);
ASSERT_EQ
(
OB_SUCCESS
,
map
.
erase
(
item1
.
key_
,
del_item
));
ASSERT_EQ
(
&
item1
,
del_item
);
}
TEST
(
TestObMemLessLinkHashMap
,
erase
)
{
TestMap
map
;
int64_t
buckets_count
=
100
;
uint32_t
latch_id
=
1
;
const
lib
::
ObLabel
&
label
=
"1"
;
TestEraseChecker
checker
;
Item
*
del_item
=
NULL
;
ASSERT_EQ
(
OB_SUCCESS
,
map
.
init
(
buckets_count
,
latch_id
,
label
));
Item
item1
=
{
1
,
0
,
0
};
Node
*
node1
=
map
.
alloc_node
(
item1
);
Item
item2
=
{
2
,
1
,
0
};
Node
*
node2
=
map
.
alloc_node
(
item2
);
ASSERT_EQ
(
OB_SUCCESS
,
map
.
put
(
*
node1
));
ASSERT_EQ
(
OB_SUCCESS
,
map
.
put
(
*
node2
));
ASSERT_EQ
(
OB_SUCCESS
,
map
.
erase
(
1
,
del_item
,
&
checker
));
ASSERT_EQ
(
del_item
,
&
item1
);
ASSERT_EQ
(
OB_EAGAIN
,
map
.
erase
(
2
,
del_item
,
&
checker
));
}
TEST
(
TestObMemLessLinkHashMap
,
get_functor
)
{
TestMap
map
;
int64_t
buckets_count
=
100
;
uint32_t
latch_id
=
1
;
const
lib
::
ObLabel
&
label
=
"1"
;
ASSERT_EQ
(
OB_SUCCESS
,
map
.
init
(
buckets_count
,
latch_id
,
label
));
Item
item1
=
{
1
,
0
,
0
};
Node
*
node1
=
map
.
alloc_node
(
item1
);
Item
item2
=
{
2
,
3
,
0
};
Node
*
node2
=
map
.
alloc_node
(
item2
);
TestGetFunctor
get_functor
;
Item
*
got_item
=
NULL
;
ASSERT_EQ
(
OB_SUCCESS
,
map
.
put
(
*
node1
));
ASSERT_EQ
(
OB_SUCCESS
,
map
.
put
(
*
node2
));
ASSERT_EQ
(
OB_SUCCESS
,
map
.
get
(
1
,
got_item
,
&
get_functor
));
ASSERT_EQ
(
got_item
,
&
item1
);
ASSERT_EQ
(
OB_SUCCESS
,
map
.
get
(
1
,
get_functor
));
ASSERT_EQ
(
get_functor
.
item_
,
&
item1
);
ASSERT_EQ
(
OB_ERR_SYS
,
map
.
get
(
2
,
got_item
,
&
get_functor
));
ASSERT_TRUE
(
got_item
==
NULL
);
ASSERT_TRUE
(
get_functor
.
item_
==
NULL
);
ASSERT_EQ
(
OB_HASH_EXIST
,
map
.
exist
(
1
));
ASSERT_EQ
(
OB_HASH_EXIST
,
map
.
exist
(
2
));
ASSERT_EQ
(
OB_HASH_NOT_EXIST
,
map
.
exist
(
3
));
}
TEST
(
TestObMemLessLinkHashMap
,
foreach
)
{
TestMap
map
;
int64_t
buckets_count
=
100
;
uint32_t
latch_id
=
1
;
const
lib
::
ObLabel
&
label
=
"1"
;
const
int64_t
count
=
10000
;
Item
*
items
[
count
];
TestForeachFinder
finder
;
ASSERT_EQ
(
OB_SUCCESS
,
map
.
init
(
buckets_count
,
latch_id
,
label
));
for
(
int64_t
i
=
0
;
i
<
count
;
++
i
)
{
Item
*
item
=
new
Item
();
item
->
key_
=
i
;
item
->
value_
=
i
%
2
;
Node
*
node
=
map
.
alloc_node
(
*
item
);
items
[
i
]
=
item
;
ASSERT_EQ
(
OB_SUCCESS
,
map
.
put
(
*
node
));
}
for
(
int64_t
i
=
0
;
i
<
count
;
++
i
)
{
Item
*
got_item
=
NULL
;
ASSERT_EQ
(
OB_SUCCESS
,
map
.
get
(
i
,
got_item
));
ASSERT_EQ
(
items
[
i
],
got_item
);
}
ASSERT_EQ
(
OB_SUCCESS
,
map
.
foreach
(
finder
));
ASSERT_EQ
(
3
,
finder
.
count_
);
for
(
int64_t
i
=
0
;
i
<
3
;
++
i
)
{
COMMON_LOG
(
INFO
,
"dump"
,
K
(
items
[
2
*
i
]),
K
(
*
finder
.
items_
[
i
]));
}
for
(
int64_t
i
=
0
;
i
<
count
;
++
i
)
{
delete
items
[
i
];
}
}
TEST
(
TestObMemLessLinkHashMap
,
iterator
)
{
TestMap
map
;
TestMap
::
Iterator
iter
(
map
);
int64_t
buckets_count
=
100000
;
uint32_t
latch_id
=
1
;
const
lib
::
ObLabel
&
label
=
"1"
;
ASSERT_EQ
(
OB_SUCCESS
,
map
.
init
(
buckets_count
,
latch_id
,
label
));
Item
item1
=
{
1
,
0
,
0
};
Node
*
node1
=
map
.
alloc_node
(
item1
);
Item
item2
=
{
2
,
3
,
0
};
Node
*
node2
=
map
.
alloc_node
(
item2
);
TestGetFunctor
get_functor
;
Item
*
got_item
=
NULL
;
ASSERT_EQ
(
OB_SUCCESS
,
map
.
put
(
*
node1
));
ASSERT_EQ
(
OB_SUCCESS
,
map
.
put
(
*
node2
));
ASSERT_EQ
(
OB_SUCCESS
,
iter
.
get_next
(
got_item
));
ASSERT_EQ
(
&
item1
,
got_item
);
ASSERT_EQ
(
OB_SUCCESS
,
iter
.
get_next
(
got_item
));
ASSERT_EQ
(
&
item2
,
got_item
);
ASSERT_EQ
(
OB_ITER_END
,
iter
.
get_next
(
got_item
));
}
TEST
(
TestObMemLessLinkHashMap
,
iterator2
)
{
int
ret
=
OB_SUCCESS
;
TestMap
map
;
int64_t
buckets_count
=
100
;
uint32_t
latch_id
=
1
;
const
lib
::
ObLabel
&
label
=
"1"
;
ASSERT_EQ
(
OB_SUCCESS
,
map
.
init
(
buckets_count
,
latch_id
,
label
));
const
int64_t
count
=
8061
;
for
(
int64_t
i
=
0
;
i
<
count
;
++
i
)
{
Item
*
item
=
new
Item
();
item
->
key_
=
i
;
item
->
value_
=
i
;
item
->
ref_
=
0
;
Node
*
node
=
map
.
alloc_node
(
*
item
);
ASSERT_EQ
(
OB_SUCCESS
,
map
.
put
(
*
node
));
}
{
TestMap
::
Iterator
iter
(
map
);
Item
*
got_item
=
NULL
;
int64_t
num
=
0
;
while
(
OB_SUCC
(
ret
))
{
if
(
OB_FAIL
(
iter
.
get_next
(
got_item
)))
{
COMMON_LOG
(
WARN
,
"rend"
,
K
(
ret
),
K
(
num
));
}
else
{
++
num
;
}
}
ASSERT_EQ
(
OB_ITER_END
,
ret
);
}
TestForeachCheckRef
checker
;
ASSERT_EQ
(
OB_SUCCESS
,
map
.
foreach
(
checker
));
ASSERT_EQ
(
count
,
checker
.
count_
);
}
int
main
(
int
argc
,
char
**
argv
)
{
OB_LOGGER
.
set_log_level
(
"INFO"
);
testing
::
InitGoogleTest
(
&
argc
,
argv
);
return
RUN_ALL_TESTS
();
}
src/logservice/libobcdc/src/ob_log_trans_ctx.h
浏览文件 @
44d430d9
...
...
@@ -17,7 +17,6 @@
#include "share/ob_define.h" // OB_*
#include "lib/allocator/ob_allocator.h" // ObIAllocator
#include "lib/hash/ob_ext_iter_hashset.h" // ObExtIterHashSet
#include "lib/container/ob_se_array.h" // ObSEArray
#include "lib/allocator/page_arena.h" // ObArenaAllocator
#include "lib/lock/ob_spin_lock.h" // ObSpinLock
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录