Allocate DefIndices for global crate metadata.

This allows for treating global crate metadata the same as regular metadata with regard to incr. comp.
This commit is contained in:
Michael Woerister 2017-06-07 10:45:20 +02:00
parent 12e5b699a4
commit 8b36d3308e
14 changed files with 159 additions and 119 deletions

View file

@ -53,9 +53,6 @@ pub enum DepNode<D: Clone + Debug> {
/// in an extern crate.
MetaData(D),
/// Represents some piece of metadata global to its crate.
GlobalMetaData(D, GlobalMetaDataKind),
/// Represents some artifact that we save to disk. Note that these
/// do not have a def-id as part of their identifier.
WorkProduct(WorkProductId),
@ -309,7 +306,6 @@ impl<D: Clone + Debug> DepNode<D> {
ItemBodyNestedBodies(ref d) => op(d).map(ItemBodyNestedBodies),
ConstIsRvaluePromotableToStatic(ref d) => op(d).map(ConstIsRvaluePromotableToStatic),
IsMirAvailable(ref d) => op(d).map(IsMirAvailable),
GlobalMetaData(ref d, kind) => op(d).map(|d| GlobalMetaData(d, kind)),
}
}
}
@ -330,16 +326,3 @@ impl WorkProductId {
WorkProductId(hasher.finish())
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub enum GlobalMetaDataKind {
Krate,
CrateDeps,
DylibDependencyFormats,
LangItems,
LangItemsMissing,
NativeLibraries,
CodeMap,
Impls,
ExportedSymbols,
}

View file

@ -22,7 +22,6 @@ mod thread;
pub use self::dep_tracking_map::{DepTrackingMap, DepTrackingMapConfig};
pub use self::dep_node::DepNode;
pub use self::dep_node::WorkProductId;
pub use self::dep_node::GlobalMetaDataKind;
pub use self::graph::DepGraph;
pub use self::graph::WorkProduct;
pub use self::query::DepGraphQuery;

View file

@ -15,7 +15,8 @@
//! expressions) that are mostly just leftovers.
use hir;
use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, DefIndexAddressSpace};
use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, DefIndexAddressSpace,
CRATE_DEF_INDEX};
use ich::Fingerprint;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::IndexVec;
@ -396,6 +397,11 @@ pub enum DefPathData {
ImplTrait,
/// A `typeof` type node.
Typeof,
/// GlobalMetaData identifies a piece of crate metadata that is global to
/// a whole crate (as opposed to just one item). GlobalMetaData components
/// are only supposed to show up right below the crate root.
GlobalMetaData(Ident)
}
#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug,
@ -427,8 +433,8 @@ impl Definitions {
/// Get the number of definitions.
pub fn def_index_counts_lo_hi(&self) -> (usize, usize) {
(self.def_index_to_node[DefIndexAddressSpace::Low.index()].len(),
self.def_index_to_node[DefIndexAddressSpace::High.index()].len())
(self.table.index_to_key[DefIndexAddressSpace::Low.index()].len(),
self.table.index_to_key[DefIndexAddressSpace::High.index()].len())
}
pub fn def_key(&self, index: DefIndex) -> DefKey {
@ -469,7 +475,12 @@ impl Definitions {
if def_id.krate == LOCAL_CRATE {
let space_index = def_id.index.address_space().index();
let array_index = def_id.index.as_array_index();
Some(self.def_index_to_node[space_index][array_index])
let node_id = self.def_index_to_node[space_index][array_index];
if node_id != ast::DUMMY_NODE_ID {
Some(node_id)
} else {
None
}
} else {
None
}
@ -498,12 +509,16 @@ impl Definitions {
// Create the definition.
let address_space = super::ITEM_LIKE_SPACE;
let index = self.table.allocate(key, def_path_hash, address_space);
let root_index = self.table.allocate(key, def_path_hash, address_space);
assert_eq!(root_index, CRATE_DEF_INDEX);
assert!(self.def_index_to_node[address_space.index()].is_empty());
self.def_index_to_node[address_space.index()].push(ast::CRATE_NODE_ID);
self.node_to_def_index.insert(ast::CRATE_NODE_ID, index);
self.node_to_def_index.insert(ast::CRATE_NODE_ID, root_index);
index
// Allocate some other DefIndices that always must exist.
GlobalMetaDataKind::allocate_def_indices(self);
root_index
}
/// Add a definition with a parent definition.
@ -550,13 +565,19 @@ impl Definitions {
assert_eq!(index.as_array_index(),
self.def_index_to_node[address_space.index()].len());
self.def_index_to_node[address_space.index()].push(node_id);
// Some things for which we allocate DefIndices don't correspond to
// anything in the AST, so they don't have a NodeId. For these cases
// we don't need a mapping from NodeId to DefIndex.
if node_id != ast::DUMMY_NODE_ID {
debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id);
self.node_to_def_index.insert(node_id, index);
}
if expansion.is_modern() {
self.expansions.insert(index, expansion);
}
debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id);
self.node_to_def_index.insert(node_id, index);
index
}
@ -594,7 +615,8 @@ impl DefPathData {
LifetimeDef(ident) |
EnumVariant(ident) |
Binding(ident) |
Field(ident) => Some(ident),
Field(ident) |
GlobalMetaData(ident) => Some(ident),
Impl |
CrateRoot |
@ -622,7 +644,8 @@ impl DefPathData {
LifetimeDef(ident) |
EnumVariant(ident) |
Binding(ident) |
Field(ident) => {
Field(ident) |
GlobalMetaData(ident) => {
return ident.name.as_str();
}
@ -667,3 +690,74 @@ impl ::std::hash::Hash for DefPathData {
}
}
}
// We define the GlobalMetaDataKind enum with this macro because we want to
// make sure that we exhaustively iterate over all variants when registering
// the corresponding DefIndices in the DefTable.
macro_rules! define_global_metadata_kind {
(pub enum GlobalMetaDataKind {
$($variant:ident),*
}) => (
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
RustcEncodable, RustcDecodable)]
pub enum GlobalMetaDataKind {
$($variant),*
}
impl GlobalMetaDataKind {
fn allocate_def_indices(definitions: &mut Definitions) {
$({
let instance = GlobalMetaDataKind::$variant;
definitions.create_def_with_parent(
CRATE_DEF_INDEX,
ast::DUMMY_NODE_ID,
DefPathData::GlobalMetaData(instance.ident()),
DefIndexAddressSpace::High,
Mark::root()
);
// Make sure calling def_index does not crash.
instance.def_index(&definitions.table);
})*
}
pub fn def_index(&self, def_path_table: &DefPathTable) -> DefIndex {
let def_key = DefKey {
parent: Some(CRATE_DEF_INDEX),
disambiguated_data: DisambiguatedDefPathData {
data: DefPathData::GlobalMetaData(self.ident()),
disambiguator: 0,
}
};
def_path_table.key_to_index[&def_key]
}
fn ident(&self) -> Ident {
let string = match *self {
$(
GlobalMetaDataKind::$variant => {
concat!("{{GlobalMetaData::", stringify!($variant), "}}")
}
)*
};
Ident::from_str(string)
}
}
)
}
define_global_metadata_kind!(pub enum GlobalMetaDataKind {
Krate,
CrateDeps,
DylibDependencyFormats,
LangItems,
LangItemsMissing,
NativeLibraries,
CodeMap,
Impls,
ExportedSymbols
});

