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

Implement cache #4

Open
jcs090218 opened this issue May 22, 2022 · 1 comment
Open

Implement cache #4

jcs090218 opened this issue May 22, 2022 · 1 comment

Comments

@jcs090218
Copy link
Member

jcs090218 commented May 22, 2022

Original discussed in jcs-elpa/flx-rs#3

Here is another attempt to implement feature cache, see #3. I am not a rust expert, so I always look for improvement or better attempts.

@jojojames
Copy link

Throwing in what I had:

pub static STRING_CACHE: HashMap<&str, FlxStrInfo> = HashMap::new();

#[derive(Clone)]
pub struct FlxStrInfo {
    // Generated through get_hash_for_string
    hash_for_string: HashMap<Option<u32>, VecDeque<Option<u32>>>,

    // Something that get_heatmap_str would return.
    heatmap: Vec<i32>,
}

impl FlxStrInfo {
    fn new() -> FlxStrInfo {
        FlxStrInfo {
            hash_for_string: HashMap::new(),
            heatmap: Vec::new(),
        }
    }
}

fn get_hash_for_string_2(
    hash: &mut FlxStrInfo,
    str: &str,
) {
    let mut result: HashMap<Option<u32>, VecDeque<Option<u32>>> = HashMap::new();
    let str_len: i32 = str.len() as i32;
    let mut index: i32 = str_len - 1;
    let mut char: Option<u32>;
    let mut down_char: Option<u32>;

    while 0 <= index {
        char = Some(str.chars().nth(index as usize).unwrap() as u32);

        if capital(char) {
            result
                .entry(char)
                .or_insert_with(VecDeque::new)
                .push_front(Some(index as u32));
            let valid: Option<char> = char::from_u32(char.unwrap());
            down_char = Some(valid.unwrap().to_lowercase().next().unwrap() as u32);
        } else {
            down_char = char;
        }

        result
            .entry(down_char)
            .or_insert_with(VecDeque::new)
            .push_front(Some(index as u32));

        index -= 1;
    }

    let mut heatmap: Vec<i32> = Vec::new();
    get_heatmap_str(&mut heatmap, str, None);

    hash.hash_for_string = result;
    hash.heatmap = heatmap;
}

pub fn flx_make_string_cache<'a>() -> HashMap<&'a str, FlxStrInfo> {
    return HashMap::new();
}

pub fn flx_process_cache<'a>(
    str: &'a str,
    cache: Option<&'a mut HashMap<&'a str, FlxStrInfo>>,
) -> FlxStrInfo {
    match cache {
        Some(c) => {
            match c.get(str).cloned() {
                Some(v) => {
                    return v;
                }

                None => {
                    let mut str_info: FlxStrInfo = FlxStrInfo::new();
                    get_hash_for_string_2(&mut str_info, str);
                    // FIXME: These clones are probably not good...
                    c.insert(str, str_info.clone());
                    return str_info.clone();
                }
            }
        }

        None => {
            let mut str_info: FlxStrInfo = FlxStrInfo::new();
            get_hash_for_string_2(&mut str_info, str);
            return str_info;
        }
    }
}

From looking at the original implementation's hash map, it looks like it stores three things, heatmap-func, heatmap, and the hash_for_strings value.

I was struggling with some of the rust syntax around optionals and maybe this looks to be what I'm looking for.

_cache.get(str).unwrap().clone();

The biggest thing is trying to figure out how to set up a static cache in the flx-rs library. Maybe allowing the elisp side to send the hashmap down will work but I'm not sure about pulling/pushing in values to the map from the lisp side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants