Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix loadDerived not taking entity cache into consideration when loading derived entities #4799

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 51 additions & 3 deletions graph/src/components/store/entity_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,59 @@ impl EntityCache {
id_is_bytes: id_is_bytes,
};

// Get the entities from the store and insert it into the cache if it's not already there
let entities = self.store.get_derived(&query)?;
entities.iter().for_each(|(key, e)| {
self.current.insert(key.clone(), Some(e.clone()));

entities.iter().for_each(|(k, v)| {
// Only insert to the cache if it's not already there
incrypto32 marked this conversation as resolved.
Show resolved Hide resolved
if !self.current.contains_key(k) {
self.current.insert(k.clone(), Some(v.clone()));
incrypto32 marked this conversation as resolved.
Show resolved Hide resolved
}
});

// Insert `None` for entities that are not in the store and not in the current cache
// but are present in updates or handler_updates
// The updates will be applied before returning the entities
self.updates.iter().for_each(|(k, _)| {
if !self.current.contains_key(k) {
self.current.insert(k.clone(), None);
}
});
let entities: Vec<Entity> = entities.values().cloned().collect();

self.handler_updates.iter().for_each(|(k, _)| {
if !self.current.contains_key(k) {
self.current.insert(k.clone(), None);
}
});
incrypto32 marked this conversation as resolved.
Show resolved Hide resolved

// Retrieve the derived entities from the cache by filtering the cached entities.
// Include entities if either a matching value is found in the specified entity field
// as indicated by `query`, or if the entity is None.
let entities = self.current.iter().filter(|(key, entity)| {
key.entity_type == query.entity_type
&& entity.as_ref().map_or(true, |e| {
e.get(&query.entity_field.to_camel_case())
incrypto32 marked this conversation as resolved.
Show resolved Hide resolved
.map(|v| v.to_string() == query.value.to_string())
incrypto32 marked this conversation as resolved.
Show resolved Hide resolved
.unwrap_or(false)
})
});

let entities = entities
.filter_map(|(key, entity)| {
let mut entity: Option<Cow<'_, Entity>> = entity.to_owned().map(Cow::Owned);

if let Some(op) = self.updates.get(&key).cloned() {
op.apply_to(&mut entity).ok()?;
}

if let Some(op) = self.handler_updates.get(&key).cloned() {
op.apply_to(&mut entity).ok()?;
}

entity.map(|e| e.into_owned())
})
.collect();

Ok(entities)
}

Expand Down
6 changes: 6 additions & 0 deletions graph/src/util/lfu_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,12 @@ impl<K: Clone + Ord + Eq + Hash + Debug + CacheWeight, V: CacheWeight + Default>
})
}

pub fn iter<'a>(&'a self) -> impl Iterator<Item = (&K, &V)> {
self.queue
.iter()
.map(|entry| (&entry.0.key, &entry.0.value))
}

pub fn get(&mut self, key: &K) -> Option<&V> {
self.get_mut(key.clone()).map(|x| &x.value)
}
Expand Down
33 changes: 0 additions & 33 deletions tests/integration-tests/derived-loaders/abis/Contract.abi

This file was deleted.

34 changes: 0 additions & 34 deletions tests/integration-tests/derived-loaders/src/mapping.ts

This file was deleted.

120 changes: 0 additions & 120 deletions tests/integration-tests/derived-loaders/test/test.js

This file was deleted.

22 changes: 0 additions & 22 deletions tests/integration-tests/derived-loaders/truffle.js

This file was deleted.

15 changes: 15 additions & 0 deletions tests/runner-tests/derived-loaders/abis/Contract.abi
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "testCommand",
"type": "string"
}
],
"name": "TestEvent",
"type": "event"
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"deploy:test": "graph deploy test/derived-loaders --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI"
},
"devDependencies": {
"@graphprotocol/graph-cli": "0.51.0",
"@graphprotocol/graph-cli": "0.53.0",
"@graphprotocol/graph-ts": "0.31.0",
"solc": "^0.8.2"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
type BFoo @entity {
id: Bytes!
value: Int8!
bar: BBar! @derivedFrom(field: "fooValue")
bar: BBar @derivedFrom(field: "fooValue")
}

type BBar @entity {
Expand All @@ -12,10 +12,16 @@ type BBar @entity {
type Foo @entity {
id: ID!
value: Int8!
bar: Bar! @derivedFrom(field: "fooValue")
bar: Bar @derivedFrom(field: "fooValue")
}

type Bar @entity {
id: ID!
fooValue: Foo!
}

type TestResult @entity {
id: ID!
barDerived: String
bBarDerived: Bytes
}
Loading
Loading