View file

@ -23,7 +23,6 @@
// probably get a better home if someone can find one.
use hir::def;
use dep_graph::DepNode;
use hir::def_id::{CrateNum, DefId, DefIndex};
use hir::map as hir_map;
use hir::map::definitions::{Definitions, DefKey, DisambiguatedDefPathData,
@ -190,15 +189,14 @@ pub struct EncodedMetadataHash {
/// upstream crate.
#[derive(Debug, RustcEncodable, RustcDecodable, Clone)]
pub struct EncodedMetadataHashes {
pub entry_hashes: Vec<EncodedMetadataHash>,
pub global_hashes: Vec<(DepNode<()>, ich::Fingerprint)>,
// Stable content hashes for things in crate metadata, indexed by DefIndex.
pub hashes: Vec<EncodedMetadataHash>,
}
impl EncodedMetadataHashes {
pub fn new() -> EncodedMetadataHashes {
EncodedMetadataHashes {
entry_hashes: Vec::new(),
global_hashes: Vec::new(),
hashes: Vec::new(),
}
}
}

View file

@ -197,7 +197,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
data @ DefPathData::ClosureExpr |
data @ DefPathData::Binding(..) |
data @ DefPathData::ImplTrait |
data @ DefPathData::Typeof => {
data @ DefPathData::Typeof |
data @ DefPathData::GlobalMetaData(..) => {
let parent_def_id = self.parent_def_id(def_id).unwrap();
self.push_item_path(buffer, parent_def_id);
buffer.push(&data.as_interned_str());

View file

@ -126,10 +126,6 @@ pub struct SerializedMetadataHashes {
/// (matching the one found in this structure).
pub entry_hashes: Vec<EncodedMetadataHash>,
/// This map contains fingerprints that are not specific to some DefId but
/// describe something global to the whole crate.
pub global_hashes: Vec<(DepNode<()>, Fingerprint)>,
/// For each DefIndex (as it occurs in SerializedMetadataHash), this
/// map stores the DefPathIndex (as it occurs in DefIdDirectory), so
/// that we can find the new DefId for a SerializedMetadataHash in a

View file

@ -9,7 +9,7 @@
// except according to those terms.
use rustc::dep_graph::DepNode;
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE, CRATE_DEF_INDEX};
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc::hir::svh::Svh;
use rustc::ich::Fingerprint;
use rustc::ty::TyCtxt;
@ -29,9 +29,8 @@ use std::fmt::Debug;
pub struct HashContext<'a, 'tcx: 'a> {
pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
incremental_hashes_map: &'a IncrementalHashesMap,
item_metadata_hashes: FxHashMap<DefId, Fingerprint>,
metadata_hashes: FxHashMap<DefId, Fingerprint>,
crate_hashes: FxHashMap<CrateNum, Svh>,
global_metadata_hashes: FxHashMap<DepNode<DefId>, Fingerprint>,
}
impl<'a, 'tcx> HashContext<'a, 'tcx> {
@ -41,9 +40,8 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
HashContext {
tcx: tcx,
incremental_hashes_map: incremental_hashes_map,
item_metadata_hashes: FxHashMap(),
metadata_hashes: FxHashMap(),
crate_hashes: FxHashMap(),
global_metadata_hashes: FxHashMap(),
}
}
@ -53,8 +51,7 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
DepNode::Hir(_) |
DepNode::HirBody(_) =>
true,
DepNode::MetaData(def_id) |
DepNode::GlobalMetaData(def_id, _) => !def_id.is_local(),
DepNode::MetaData(def_id) => !def_id.is_local(),
_ => false,
}
}
@ -83,13 +80,7 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
DepNode::MetaData(def_id) if !def_id.is_local() => {
Some(self.metadata_hash(def_id,
def_id.krate,
|this| &mut this.item_metadata_hashes))
}
DepNode::GlobalMetaData(def_id, kind) => {
Some(self.metadata_hash(DepNode::GlobalMetaData(def_id, kind),
def_id.krate,
|this| &mut this.global_metadata_hashes))
|this| &mut this.metadata_hashes))
}
_ => {
@ -217,27 +208,11 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
let def_id = DefId { krate: cnum, index: serialized_hash.def_index };
// record the hash for this dep-node
let old = self.item_metadata_hashes.insert(def_id, serialized_hash.hash);
let old = self.metadata_hashes.insert(def_id, serialized_hash.hash);
debug!("load_from_data: def_id={:?} hash={}", def_id, serialized_hash.hash);
assert!(old.is_none(), "already have hash for {:?}", def_id);
}
for (dep_node, fingerprint) in serialized_hashes.global_hashes {
// Here we need to remap the CrateNum in the DepNode.
let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
let dep_node = match dep_node {
DepNode::GlobalMetaData(_, kind) => DepNode::GlobalMetaData(def_id, kind),
other => {
bug!("unexpected DepNode variant: {:?}", other)
}
};
// record the hash for this dep-node
debug!("load_from_data: def_node={:?} hash={}", dep_node, fingerprint);
let old = self.global_metadata_hashes.insert(dep_node.clone(), fingerprint);
assert!(old.is_none(), "already have hash for {:?}", dep_node);
}
Ok(())
}
}

