Can stable storage structures and non-stable storage structures be mixed?

use ic_stable_structures::{DefaultMemoryImpl, StableBTreeMap, StableCell, RestrictedMemory};
use std::{cell::RefCell, collections::BTreeMap};

pub type RM = RestrictedMemory<DefaultMemoryImpl>;
pub const USER_PAGE_START: u64 = 64;

thread_local! {
    // Stable storage structure
    static STABLE_STORAGE_STRUCTURE: RefCell<StableBTreeMap<u64, u64, RM>> =
            RM::new(DefaultMemoryImpl::default(), USER_PAGE_START..STABLE_STORAGE_STRUCTURE_PAGE_END)

    // Non-stable storage structure
    static NON_STABLE_STORAGE_STRUCTURE: RefCell<BTreeMap<Principal, ic_cdk_timers::TimerId>> = RefCell::default();

Is it possible to use it this way?
Are there any potential problems?
Is it possible that unstable structural data will occupy the storage space of stable structural data?
What should I do if I want to store ic_cdk_timers::TimerId in a stable structure :sweat_smile:

1 Like

Yes you can have both heap and stable storage within the same canister, it’s what I do in Juno.

This sample from the stable structure repo shows a sample on how to have both:

Does that answer your question?

1 Like

I did a little workaround for storing the TimerId since it can’t implement CandidType.

I used bincode deserialization and serialization to store and retrieve from Stable storage when implementing the Storable trait, make sure you add the slotmap crate with serde feature enabled.

This what worked for me, any suggestions are welcome as well.

1 Like