From 4337ab3b0783a3df12ba8ebde2c6c9ec667a86a5 Mon Sep 17 00:00:00 2001 From: Matthieu Vachon Date: Fri, 29 Jul 2022 15:46:36 -0400 Subject: [PATCH] Updated store and state methods to accept `key` of type `AsRef` --- docs/release-notes/change-log.md | 52 +++++++++++ rust/substreams/src/state.rs | 151 ++++++++++++++++--------------- rust/substreams/src/store.rs | 62 ++++++------- 3 files changed, 159 insertions(+), 106 deletions(-) diff --git a/docs/release-notes/change-log.md b/docs/release-notes/change-log.md index f7a51011b..69b7476ad 100644 --- a/docs/release-notes/change-log.md +++ b/docs/release-notes/change-log.md @@ -8,6 +8,58 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), **New updatePolicy `append`**, allows one to build a store that concatenates values and supports parallelism. This affects the server, the manifest format (additive only), the substreams crate and the generated code therein. +### Rust API + +- Store APIs methods now accept `key` of type `AsRef` which means for example that both `String` an `&str` are accepted as inputs in: + + - `StoreSet::set` + - `StoreSet::set_many` + - `StoreSet::set_if_not_exists` + - `StoreSet::set_if_not_exists_many` + - `StoreAddInt64::add` + - `StoreAddInt64::add_many` + - `StoreAddFloat64::add` + - `StoreAddFloat64::add_many` + - `StoreAddBigFloat::add` + - `StoreAddBigFloat::add_many` + - `StoreAddBigInt::add` + - `StoreAddBigInt::add_many` + - `StoreMaxInt64::max` + - `StoreMaxFloat64::max` + - `StoreMaxBigInt::max` + - `StoreMaxBigFloat::max` + - `StoreMinInt64::min` + - `StoreMinFloat64::min` + - `StoreMinBigInt::min` + - `StoreMinBigFloat::min` + - `StoreAppend::append` + - `StoreAppend::append_bytes` + - `StoreGet::get_at` + - `StoreGet::get_last` + - `StoreGet::get_first` + +- Low-level state methods now accept `key` of type `AsRef` which means for example that both `String` an `&str` are accepted as inputs in: + + - `state::get_at` + - `state::get_last` + - `state::get_first` + - `state::set` + - `state::set_if_not_exists` + - `state::append` + - `state::delete_prefix` + - `state::add_bigint` + - `state::add_int64` + - `state::add_float64` + - `state::add_bigfloat` + - `state::set_min_int64` + - `state::set_min_bigint` + - `state::set_min_float64` + - `state::set_min_bigfloat` + - `state::set_max_int64` + - `state::set_max_bigint` + - `state::set_max_float64` + - `state::set_max_bigfloat` + ### CLI * Changed the output modes: `module-*` modes are gone and become the diff --git a/rust/substreams/src/state.rs b/rust/substreams/src/state.rs index 72c7332d6..a4e283354 100644 --- a/rust/substreams/src/state.rs +++ b/rust/substreams/src/state.rs @@ -1,9 +1,11 @@ use crate::externs; use crate::memory; -use num_bigint::{BigInt}; use bigdecimal::BigDecimal; +use num_bigint::BigInt; + +pub fn get_at>(store_idx: u32, ord: i64, key: K) -> Option> { + let key = key.as_ref(); -pub fn get_at(store_idx: u32, ord: i64, key: &String) -> Option> { unsafe { let key_bytes = key.as_bytes(); let output_ptr = memory::alloc(8); @@ -21,7 +23,9 @@ pub fn get_at(store_idx: u32, ord: i64, key: &String) -> Option> { }; } } -pub fn get_last(store_idx: u32, key: &String) -> Option> { +pub fn get_last>(store_idx: u32, key: K) -> Option> { + let key = key.as_ref(); + unsafe { let key_bytes = key.as_bytes(); let output_ptr = memory::alloc(8); @@ -39,7 +43,9 @@ pub fn get_last(store_idx: u32, key: &String) -> Option> { }; } } -pub fn get_first(store_idx: u32, key: &String) -> Option> { +pub fn get_first>(store_idx: u32, key: K) -> Option> { + let key = key.as_ref(); + unsafe { let key_bytes = key.as_bytes(); let output_ptr = memory::alloc(8); @@ -57,7 +63,9 @@ pub fn get_first(store_idx: u32, key: &String) -> Option> { }; } } -pub fn set(ord: i64, key: String, value: &Vec) { +pub fn set>(ord: i64, key: K, value: &Vec) { + let key = key.as_ref(); + unsafe { externs::state::set( ord, @@ -68,7 +76,9 @@ pub fn set(ord: i64, key: String, value: &Vec) { ) } } -pub fn set_if_not_exists(ord: i64, key: String, value: &Vec) { +pub fn set_if_not_exists>(ord: i64, key: K, value: &Vec) { + let key = key.as_ref(); + unsafe { externs::state::set_if_not_exists( ord, @@ -80,7 +90,9 @@ pub fn set_if_not_exists(ord: i64, key: String, value: &Vec) { } } -pub fn append(ord: i64, key: String, value: &Vec) { +pub fn append>(ord: i64, key: K, value: &Vec) { + let key = key.as_ref(); + unsafe { externs::state::append( ord, @@ -92,17 +104,16 @@ pub fn append(ord: i64, key: String, value: &Vec) { } } -pub fn delete_prefix(ord: i64, prefix: &String){ - unsafe { - externs::state::delete_prefix( - ord, - prefix.as_ptr(), - prefix.len() as u32, - ) - } +pub fn delete_prefix>(ord: i64, prefix: K) { + let prefix = prefix.as_ref(); + + unsafe { externs::state::delete_prefix(ord, prefix.as_ptr(), prefix.len() as u32) } } -pub fn add_bigint(ord: i64, key: String, value: &BigInt) { + +pub fn add_bigint>(ord: i64, key: K, value: &BigInt) { + let key = key.as_ref(); let data = value.to_string(); + unsafe { externs::state::add_bigint( ord, @@ -113,28 +124,22 @@ pub fn add_bigint(ord: i64, key: String, value: &BigInt) { ) } } -pub fn add_int64(ord: i64, key: String, value: i64) { - unsafe { - externs::state::add_int64( - ord, - key.as_ptr(), - key.len() as u32, - value, - ) - } +pub fn add_int64>(ord: i64, key: K, value: i64) { + let key = key.as_ref(); + + unsafe { externs::state::add_int64(ord, key.as_ptr(), key.len() as u32, value) } } -pub fn add_float64(ord: i64, key: String, value: f64) { - unsafe { - externs::state::add_float64( - ord, - key.as_ptr(), - key.len() as u32, - value - ) - } + +pub fn add_float64>(ord: i64, key: K, value: f64) { + let key = key.as_ref(); + + unsafe { externs::state::add_float64(ord, key.as_ptr(), key.len() as u32, value) } } -pub fn add_bigfloat(ord: i64, key: String, value: &BigDecimal) { + +pub fn add_bigfloat>(ord: i64, key: K, value: &BigDecimal) { + let key = key.as_ref(); let data = value.to_string(); + unsafe { externs::state::add_bigfloat( ord, @@ -145,18 +150,17 @@ pub fn add_bigfloat(ord: i64, key: String, value: &BigDecimal) { ) } } -pub fn set_min_int64(ord: i64, key: String, value: i64) { - unsafe { - externs::state::set_min_int64( - ord, - key.as_ptr(), - key.len() as u32, - value, - ) - } + +pub fn set_min_int64>(ord: i64, key: K, value: i64) { + let key = key.as_ref(); + + unsafe { externs::state::set_min_int64(ord, key.as_ptr(), key.len() as u32, value) } } -pub fn set_min_bigint(ord: i64, key: String, value: &BigInt) { + +pub fn set_min_bigint>(ord: i64, key: K, value: &BigInt) { + let key = key.as_ref(); let data = value.to_string(); + unsafe { externs::state::set_min_bigint( ord, @@ -167,18 +171,17 @@ pub fn set_min_bigint(ord: i64, key: String, value: &BigInt) { ) } } -pub fn set_min_float64(ord: i64, key: String, value: f64) { - unsafe { - externs::state::set_min_float64( - ord, - key.as_ptr(), - key.len() as u32, - value, - ) - } + +pub fn set_min_float64>(ord: i64, key: K, value: f64) { + let key = key.as_ref(); + + unsafe { externs::state::set_min_float64(ord, key.as_ptr(), key.len() as u32, value) } } -pub fn set_min_bigfloat(ord: i64, key: String, value: &BigDecimal) { + +pub fn set_min_bigfloat>(ord: i64, key: K, value: &BigDecimal) { + let key = key.as_ref(); let data = value.to_string(); + unsafe { externs::state::set_min_bigfloat( ord, @@ -189,18 +192,17 @@ pub fn set_min_bigfloat(ord: i64, key: String, value: &BigDecimal) { ) } } -pub fn set_max_int64(ord: i64, key: String, value: i64) { - unsafe { - externs::state::set_max_int64( - ord, - key.as_ptr(), - key.len() as u32, - value, - ) - } + +pub fn set_max_int64>(ord: i64, key: K, value: i64) { + let key = key.as_ref(); + + unsafe { externs::state::set_max_int64(ord, key.as_ptr(), key.len() as u32, value) } } -pub fn set_max_bigint(ord: i64, key: String, value: &BigInt) { + +pub fn set_max_bigint>(ord: i64, key: K, value: &BigInt) { + let key = key.as_ref(); let data = value.to_string(); + unsafe { externs::state::set_max_bigint( ord, @@ -211,18 +213,17 @@ pub fn set_max_bigint(ord: i64, key: String, value: &BigInt) { ) } } -pub fn set_max_float64(ord: i64, key: String, value: f64) { - unsafe { - externs::state::set_max_float64( - ord, - key.as_ptr(), - key.len() as u32, - value, - ) - } + +pub fn set_max_float64>(ord: i64, key: K, value: f64) { + let key = key.as_ref(); + + unsafe { externs::state::set_max_float64(ord, key.as_ptr(), key.len() as u32, value) } } -pub fn set_max_bigfloat(ord: i64, key: String, value: &BigDecimal) { + +pub fn set_max_bigfloat>(ord: i64, key: K, value: &BigDecimal) { + let key = key.as_ref(); let data = value.to_string(); + unsafe { externs::state::set_max_bigfloat( ord, diff --git a/rust/substreams/src/store.rs b/rust/substreams/src/store.rs index dbf296788..2c260bf06 100644 --- a/rust/substreams/src/store.rs +++ b/rust/substreams/src/store.rs @@ -19,14 +19,14 @@ pub type Deltas = Vec; pub struct StoreSet {} impl StoreSet { /// Set a given key to a given value, if the key existed before, it will be replaced. - pub fn set(&self, ord: u64, key: String, value: &Vec) { + pub fn set>(&self, ord: u64, key: K, value: &Vec) { state::set(ord as i64, key, value); } /// Set many keys to a given values, if the key existed before, it will be replaced. - pub fn set_many(&self, ord: u64, keys: &Vec, value: &Vec) { + pub fn set_many>(&self, ord: u64, keys: &Vec, value: &Vec) { for key in keys { - state::set(ord as i64, key.to_string(), value); + state::set(ord as i64, key, value); } } } @@ -37,14 +37,14 @@ impl StoreSet { pub struct StoreSetIfNotExists {} impl StoreSetIfNotExists { /// Set a given key to a given value, if the key existed before, it will be ignored and not set. - pub fn set_if_not_exists(&self, ord: u64, key: String, value: &Vec) { + pub fn set_if_not_exists>(&self, ord: u64, key: K, value: &Vec) { state::set_if_not_exists(ord as i64, key, value); } /// Set given keys to given values, if the key existed before, it will be ignored and not set. - pub fn set_if_not_exists_many(&self, ord: u64, keys: &Vec, value: &Vec) { + pub fn set_if_not_exists_many>(&self, ord: u64, keys: &Vec, value: &Vec) { for key in keys { - state::set_if_not_exists(ord as i64, key.to_string(), value); + state::set_if_not_exists(ord as i64, key, value); } } } @@ -56,15 +56,15 @@ pub struct StoreAddInt64 {} impl StoreAddInt64 { /// Will add the value to the already present value at the key (or default to /// zero if the key was not set) - pub fn add(&self, ord: u64, key: String, value: i64) { + pub fn add>(&self, ord: u64, key: K, value: i64) { state::add_int64(ord as i64, key, value); } /// Will add the value to the already present value of the keys (or default to /// zero if the key was not set) - pub fn add_many(&self, ord: u64, keys: &Vec, value: i64) { + pub fn add_many>(&self, ord: u64, keys: &Vec, value: i64) { for key in keys { - state::add_int64(ord as i64, key.to_string(), value); + state::add_int64(ord as i64, key, value); } } } @@ -76,15 +76,15 @@ pub struct StoreAddFloat64 {} impl StoreAddFloat64 { /// Will add the value to the already present value at the key (or default to /// zero if the key was not set) - pub fn add(&self, ord: u64, key: String, value: f64) { + pub fn add>(&self, ord: u64, key: K, value: f64) { state::add_float64(ord as i64, key, value); } /// Will add the value to the already present value of the keys (or default to /// zero if the key was not set) - pub fn add_many(&self, ord: u64, keys: &Vec, value: f64) { + pub fn add_many>(&self, ord: u64, keys: &Vec, value: f64) { for key in keys { - state::add_float64(ord as i64, key.to_string(), value); + state::add_float64(ord as i64, key, value); } } } @@ -96,15 +96,15 @@ pub struct StoreAddBigFloat {} impl StoreAddBigFloat { /// Will add the value to the already present value at the key (or default to /// zero if the key was not set) - pub fn add(&self, ord: u64, key: String, value: &BigDecimal) { + pub fn add>(&self, ord: u64, key: K, value: &BigDecimal) { state::add_bigfloat(ord as i64, key, value); } /// Will add the value to the already present value of the keys (or default to /// zero if the key was not set) - pub fn add_many(&self, ord: u64, keys: &Vec, value: &BigDecimal) { + pub fn add_many>(&self, ord: u64, keys: &Vec, value: &BigDecimal) { for key in keys { - state::add_bigfloat(ord as i64, key.to_string(), value); + state::add_bigfloat(ord as i64, key, value); } } } @@ -116,15 +116,15 @@ pub struct StoreAddBigInt {} impl StoreAddBigInt { /// Will add the value to the already present value of the keys (or default to /// zero if the key was not set) - pub fn add(&self, ord: u64, key: String, value: &BigInt) { + pub fn add>(&self, ord: u64, key: K, value: &BigInt) { state::add_bigint(ord as i64, key, value); } /// Will add the value to the already present value of the keys (or default to /// zero if the key was not set) - pub fn add_many(&self, ord: u64, keys: &Vec, value: &BigInt) { + pub fn add_many>(&self, ord: u64, keys: &Vec, value: &BigInt) { for key in keys { - state::add_bigint(ord as i64, key.to_string(), value); + state::add_bigint(ord as i64, key, value); } } } @@ -137,7 +137,7 @@ impl StoreMaxInt64 { /// max will set the provided key in the store only if the value received in /// parameter is bigger than the one already present in the store, with /// a default of the zero value when the key is absent. - pub fn max(&self, ord: u64, key: String, value: i64) { + pub fn max>(&self, ord: u64, key: K, value: i64) { state::set_max_int64(ord as i64, key, value); } } @@ -150,7 +150,7 @@ impl StoreMaxBigInt { /// Will set the provided key in the store only if the value received in /// parameter is bigger than the one already present in the store, with /// a default of the zero value when the key is absent. - pub fn max(&self, ord: u64, key: String, value: &BigInt) { + pub fn max>(&self, ord: u64, key: K, value: &BigInt) { state::set_max_bigint(ord as i64, key, value); } } @@ -163,7 +163,7 @@ impl StoreMaxFloat64 { /// Will set the provided key in the store only if the value received in /// parameter is bigger than the one already present in the store, with /// a default of the zero value when the key is absent. - pub fn max(&self, ord: u64, key: String, value: f64) { + pub fn max>(&self, ord: u64, key: K, value: f64) { state::set_max_float64(ord as i64, key, value); } } @@ -176,7 +176,7 @@ impl StoreMaxBigFloat { /// Will set the provided key in the store only if the value received in /// parameter is bigger than the one already present in the store, with /// a default of the zero value when the key is absent. - pub fn max(&self, ord: u64, key: String, value: &BigDecimal) { + pub fn max>(&self, ord: u64, key: K, value: &BigDecimal) { state::set_max_bigfloat(ord as i64, key, value); } } @@ -189,7 +189,7 @@ impl StoreMinInt64 { /// Will set the provided key in the store only if the value received in /// parameter is smaller than the one already present in the store, with /// a default of the zero value when the key is absent. - pub fn min(&self, ord: u64, key: String, value: i64) { + pub fn min>(&self, ord: u64, key: K, value: i64) { state::set_min_int64(ord as i64, key, value); } } @@ -202,7 +202,7 @@ impl StoreMinBigInt { /// Will set the provided key in the store only if the value received in /// parameter is smaller than the one already present in the store, with /// a default of the zero value when the key is absent. - pub fn min(&self, ord: u64, key: String, value: &BigInt) { + pub fn min>(&self, ord: u64, key: K, value: &BigInt) { state::set_min_bigint(ord as i64, key, value); } } @@ -215,7 +215,7 @@ impl StoreMinFloat64 { /// Will set the provided key in the store only if the value received in /// parameter is smaller than the one already present in the store, with /// a default of the zero value when the key is absent. - pub fn min(&self, ord: u64, key: String, value: f64) { + pub fn min>(&self, ord: u64, key: K, value: f64) { state::set_min_float64(ord as i64, key, value); } } @@ -228,7 +228,7 @@ impl StoreMinBigFloat { /// Will set the provided key in the store only if the value received in /// parameter is smaller than the one already present in the store, with /// a default of the zero value when the key is absent. - pub fn min(&self, ord: u64, key: String, value: &BigDecimal) { + pub fn min>(&self, ord: u64, key: K, value: &BigDecimal) { state::set_min_bigfloat(ord as i64, key, value); } } @@ -239,12 +239,12 @@ impl StoreMinBigFloat { pub struct StoreAppend {} impl StoreAppend { /// Concatenates a given value at the end of the key's current value - pub fn append(&self, ord: u64, key: String, value: &String) { + pub fn append>(&self, ord: u64, key: K, value: &String) { state::append(ord as i64, key, &value.as_bytes().to_vec()); } /// Concatenates a given value at the end of the key's current value - pub fn append_bytes(&self, ord: u64, key: String, value: &Vec) { + pub fn append_bytes>(&self, ord: u64, key: K, value: &Vec) { state::append(ord as i64, key, value); } } @@ -265,7 +265,7 @@ impl StoreGet { /// the output section of the manifest. The ordinal is used here /// to go query a key that might have changed mid-block by /// the store module that built it. - pub fn get_at(&self, ord: u64, key: &String) -> Option> { + pub fn get_at>(&self, ord: u64, key: K) -> Option> { return state::get_at(self.idx, ord as i64, key); } @@ -273,7 +273,7 @@ impl StoreGet { /// the store as of the beginning of the block being processed, before any changes /// were applied within the current block. Tt does not need to rewind any changes /// in the middle of the block. - pub fn get_last(&self, key: &String) -> Option> { + pub fn get_last>(&self, key: K) -> Option> { return state::get_last(self.idx, key); } @@ -281,7 +281,7 @@ impl StoreGet { /// the store as of the beginning of the block being processed, before any changes /// were applied within the current block. However, it needs to unwind any keys that /// would have changed mid-block, so will be slightly less performant. - pub fn get_first(&self, key: &String) -> Option> { + pub fn get_first>(&self, key: K) -> Option> { return state::get_first(self.idx, key); } }