View file

@ -255,9 +255,11 @@ pub fn encode_metadata_hashes(tcx: TyCtxt,
current_metadata_hashes: &mut FxHashMap<DefId, Fingerprint>,
encoder: &mut Encoder)
-> io::Result<()> {
assert_eq!(metadata_hashes.hashes.len(),
metadata_hashes.hashes.iter().map(|x| (x.def_index, ())).collect::<FxHashMap<_,_>>().len());
let mut serialized_hashes = SerializedMetadataHashes {
entry_hashes: metadata_hashes.entry_hashes.to_vec(),
global_hashes: metadata_hashes.global_hashes.to_vec(),
entry_hashes: metadata_hashes.hashes.to_vec(),
index_map: FxHashMap()
};

View file

@ -14,8 +14,7 @@ use cstore::{self, CStore, CrateSource, MetadataBlob};
use locator::{self, CratePaths};
use schema::{CrateRoot, Tracked};
use rustc::dep_graph::{DepNode, GlobalMetaDataKind};
use rustc::hir::def_id::{DefId, CrateNum, DefIndex, CRATE_DEF_INDEX};
use rustc::hir::def_id::{CrateNum, DefIndex};
use rustc::hir::svh::Svh;
use rustc::middle::cstore::DepKind;
use rustc::session::Session;
@ -516,14 +515,11 @@ impl<'a> CrateLoader<'a> {
return cstore::CrateNumMap::new();
}
let dep_node = DepNode::GlobalMetaData(DefId { krate, index: CRATE_DEF_INDEX },
GlobalMetaDataKind::CrateDeps);
// The map from crate numbers in the crate we're resolving to local crate numbers.
// We map 0 and all other holes in the map to our parent crate. The "additional"
// self-dependencies should be harmless.
::std::iter::once(krate).chain(crate_root.crate_deps
.get(&self.sess.dep_graph, dep_node)
.get_untracked()
.decode(metadata)
.map(|dep| {
debug!("resolving dep crate {} hash: `{}`", dep.name, dep.hash);

View file

@ -13,9 +13,9 @@
use schema::{self, Tracked};
use rustc::dep_graph::{DepGraph, DepNode, GlobalMetaDataKind};
use rustc::dep_graph::DepGraph;
use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefIndex, DefId};
use rustc::hir::map::definitions::DefPathTable;
use rustc::hir::map::definitions::{DefPathTable, GlobalMetaDataKind};
use rustc::hir::svh::Svh;
use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader};
use rustc_back::PanicStrategy;
@ -304,12 +304,7 @@ impl CrateMetadata {
}
pub fn panic_strategy(&self, dep_graph: &DepGraph) -> PanicStrategy {
let def_id = DefId {
krate: self.cnum,
index: CRATE_DEF_INDEX,
};
let dep_node = DepNode::GlobalMetaData(def_id, GlobalMetaDataKind::Krate);
let dep_node = self.metadata_dep_node(GlobalMetaDataKind::Krate);
self.root
.panic_strategy
.get(dep_graph, dep_node)

View file

@ -23,9 +23,9 @@ use rustc::ty::{self, TyCtxt};
use rustc::ty::maps::Providers;
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc::dep_graph::{DepNode, GlobalMetaDataKind};
use rustc::dep_graph::{DepNode};
use rustc::hir::map::{DefKey, DefPath, DisambiguatedDefPathData, DefPathHash};
use rustc::hir::map::definitions::DefPathTable;
use rustc::hir::map::definitions::{DefPathTable, GlobalMetaDataKind};
use rustc::util::nodemap::{NodeSet, DefIdMap};
use rustc_back::PanicStrategy;

View file

@ -13,8 +13,9 @@
use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary};
use schema::*;
use rustc::dep_graph::{DepGraph, DepNode, GlobalMetaDataKind};
use rustc::dep_graph::{DepGraph, DepNode};
use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
use rustc::hir::map::definitions::GlobalMetaDataKind;
use rustc::hir;
use rustc::middle::cstore::LinkagePreference;
@ -993,12 +994,8 @@ impl<'a, 'tcx> CrateMetadata {
pub fn get_dylib_dependency_formats(&self,
dep_graph: &DepGraph)
-> Vec<(CrateNum, LinkagePreference)> {
let def_id = DefId {
krate: self.cnum,
index: CRATE_DEF_INDEX,
};
let dep_node = DepNode::GlobalMetaData(def_id,
GlobalMetaDataKind::DylibDependencyFormats);
let dep_node =
self.metadata_dep_node(GlobalMetaDataKind::DylibDependencyFormats);
self.root
.dylib_dependency_formats
.get(dep_graph, dep_node)
@ -1198,11 +1195,7 @@ impl<'a, 'tcx> CrateMetadata {
}
pub fn metadata_dep_node(&self, kind: GlobalMetaDataKind) -> DepNode<DefId> {
let def_id = DefId {
krate: self.cnum,
index: CRATE_DEF_INDEX,
};
DepNode::GlobalMetaData(def_id, kind)
let def_index = kind.def_index(&self.def_path_table);
DepNode::MetaData(self.local_def_id(def_index))
}
}

View file

@ -14,10 +14,10 @@ use isolated_encoder::IsolatedEncoder;
use schema::*;
use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary,
EncodedMetadata, EncodedMetadataHashes};
EncodedMetadata, EncodedMetadataHashes,
EncodedMetadataHash};
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LOCAL_CRATE};
use rustc::hir::map::definitions::DefPathTable;
use rustc::dep_graph::{DepNode, GlobalMetaDataKind};
use rustc::hir::map::definitions::{DefPathTable, GlobalMetaDataKind};
use rustc::ich::Fingerprint;
use rustc::middle::dependency_format::Linkage;
use rustc::middle::lang_items;
@ -244,7 +244,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// Encodes something that corresponds to a single DepNode::GlobalMetaData
// and registers the Fingerprint in the `metadata_hashes` map.
pub fn tracked<'x, DATA, R>(&'x mut self,
dep_node: DepNode<()>,
def_index: DefIndex,
op: fn(&mut IsolatedEncoder<'x, 'a, 'tcx>, DATA) -> R,
data: DATA)
-> Tracked<R> {
@ -253,7 +253,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let (fingerprint, this) = entry_builder.finish();
if let Some(fingerprint) = fingerprint {
this.metadata_hashes.global_hashes.push((dep_node, fingerprint));
this.metadata_hashes.hashes.push(EncodedMetadataHash {
def_index,
hash: fingerprint,
})
}
Tracked::new(ret)
@ -322,12 +325,17 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
let mut i = self.position();
let tcx = self.tcx;
let global_metadata_def_index = move |kind: GlobalMetaDataKind| {
kind.def_index(tcx.hir.definitions().def_path_table())
};
let crate_deps = self.tracked(
DepNode::GlobalMetaData((), GlobalMetaDataKind::CrateDeps),
global_metadata_def_index(GlobalMetaDataKind::CrateDeps),
IsolatedEncoder::encode_crate_deps,
());
let dylib_dependency_formats = self.tracked(
DepNode::GlobalMetaData((), GlobalMetaDataKind::DylibDependencyFormats),
global_metadata_def_index(GlobalMetaDataKind::DylibDependencyFormats),
IsolatedEncoder::encode_dylib_dependency_formats,
());
let dep_bytes = self.position() - i;
@ -335,12 +343,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// Encode the language items.
i = self.position();
let lang_items = self.tracked(
DepNode::GlobalMetaData((), GlobalMetaDataKind::LangItems),
global_metadata_def_index(GlobalMetaDataKind::LangItems),
IsolatedEncoder::encode_lang_items,
());
let lang_items_missing = self.tracked(
DepNode::GlobalMetaData((), GlobalMetaDataKind::LangItemsMissing),
global_metadata_def_index(GlobalMetaDataKind::LangItemsMissing),
IsolatedEncoder::encode_lang_items_missing,
());
let lang_item_bytes = self.position() - i;
@ -348,7 +356,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// Encode the native libraries used
i = self.position();
let native_libraries = self.tracked(
DepNode::GlobalMetaData((), GlobalMetaDataKind::NativeLibraries),
global_metadata_def_index(GlobalMetaDataKind::NativeLibraries),
IsolatedEncoder::encode_native_libraries,
());
let native_lib_bytes = self.position() - i;
@ -366,7 +374,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// Encode the def IDs of impls, for coherence checking.
i = self.position();
let impls = self.tracked(
DepNode::GlobalMetaData((), GlobalMetaDataKind::Impls),
global_metadata_def_index(GlobalMetaDataKind::Impls),
IsolatedEncoder::encode_impls,
());
let impl_bytes = self.position() - i;
@ -374,7 +382,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// Encode exported symbols info.
i = self.position();
let exported_symbols = self.tracked(
DepNode::GlobalMetaData((), GlobalMetaDataKind::ExportedSymbols),
global_metadata_def_index(GlobalMetaDataKind::ExportedSymbols),
IsolatedEncoder::encode_exported_symbols,
self.exported_symbols);
let exported_symbols_bytes = self.position() - i;
@ -422,10 +430,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let total_bytes = self.position();
self.metadata_hashes.global_hashes.push((
DepNode::GlobalMetaData((), GlobalMetaDataKind::Krate),
Fingerprint::from_smaller_hash(link_meta.crate_hash.as_u64())
));
self.metadata_hashes.hashes.push(EncodedMetadataHash {
def_index: global_metadata_def_index(GlobalMetaDataKind::Krate),
hash: Fingerprint::from_smaller_hash(link_meta.crate_hash.as_u64())
});
if self.tcx.sess.meta_stats() {
let mut zero_bytes = 0;

View file

@ -135,7 +135,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
let (fingerprint, ecx) = entry_builder.finish();
if let Some(hash) = fingerprint {
ecx.metadata_hashes.entry_hashes.push(EncodedMetadataHash {
ecx.metadata_hashes.hashes.push(EncodedMetadataHash {
def_index: id.index,
hash: hash,
});