From 29763449f0e0cc4e1be3b0847dd0920f5c68d823 Mon Sep 17 00:00:00 2001 From: Dominik Csapak Date: Wed, 16 Sep 2020 14:09:44 +0200 Subject: [PATCH] api-macro: fix broken binary ident search the 'properties_' list is sorted by the the literal string of a fieldname, but we binary-search for the 'ident_str' (which may be different, since we map '-' to '_' for example) by creating a hashmap to map from ident to index, we can do a simple lookup in that case that will work benchmarks showed no measurable performance difference Signed-off-by: Dominik Csapak --- proxmox-api-macro/src/api/mod.rs | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/proxmox-api-macro/src/api/mod.rs b/proxmox-api-macro/src/api/mod.rs index 2d2dada1..0071e81f 100644 --- a/proxmox-api-macro/src/api/mod.rs +++ b/proxmox-api-macro/src/api/mod.rs @@ -8,6 +8,7 @@ //! The handling of methods vs type definitions happens in their corresponding submodules. use std::convert::{TryFrom, TryInto}; +use std::collections::HashMap; use anyhow::Error; @@ -378,12 +379,14 @@ impl SchemaItem { /// Contains a sorted list of properties: pub struct SchemaObject { properties_: Vec<(FieldName, bool, Schema)>, + ident_hash: HashMap, } impl SchemaObject { pub fn new() -> Self { Self { properties_: Vec::new(), + ident_hash: HashMap::new(), } } @@ -394,6 +397,9 @@ impl SchemaObject { fn sort_properties(&mut self) { self.properties_.sort_by(|a, b| (a.0).cmp(&b.0)); + for (idx, prop) in self.properties_.iter().enumerate() { + self.ident_hash.insert(prop.0.as_ident_str().to_string(), idx); + } } fn try_extract_from(obj: &mut JSONObject) -> Result { @@ -422,6 +428,7 @@ impl SchemaObject { Ok(properties) }, )?, + ident_hash: HashMap::new(), }; this.sort_properties(); Ok(this) @@ -439,22 +446,16 @@ impl SchemaObject { } fn find_property_by_ident(&self, key: &str) -> Option<&(FieldName, bool, Schema)> { - match self - .properties_ - .binary_search_by(|p| p.0.as_ident_str().cmp(key)) - { - Ok(idx) => Some(&self.properties_[idx]), - Err(_) => None, + match self.ident_hash.get(key) { + Some(idx) => Some(&self.properties_[*idx]), + None => None, } } fn find_property_by_ident_mut(&mut self, key: &str) -> Option<&mut (FieldName, bool, Schema)> { - match self - .properties_ - .binary_search_by(|p| p.0.as_ident_str().cmp(key)) - { - Ok(idx) => Some(&mut self.properties_[idx]), - Err(_) => None, + match self.ident_hash.get(key) { + Some(idx) => Some(&mut self.properties_[*idx]), + None => None, } }