diff --git a/src/obj/int.rs b/src/obj/int.rs index 87cfc2c..22cad9d 100644 --- a/src/obj/int.rs +++ b/src/obj/int.rs @@ -4,11 +4,21 @@ use crate::{ }; use once_cell::sync::Lazy; use shredder::Scan; -use std::fmt::{self, Debug, Formatter}; +use std::{collections::HashMap, fmt::{self, Debug, Formatter}, sync::Mutex}; +/// Integer object ref type alias. pub type IntRef = ObjRef; + +/// The native integer value type alias. pub type IntValue = i128; +const INT_MIN_CACHE: IntValue = -1; +const INT_MAX_CACHE: IntValue = 255; +static INT_VALUE_CACHE: Lazy>> = Lazy::new(|| + Default::default() +); + +/// Integer object. #[derive(Scan)] pub struct Int { value: IntValue, @@ -17,8 +27,25 @@ pub struct Int { } impl Int { - pub fn new_obj(value: IntValue) -> ObjRef { - // TODO(cache) : cache int values + /// Create a newly allocated integer object on the heap. + /// + /// This will look up the integer in the local cache of integers and return the cached value. + pub fn new_obj(value: IntValue) -> IntRef { + // before making the int value, check if it exists in the cache + if value >= INT_MIN_CACHE && value <= INT_MAX_CACHE { + let mut cache = INT_VALUE_CACHE.lock().unwrap(); + cache.entry(value) + .or_insert_with(|| Int::new_obj_uncached(value)) + .clone() + } else { + Int::new_obj_uncached(value) + } + } + + /// Create a newly allocated integer object on the heap. + /// + /// This will look up the integer in the local cache of integers. + pub fn new_obj_uncached(value: IntValue) -> IntRef { self_referring_obj! { Self { value,