Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
49238b42
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,发现更多精彩内容 >>
提交
49238b42
编写于
2月 06, 2018
作者:
D
Daniel Larimer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
implement generic index framework
上级
19129a2d
变更
5
显示空白变更内容
内联
并排
Showing
5 changed file
with
273 addition
and
54 deletion
+273
-54
libraries/chain/chain_controller.cpp
libraries/chain/chain_controller.cpp
+1
-0
libraries/chain/include/eosio/chain/apply_context.hpp
libraries/chain/include/eosio/chain/apply_context.hpp
+191
-52
libraries/chain/include/eosio/chain/contracts/contract_table_objects.hpp
.../include/eosio/chain/contracts/contract_table_objects.hpp
+49
-2
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
+30
-0
未找到文件。
libraries/chain/chain_controller.cpp
浏览文件 @
49238b42
...
...
@@ -1047,6 +1047,7 @@ void chain_controller::_initialize_indexes() {
_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
::
index128_index
>
();
_db
.
add_index
<
contracts
::
keystr_value_index
>
();
...
...
libraries/chain/include/eosio/chain/apply_context.hpp
浏览文件 @
49238b42
...
...
@@ -19,13 +19,196 @@ using contracts::key_value_object;
class
chain_controller
;
class
apply_context
{
private:
template
<
typename
T
>
class
iterator_cache
{
public:
typedef
contracts
::
table_id_object
table_id_object
;
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
;
};
public:
template
<
typename
ObjectType
>
class
generic_index
{
public:
typedef
typename
ObjectType
::
secondary_key_type
secondary_key_type
;
generic_index
(
apply_context
&
c
)
:
context
(
c
){}
int
store
(
uint64_t
scope
,
uint64_t
table
,
const
account_name
&
payer
,
uint64_t
id
,
const
secondary_key_type
&
value
)
{
FC_ASSERT
(
payer
!=
account_name
(),
"must specify a valid account to pay for new record"
);
context
.
require_write_lock
(
scope
);
const
auto
&
tab
=
context
.
find_or_create_table
(
scope
,
context
.
receiver
,
table
);
const
auto
&
obj
=
context
.
mutable_db
.
create
<
ObjectType
>
(
[
&
](
auto
&
o
){
o
.
t_id
=
tab
.
id
;
o
.
primary_key
=
id
;
o
.
secondary_key
=
value
;
o
.
payer
=
payer
;
});
context
.
mutable_db
.
modify
(
tab
,
[
&
](
auto
&
t
)
{
++
t
.
count
;
});
context
.
update_db_usage
(
payer
,
sizeof
(
secondary_key_type
)
+
200
);
itr_cache
.
cache_table
(
tab
);
return
itr_cache
.
add
(
obj
);
}
void
remove
(
int
iterator
)
{
const
auto
&
obj
=
itr_cache
.
get
(
iterator
);
context
.
update_db_usage
(
obj
.
payer
,
-
(
sizeof
(
secondary_key_type
)
+
200
)
);
const
auto
&
table_obj
=
itr_cache
.
get_table
(
obj
.
t_id
);
context
.
require_write_lock
(
table_obj
.
scope
);
context
.
mutable_db
.
modify
(
table_obj
,
[
&
](
auto
&
t
)
{
--
t
.
count
;
});
context
.
mutable_db
.
remove
(
obj
);
itr_cache
.
remove
(
iterator
,
obj
);
}
void
update
(
int
iterator
,
account_name
payer
,
const
secondary_key_type
&
secondary
)
{
const
auto
&
obj
=
itr_cache
.
get
(
iterator
);
if
(
payer
==
account_name
()
)
payer
=
obj
.
payer
;
if
(
obj
.
payer
!=
payer
)
{
context
.
update_db_usage
(
obj
.
payer
,
-
(
sizeof
(
secondary_key_type
)
+
200
)
);
context
.
update_db_usage
(
payer
,
+
(
sizeof
(
secondary_key_type
)
+
200
)
);
}
context
.
mutable_db
.
modify
(
obj
,
[
&
](
auto
&
o
)
{
o
.
secondary_key
=
secondary
;
o
.
payer
=
payer
;
});
}
int
find_secondary
(
uint64_t
code
,
uint64_t
scope
,
uint64_t
table
,
const
secondary_key_type
&
secondary
)
{
auto
tab
=
context
.
find_table
(
scope
,
context
.
receiver
,
table
);
if
(
!
tab
)
return
-
1
;
const
auto
*
obj
=
context
.
db
.
find
<
ObjectType
,
contracts
::
by_secondary
>
(
boost
::
make_tuple
(
tab
->
id
,
secondary
)
);
if
(
!
obj
)
return
-
1
;
itr_cache
.
cache_table
(
*
tab
);
return
itr_cache
.
add
(
*
obj
);
}
int
lowerbound_secondary
(
uint64_t
code
,
uint64_t
scope
,
uint64_t
table
,
const
secondary_key_type
&
secondary
)
{
auto
tab
=
context
.
find_table
(
scope
,
context
.
receiver
,
table
);
if
(
!
tab
)
return
-
1
;
const
auto
&
idx
=
context
.
db
.
get_index
<
chainbase
::
get_index_type
<
ObjectType
>::
type
,
contracts
::
by_secondary
>
();
auto
itr
=
idx
.
lower_bound
(
boost
::
make_tuple
(
tab
->
id
,
secondary
)
);
if
(
itr
==
idx
.
end
()
)
return
-
1
;
if
(
itr
->
t_id
!=
tab
.
id
)
return
-
1
;
itr_cache
.
cache_table
(
*
tab
);
return
itr_cache
.
add
(
*
itr
);
}
int
upperbound_secondary
(
uint64_t
code
,
uint64_t
scope
,
uint64_t
table
,
const
secondary_key_type
&
secondary
)
{
auto
tab
=
context
.
find_table
(
scope
,
context
.
receiver
,
table
);
if
(
!
tab
)
return
-
1
;
const
auto
&
idx
=
context
.
db
.
get_index
<
chainbase
::
get_index_type
<
ObjectType
>::
type
,
contracts
::
by_secondary
>
();
auto
itr
=
idx
.
upper_bound
(
boost
::
make_tuple
(
tab
->
id
,
secondary
)
);
if
(
itr
==
idx
.
end
()
)
return
-
1
;
if
(
itr
->
t_id
!=
tab
.
id
)
return
-
1
;
itr_cache
.
cache_table
(
*
tab
);
return
itr_cache
.
add
(
*
itr
);
}
int
find_primary
(
uint64_t
code
,
uint64_t
scope
,
uint64_t
table
,
uint64_t
primary
)
{
auto
tab
=
context
.
find_table
(
scope
,
context
.
receiver
,
table
);
if
(
!
tab
)
return
-
1
;
const
auto
*
obj
=
context
.
db
.
find
<
ObjectType
,
contracts
::
by_primary
>
(
boost
::
make_tuple
(
tab
->
id
,
primary
)
);
if
(
!
obj
)
return
-
1
;
itr_cache
.
cache_table
(
*
tab
);
return
itr_cache
.
add
(
*
obj
);
}
void
get
(
int
iterator
,
uint64_t
&
primary
,
secondary_key_type
&
secondary
)
{
const
auto
&
obj
=
itr_cache
.
get
(
iterator
);
primary
=
obj
.
primary_key
;
secondary
=
obj
.
secondary_key
;
}
private:
apply_context
&
context
;
iterator_cache
<
ObjectType
>
itr_cache
;
};
apply_context
(
chain_controller
&
con
,
chainbase
::
database
&
db
,
const
action
&
a
,
const
transaction_metadata
&
trx_meta
,
uint32_t
checktime_limit
)
:
controller
(
con
),
db
(
db
),
act
(
a
),
mutable_controller
(
con
),
mutable_db
(
db
),
used_authorizations
(
act
.
authorization
.
size
(),
false
),
trx_meta
(
trx_meta
),
_checktime_limit
(
checktime_limit
)
{}
:
controller
(
con
),
db
(
db
),
act
(
a
),
mutable_controller
(
con
),
mutable_db
(
db
),
used_authorizations
(
act
.
authorization
.
size
(),
false
),
trx_meta
(
trx_meta
),
idx64
(
*
this
),
idx128
(
*
this
),
_checktime_limit
(
checktime_limit
)
{}
void
exec
();
...
...
@@ -200,6 +383,8 @@ class apply_context {
const
auto
&
tab
=
find_or_create_table
(
scope
,
receiver
,
table
);
auto
tableid
=
tab
.
id
;
FC_ASSERT
(
payer
!=
account_name
(),
"must specify a valid account to pay for new record"
);
const
auto
&
obj
=
mutable_db
.
create
<
key_value_object
>
(
[
&
](
auto
&
o
)
{
o
.
t_id
=
tableid
;
o
.
primary_key
=
id
;
...
...
@@ -324,59 +509,13 @@ class apply_context {
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
;
}
generic_index
<
contracts
::
index64_object
>
idx64
;
generic_index
<
contracts
::
index128_object
>
idx128
;
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
浏览文件 @
49238b42
...
...
@@ -76,6 +76,52 @@ namespace eosio { namespace chain { namespace contracts {
>
>
;
struct
by_primary
;
struct
by_secondary
;
template
<
typename
SecondaryKey
,
uint64_t
ObjectTypeId
>
struct
secondary_index
{
struct
index_object
:
public
chainbase
::
object
<
ObjectTypeId
,
index_object
>
{
OBJECT_CTOR
(
index_object
)
typedef
SecondaryKey
secondary_key_type
;
typename
chainbase
::
object
<
ObjectTypeId
,
index_object
>::
id_type
id
;
table_id
t_id
;
uint64_t
primary_key
;
SecondaryKey
secondary_key
;
account_name
payer
;
};
typedef
chainbase
::
shared_multi_index_container
<
index_object
,
indexed_by
<
ordered_unique
<
tag
<
by_id
>
,
member
<
index_object
,
typename
index_object
::
id_type
,
&
index_object
::
id
>>
,
ordered_unique
<
tag
<
by_primary
>
,
composite_key
<
index_object
,
member
<
index_object
,
table_id
,
&
index_object
::
t_id
>
,
member
<
index_object
,
uint64_t
,
&
index_object
::
primary_key
>
>
,
composite_key_compare
<
std
::
less
<
table_id
>
,
std
::
less
<
uint64_t
>
>
>
,
ordered_unique
<
tag
<
by_secondary
>
,
composite_key
<
index_object
,
member
<
index_object
,
SecondaryKey
,
&
index_object
::
secondary_key
>
,
member
<
index_object
,
uint64_t
,
&
index_object
::
primary_key
>
>
>
>
>
index_index
;
};
typedef
secondary_index
<
uint64_t
,
index64_object_type
>::
index_object
index64_object
;
typedef
secondary_index
<
uint64_t
,
index64_object_type
>::
index_index
index64_index
;
typedef
secondary_index
<
uint128_t
,
index128_object_type
>::
index_object
index128_object
;
typedef
secondary_index
<
uint128_t
,
index128_object_type
>::
index_index
index128_index
;
/*
struct index64_object : public chainbase::object<index64_object_type, index64_object> {
OBJECT_CTOR(index64_object)
...
...
@@ -86,10 +132,9 @@ namespace eosio { namespace chain { namespace contracts {
table_id t_id;
uint64_t primary_key;
uint64_t secondary_key;
account_name payer;
};
struct
by_primary
;
struct
by_secondary
;
using index64_index = chainbase::shared_multi_index_container<
index64_object,
indexed_by<
...
...
@@ -109,6 +154,7 @@ namespace eosio { namespace chain { namespace contracts {
>
>
>;
*/
...
...
@@ -295,6 +341,7 @@ CHAINBASE_SET_INDEX_TYPE(eosio::chain::contracts::key64x64_value_object, eosio::
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
)
CHAINBASE_SET_INDEX_TYPE
(
eosio
::
chain
::
contracts
::
index128_object
,
eosio
::
chain
::
contracts
::
index128_index
)
FC_REFLECT
(
eosio
::
chain
::
contracts
::
table_id_object
,
(
id
)(
code
)(
scope
)(
table
)
)
FC_REFLECT
(
eosio
::
chain
::
contracts
::
key_value_object
,
(
id
)(
t_id
)(
primary_key
)(
value
)(
payer
)
)
...
...
libraries/chain/include/eosio/chain/types.hpp
浏览文件 @
49238b42
...
...
@@ -122,6 +122,7 @@ namespace eosio { namespace chain {
key128x128_value_object_type
,
key64x64_value_object_type
,
index64_object_type
,
index128_object_type
,
action_permission_object_type
,
global_property_object_type
,
dynamic_global_property_object_type
,
...
...
@@ -176,6 +177,7 @@ FC_REFLECT_ENUM(eosio::chain::object_type,
(
key128x128_value_object_type
)
(
key64x64_value_object_type
)
(
index64_object_type
)
(
index128_object_type
)
(
action_permission_object_type
)
(
global_property_object_type
)
(
dynamic_global_property_object_type
)
...
...
libraries/chain/wasm_interface.cpp
浏览文件 @
49238b42
...
...
@@ -708,6 +708,27 @@ class database_api : public context_aware_api {
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
);
}
int
db_idx64_store
(
uint64_t
scope
,
uint64_t
table
,
uint64_t
payer
,
uint64_t
id
,
const
uint64_t
&
secondary
)
{
return
context
.
idx64
.
store
(
scope
,
table
,
payer
,
id
,
secondary
);
}
void
db_idx64_update
(
int
iterator
,
uint64_t
payer
,
const
uint64_t
&
secondary
)
{
return
context
.
idx64
.
update
(
iterator
,
payer
,
secondary
);
}
void
db_idx64_remove
(
int
iterator
)
{
return
context
.
idx64
.
remove
(
iterator
);
}
int
db_idx128_store
(
uint64_t
scope
,
uint64_t
table
,
uint64_t
payer
,
uint64_t
id
,
const
uint128_t
&
secondary
)
{
return
context
.
idx128
.
store
(
scope
,
table
,
payer
,
id
,
secondary
);
}
void
db_idx128_update
(
int
iterator
,
uint64_t
payer
,
const
uint128_t
&
secondary
)
{
return
context
.
idx128
.
update
(
iterator
,
payer
,
secondary
);
}
void
db_idx128_remove
(
int
iterator
)
{
return
context
.
idx128
.
remove
(
iterator
);
}
};
...
...
@@ -944,6 +965,15 @@ REGISTER_INTRINSICS( database_api,
(
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
))
(
db_idx64_store
,
int
(
int64_t
,
int64_t
,
int64_t
,
int64_t
,
int
))
(
db_idx64_remove
,
void
(
int
))
(
db_idx64_update
,
void
(
int
,
int64_t
,
int
))
(
db_idx128_store
,
int
(
int64_t
,
int64_t
,
int64_t
,
int64_t
,
int
))
(
db_idx128_remove
,
void
(
int
))
(
db_idx128_update
,
void
(
int
,
int64_t
,
int
))
)
REGISTER_INTRINSICS
(
crypto_api
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录