Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
352fa9b4
Y
YTBP
项目概览
YottaChain
/
YTBP
通知
0
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Y
YTBP
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
352fa9b4
编写于
2月 05, 2018
作者:
D
Daniel Larimer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add new iterator based db api
上级
df878838
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
283 addition
and
0 deletion
+283
-0
libraries/chain/chain_controller.cpp
libraries/chain/chain_controller.cpp
+6
-0
libraries/chain/include/eosio/chain/apply_context.hpp
libraries/chain/include/eosio/chain/apply_context.hpp
+191
-0
libraries/chain/include/eosio/chain/contracts/contract_table_objects.hpp
.../include/eosio/chain/contracts/contract_table_objects.hpp
+44
-0
libraries/chain/include/eosio/chain/types.hpp
libraries/chain/include/eosio/chain/types.hpp
+2
-0
libraries/chain/wasm_interface.cpp
libraries/chain/wasm_interface.cpp
+40
-0
未找到文件。
libraries/chain/chain_controller.cpp
浏览文件 @
352fa9b4
...
...
@@ -1040,8 +1040,14 @@ void chain_controller::_initialize_indexes() {
_db
.
add_index
<
permission_usage_index
>
();
_db
.
add_index
<
permission_link_index
>
();
_db
.
add_index
<
action_permission_index
>
();
_db
.
add_index
<
contracts
::
table_id_multi_index
>
();
_db
.
add_index
<
contracts
::
key_value_index
>
();
_db
.
add_index
<
contracts
::
index64_index
>
();
_db
.
add_index
<
contracts
::
keystr_value_index
>
();
_db
.
add_index
<
contracts
::
key128x128_value_index
>
();
_db
.
add_index
<
contracts
::
key64x64_value_index
>
();
...
...
libraries/chain/include/eosio/chain/apply_context.hpp
浏览文件 @
352fa9b4
...
...
@@ -14,6 +14,8 @@ namespace chainbase { class database; }
namespace
eosio
{
namespace
chain
{
using
contracts
::
key_value_object
;
class
chain_controller
;
class
apply_context
{
...
...
@@ -185,7 +187,196 @@ class apply_context {
void
checktime
()
const
;
void
update_db_usage
(
const
account_name
&
payer
,
int64_t
delta
)
{
require_write_lock
(
payer
);
if
(
(
delta
>
0
)
&&
payer
!=
account_name
(
receiver
)
)
{
require_authorization
(
payer
);
}
}
int
db_store_i64
(
uint64_t
scope
,
uint64_t
table
,
const
account_name
&
payer
,
uint64_t
id
,
const
char
*
buffer
,
size_t
buffer_size
)
{
require_write_lock
(
scope
);
const
auto
&
tab
=
find_or_create_table
(
scope
,
receiver
,
table
);
auto
tableid
=
tab
.
id
;
const
auto
&
obj
=
mutable_db
.
create
<
key_value_object
>
(
[
&
](
auto
&
o
)
{
o
.
t_id
=
tableid
;
o
.
primary_key
=
id
;
o
.
value
.
resize
(
buffer_size
);
o
.
payer
=
payer
;
memcpy
(
o
.
value
.
data
(),
buffer
,
buffer_size
);
});
mutable_db
.
modify
(
tab
,
[
&
](
auto
&
t
)
{
++
t
.
count
;
});
update_db_usage
(
payer
,
buffer_size
+
200
);
keyval_cache
.
cache_table
(
tab
);
return
keyval_cache
.
add
(
obj
);
}
void
db_update_i64
(
int
iterator
,
account_name
payer
,
const
char
*
buffer
,
size_t
buffer_size
)
{
const
key_value_object
&
obj
=
keyval_cache
.
get
(
iterator
);
require_write_lock
(
keyval_cache
.
get_table
(
obj
.
t_id
).
scope
);
int64_t
old_size
=
obj
.
value
.
size
();
if
(
payer
==
account_name
()
)
payer
=
obj
.
payer
;
if
(
account_name
(
obj
.
payer
)
==
payer
)
{
update_db_usage
(
obj
.
payer
,
buffer_size
+
200
-
old_size
);
}
else
{
update_db_usage
(
obj
.
payer
,
-
(
old_size
+
200
)
);
update_db_usage
(
payer
,
(
buffer_size
+
200
)
);
}
mutable_db
.
modify
(
obj
,
[
&
](
auto
&
o
)
{
o
.
value
.
resize
(
buffer_size
);
memcpy
(
o
.
value
.
data
(),
buffer
,
buffer_size
);
o
.
payer
=
payer
;
});
}
void
db_remove_i64
(
int
iterator
)
{
const
key_value_object
&
obj
=
keyval_cache
.
get
(
iterator
);
update_db_usage
(
obj
.
payer
,
-
(
obj
.
value
.
size
()
+
200
)
);
const
auto
&
table_obj
=
keyval_cache
.
get_table
(
obj
.
t_id
);
require_write_lock
(
table_obj
.
scope
);
mutable_db
.
modify
(
table_obj
,
[
&
](
auto
&
t
)
{
--
t
.
count
;
});
mutable_db
.
remove
(
obj
);
keyval_cache
.
remove
(
iterator
,
obj
);
}
int
db_get_i64
(
int
iterator
,
uint64_t
&
id
,
char
*
buffer
,
size_t
buffer_size
)
{
const
key_value_object
&
obj
=
keyval_cache
.
get
(
iterator
);
if
(
buffer_size
>=
obj
.
value
.
size
()
)
{
memcpy
(
buffer
,
obj
.
value
.
data
(),
obj
.
value
.
size
()
);
}
id
=
obj
.
primary_key
;
return
obj
.
value
.
size
();
}
int
db_next_i64
(
int
iterator
)
{
const
auto
&
obj
=
keyval_cache
.
get
(
iterator
);
const
auto
&
idx
=
db
.
get_index
<
contracts
::
key_value_index
,
contracts
::
by_scope_primary
>
();
auto
itr
=
idx
.
iterator_to
(
obj
);
++
itr
;
if
(
itr
==
idx
.
end
()
)
return
-
1
;
if
(
itr
->
t_id
!=
obj
.
t_id
)
return
-
1
;
return
keyval_cache
.
add
(
*
itr
);
}
int
db_find_i64
(
uint64_t
code
,
uint64_t
scope
,
uint64_t
table
,
uint64_t
id
)
{
require_read_lock
(
code
,
scope
);
const
auto
*
tab
=
find_table
(
scope
,
code
,
table
);
if
(
!
tab
)
return
-
1
;
const
key_value_object
*
obj
=
db
.
find
<
key_value_object
,
contracts
::
by_scope_primary
>
(
boost
::
make_tuple
(
tab
->
id
,
id
)
);
if
(
!
obj
)
return
-
1
;
keyval_cache
.
cache_table
(
*
tab
);
return
keyval_cache
.
add
(
*
obj
);
}
int
db_lowerbound_i64
(
uint64_t
code
,
uint64_t
scope
,
uint64_t
table
,
uint64_t
id
)
{
require_read_lock
(
code
,
scope
);
const
auto
*
tab
=
find_table
(
scope
,
code
,
table
);
if
(
!
tab
)
return
-
1
;
const
auto
&
idx
=
db
.
get_index
<
contracts
::
key_value_index
,
contracts
::
by_scope_primary
>
();
auto
itr
=
idx
.
lower_bound
(
boost
::
make_tuple
(
tab
->
id
,
id
)
);
if
(
itr
==
idx
.
end
()
)
return
-
1
;
if
(
itr
->
t_id
!=
tab
->
id
)
return
-
1
;
keyval_cache
.
cache_table
(
*
tab
);
return
keyval_cache
.
add
(
*
itr
);
}
int
db_upperbound_i64
(
uint64_t
code
,
uint64_t
scope
,
uint64_t
table
,
uint64_t
id
)
{
require_read_lock
(
code
,
scope
);
const
auto
*
tab
=
find_table
(
scope
,
code
,
table
);
if
(
!
tab
)
return
-
1
;
const
auto
&
idx
=
db
.
get_index
<
contracts
::
key_value_index
,
contracts
::
by_scope_primary
>
();
auto
itr
=
idx
.
upper_bound
(
boost
::
make_tuple
(
tab
->
id
,
id
)
);
if
(
itr
==
idx
.
end
()
)
return
-
1
;
if
(
itr
->
t_id
!=
tab
->
id
)
return
-
1
;
keyval_cache
.
cache_table
(
*
tab
);
return
keyval_cache
.
add
(
*
itr
);
}
private:
template
<
typename
T
>
class
iterator_cache
{
public:
iterator_cache
(){
_iterator_to_object
.
reserve
(
32
);
}
void
cache_table
(
const
table_id_object
&
tobj
)
{
_table_cache
[
tobj
.
id
]
=
&
tobj
;
}
const
table_id_object
&
get_table
(
table_id_object
::
id_type
i
)
{
auto
itr
=
_table_cache
.
find
(
i
);
FC_ASSERT
(
itr
!=
_table_cache
.
end
(),
"an invariant was broken, table should be in cache"
);
return
*
_table_cache
[
i
];
}
const
T
&
get
(
int
iterator
)
{
FC_ASSERT
(
iterator
>=
0
,
"invalid iterator"
);
FC_ASSERT
(
iterator
<
_iterator_to_object
.
size
(),
"iterator out of range"
);
auto
result
=
_iterator_to_object
[
iterator
];
FC_ASSERT
(
result
,
"reference of deleted object"
);
return
*
result
;
}
void
remove
(
int
iterator
,
const
T
&
obj
)
{
_iterator_to_object
[
iterator
]
=
nullptr
;
_object_to_iterator
.
erase
(
&
obj
);
}
int
add
(
const
T
&
obj
)
{
auto
itr
=
_object_to_iterator
.
find
(
&
obj
);
if
(
itr
!=
_object_to_iterator
.
end
()
)
return
itr
->
second
;
_iterator_to_object
.
push_back
(
&
obj
);
_object_to_iterator
[
&
obj
]
=
_iterator_to_object
.
size
()
-
1
;
return
_iterator_to_object
.
size
()
-
1
;
}
private:
map
<
table_id_object
::
id_type
,
const
table_id_object
*>
_table_cache
;
vector
<
const
T
*>
_iterator_to_object
;
map
<
const
T
*
,
int
>
_object_to_iterator
;
};
iterator_cache
<
key_value_object
>
keyval_cache
;
void
append_results
(
apply_results
&&
other
)
{
fc
::
move_append
(
results
.
applied_actions
,
move
(
other
.
applied_actions
));
fc
::
move_append
(
results
.
generated_transactions
,
move
(
other
.
generated_transactions
));
...
...
libraries/chain/include/eosio/chain/contracts/contract_table_objects.hpp
浏览文件 @
352fa9b4
...
...
@@ -21,6 +21,7 @@ namespace eosio { namespace chain { namespace contracts {
scope_name
scope
;
account_name
code
;
table_name
table
;
uint32_t
count
=
0
;
/// the number of elements in the table
};
struct
by_scope_code_table
;
...
...
@@ -57,6 +58,7 @@ namespace eosio { namespace chain { namespace contracts {
table_id
t_id
;
uint64_t
primary_key
;
shared_string
value
;
uint64_t
payer
=
0
;
};
using
key_value_index
=
chainbase
::
shared_multi_index_container
<
...
...
@@ -73,6 +75,44 @@ namespace eosio { namespace chain { namespace contracts {
>
>
;
struct
index64_object
:
public
chainbase
::
object
<
index64_object_type
,
index64_object
>
{
OBJECT_CTOR
(
index64_object
)
typedef
uint64_t
key_type
;
static
const
int
number_of_keys
=
1
;
id_type
id
;
table_id
t_id
;
uint64_t
primary_key
;
uint64_t
secondary_key
;
};
struct
by_primary
;
struct
by_secondary
;
using
index64_index
=
chainbase
::
shared_multi_index_container
<
index64_object
,
indexed_by
<
ordered_unique
<
tag
<
by_id
>
,
member
<
index64_object
,
index64_object
::
id_type
,
&
index64_object
::
id
>>
,
ordered_unique
<
tag
<
by_primary
>
,
composite_key
<
index64_object
,
member
<
index64_object
,
table_id
,
&
index64_object
::
t_id
>
,
member
<
index64_object
,
uint64_t
,
&
index64_object
::
primary_key
>
>
,
composite_key_compare
<
std
::
less
<
table_id
>
,
std
::
less
<
uint64_t
>
>
>
,
ordered_unique
<
tag
<
by_secondary
>
,
composite_key
<
index64_object
,
member
<
index64_object
,
uint64_t
,
&
index64_object
::
secondary_key
>
,
member
<
index64_object
,
uint64_t
,
&
index64_object
::
primary_key
>
>
>
>
>
;
struct
shared_string_less
{
bool
operator
()(
const
char
*
a
,
const
char
*
b
)
const
{
return
less
(
a
,
b
);
...
...
@@ -249,8 +289,12 @@ CHAINBASE_SET_INDEX_TYPE(eosio::chain::contracts::key128x128_value_object, eosio
CHAINBASE_SET_INDEX_TYPE
(
eosio
::
chain
::
contracts
::
key64x64_value_object
,
eosio
::
chain
::
contracts
::
key64x64_value_index
)
CHAINBASE_SET_INDEX_TYPE
(
eosio
::
chain
::
contracts
::
key64x64x64_value_object
,
eosio
::
chain
::
contracts
::
key64x64x64_value_index
)
CHAINBASE_SET_INDEX_TYPE
(
eosio
::
chain
::
contracts
::
index64_object
,
eosio
::
chain
::
contracts
::
index64_index
)
FC_REFLECT
(
eosio
::
chain
::
contracts
::
table_id_object
,
(
id
)(
scope
)(
code
)(
table
)
)
FC_REFLECT
(
eosio
::
chain
::
contracts
::
key_value_object
,
(
id
)(
t_id
)(
primary_key
)(
value
)
)
FC_REFLECT
(
eosio
::
chain
::
contracts
::
index64_object
,
(
id
)(
t_id
)(
primary_key
)(
secondary_key
)
)
FC_REFLECT
(
eosio
::
chain
::
contracts
::
keystr_value_object
,
(
id
)(
t_id
)(
primary_key
)(
value
)
)
FC_REFLECT
(
eosio
::
chain
::
contracts
::
key128x128_value_object
,
(
id
)(
t_id
)(
primary_key
)(
secondary_key
)(
value
)
)
FC_REFLECT
(
eosio
::
chain
::
contracts
::
key64x64_value_object
,
(
id
)(
t_id
)(
primary_key
)(
secondary_key
)(
value
)
)
...
...
libraries/chain/include/eosio/chain/types.hpp
浏览文件 @
352fa9b4
...
...
@@ -121,6 +121,7 @@ namespace eosio { namespace chain {
key_value_object_type
,
key128x128_value_object_type
,
key64x64_value_object_type
,
index64_object_type
,
action_permission_object_type
,
global_property_object_type
,
dynamic_global_property_object_type
,
...
...
@@ -174,6 +175,7 @@ FC_REFLECT_ENUM(eosio::chain::object_type,
(
key_value_object_type
)
(
key128x128_value_object_type
)
(
key64x64_value_object_type
)
(
index64_object_type
)
(
action_permission_object_type
)
(
global_property_object_type
)
(
dynamic_global_property_object_type
)
...
...
libraries/chain/wasm_interface.cpp
浏览文件 @
352fa9b4
...
...
@@ -680,6 +680,36 @@ class console_api : public context_aware_api {
}
};
class
database_api
:
public
context_aware_api
{
public:
using
context_aware_api
::
context_aware_api
;
int
db_store_i64
(
uint64_t
scope
,
uint64_t
table
,
uint64_t
payer
,
uint64_t
id
,
array_ptr
<
const
char
>
buffer
,
size_t
buffer_size
)
{
return
context
.
db_store_i64
(
scope
,
table
,
payer
,
id
,
buffer
,
buffer_size
);
}
void
db_update_i64
(
int
itr
,
uint64_t
payer
,
array_ptr
<
const
char
>
buffer
,
size_t
buffer_size
)
{
context
.
db_update_i64
(
itr
,
payer
,
buffer
,
buffer_size
);
}
void
db_remove_i64
(
int
itr
)
{
context
.
db_remove_i64
(
itr
);
}
int
db_get_i64
(
int
itr
,
uint64_t
&
id
,
array_ptr
<
char
>
buffer
,
size_t
buffer_size
)
{
return
context
.
db_get_i64
(
itr
,
id
,
buffer
,
buffer_size
);
}
int
db_next_i64
(
int
itr
)
{
return
context
.
db_next_i64
(
itr
);
}
int
db_find_i64
(
uint64_t
code
,
uint64_t
scope
,
uint64_t
table
,
uint64_t
id
)
{
return
context
.
db_find_i64
(
code
,
scope
,
table
,
id
);
}
int
db_lowerbound_i64
(
uint64_t
code
,
uint64_t
scope
,
uint64_t
table
,
uint64_t
id
)
{
return
context
.
db_lowerbound_i64
(
code
,
scope
,
table
,
id
);
}
int
db_upperbound_i64
(
uint64_t
code
,
uint64_t
scope
,
uint64_t
table
,
uint64_t
id
)
{
return
context
.
db_lowerbound_i64
(
code
,
scope
,
table
,
id
);
}
};
template
<
typename
ObjectType
>
class
db_api
:
public
context_aware_api
{
using
KeyType
=
typename
ObjectType
::
key_type
;
...
...
@@ -905,6 +935,16 @@ REGISTER_INTRINSICS(producer_api,
(
get_active_producers
,
int
(
int
,
int
))
);
REGISTER_INTRINSICS
(
database_api
,
(
db_store_i64
,
int
(
int64_t
,
int64_t
,
int64_t
,
int64_t
,
int
,
int
))
(
db_update_i64
,
void
(
int
,
int64_t
,
int
,
int
))
(
db_remove_i64
,
void
(
int
))
(
db_get_i64
,
int
(
int
,
int
,
int
,
int
))
(
db_next_i64
,
int
(
int
))
(
db_find_i64
,
int
(
int64_t
,
int64_t
,
int64_t
,
int64_t
))
(
db_lowerbound_i64
,
int
(
int64_t
,
int64_t
,
int64_t
,
int64_t
))
)
REGISTER_INTRINSICS
(
crypto_api
,
(
assert_recover_key
,
void
(
int
,
int
,
int
,
int
,
int
))
(
recover_key
,
int
(
int
,
int
,
int
,
int
,
int
))
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录