Moved from using BigInt in set hash to u64, which is guaranteed to be of constant size - u64 seems easier than usize as it's the same size across all platforms.

This commit is contained in:
Matthew Constable
2019-02-09 21:57:26 +00:00
parent cca16ff597
commit 9271bfcb84
2 changed files with 17 additions and 14 deletions

View File

@@ -11,10 +11,11 @@ use super::objiter;
use super::objstr;
use super::objint;
use super::objtype;
use num_bigint::BigInt;
use std::hash::{Hash, Hasher};
use std::collections::HashMap;
use std::collections::hash_map::DefaultHasher;
pub fn get_elements(obj: &PyObjectRef) -> HashMap<BigInt, PyObjectRef> {
pub fn get_elements(obj: &PyObjectRef) -> HashMap<u64, PyObjectRef> {
if let PyObjectPayload::Set { elements } = &obj.borrow().payload {
elements.clone()
} else {
@@ -24,31 +25,33 @@ pub fn get_elements(obj: &PyObjectRef) -> HashMap<BigInt, PyObjectRef> {
fn perform_action_with_hash(
vm: &mut VirtualMachine,
elements: &mut HashMap<BigInt, PyObjectRef>,
elements: &mut HashMap<u64, PyObjectRef>,
item: &PyObjectRef,
f: &Fn(
&mut VirtualMachine,
&mut HashMap<BigInt, PyObjectRef>,
BigInt,
&mut HashMap<u64, PyObjectRef>,
u64,
&PyObjectRef,
) -> PyResult,
) -> PyResult {
let hash: PyObjectRef = vm.call_method(item, "__hash__", vec![])?;
let hash_value = objint::get_value(&hash);
let key = hash_value.clone();
let mut hasher = DefaultHasher::new();
hash_value.hash(&mut hasher);
let key = hasher.finish();
f(vm, elements, key, item)
}
fn insert_into_set(
vm: &mut VirtualMachine,
elements: &mut HashMap<BigInt, PyObjectRef>,
elements: &mut HashMap<u64, PyObjectRef>,
item: &PyObjectRef,
) -> PyResult {
fn insert(
vm: &mut VirtualMachine,
elements: &mut HashMap<BigInt, PyObjectRef>,
key: BigInt,
elements: &mut HashMap<u64, PyObjectRef>,
key: u64,
value: &PyObjectRef,
) -> PyResult {
elements.insert(key, value.clone());
@@ -85,8 +88,8 @@ fn set_remove(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
PyObjectPayload::Set { ref mut elements } => {
fn remove(
vm: &mut VirtualMachine,
elements: &mut HashMap<BigInt, PyObjectRef>,
key: BigInt,
elements: &mut HashMap<u64, PyObjectRef>,
key: u64,
value: &PyObjectRef,
) -> PyResult {
match elements.remove(&key) {
@@ -116,7 +119,7 @@ fn set_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
return Err(vm.new_type_error(format!("{} is not a subtype of set", cls.borrow())));
}
let elements: HashMap<BigInt, PyObjectRef> = match iterable {
let elements: HashMap<u64, PyObjectRef> = match iterable {
None => HashMap::new(),
Some(iterable) => {
let mut elements = HashMap::new();

View File

@@ -491,7 +491,7 @@ impl PyContext {
pub fn new_set(&self) -> PyObjectRef {
// Initialized empty, as calling __hash__ is required for adding each object to the set
// which requires a VM context - this is done in the objset code itself.
let elements: HashMap<BigInt, PyObjectRef> = HashMap::new();
let elements: HashMap<u64, PyObjectRef> = HashMap::new();
PyObject::new(PyObjectPayload::Set { elements: elements }, self.set_type())
}
@@ -909,7 +909,7 @@ pub enum PyObjectPayload {
elements: objdict::DictContentType,
},
Set {
elements: HashMap<BigInt, PyObjectRef>,
elements: HashMap<u64, PyObjectRef>,
},
Iterator {
position: usize,