Skip to content

Commit 9c2a568

Browse files
committed
Very minor tweaks to Node creation
1 parent c0d7015 commit 9c2a568

File tree

2 files changed

+21
-16
lines changed

2 files changed

+21
-16
lines changed

src/object.rs

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,13 @@ impl Node {
115115
}
116116

117117
#[inline(always)]
118-
fn new(value: JsonValue) -> Node {
118+
fn new(value: JsonValue, hash: u64, len: usize) -> Node {
119119
unsafe {
120120
Node {
121121
key_buf: mem::uninitialized(),
122-
key_len: 0,
122+
key_len: len,
123123
key_ptr: mem::uninitialized(),
124-
key_hash: mem::uninitialized(),
124+
key_hash: hash,
125125
value: value,
126126
left: 0,
127127
right: 0,
@@ -134,20 +134,18 @@ impl Node {
134134
// `Node`, only once the `Node` is somewhere on the heap, a persisting
135135
// pointer to the key can be obtained.
136136
#[inline(always)]
137-
fn attach_key(&mut self, key: &[u8], hash: u64) {
138-
self.key_len = key.len();
139-
self.key_hash = hash;
140-
if key.len() <= KEY_BUF_LEN {
137+
fn attach_key(&mut self, key: &[u8]) {
138+
if self.key_len <= KEY_BUF_LEN {
141139
unsafe {
142140
ptr::copy_nonoverlapping(
143141
key.as_ptr(),
144142
self.key_buf.as_mut_ptr(),
145-
key.len()
143+
self.key_len
146144
);
147145
}
148146
self.key_ptr = self.key_buf.as_mut_ptr();
149147
} else {
150-
let mut heap: Vec<u8> = key.to_vec();
148+
let mut heap = key.to_vec();
151149
self.key_ptr = heap.as_mut_ptr();
152150
mem::forget(heap);
153151
}
@@ -270,22 +268,28 @@ impl Object {
270268
// the new node at the correct index without additional
271269
// capacity or bound checks.
272270
unsafe {
273-
let node = Node::new(value);
271+
let node = Node::new(value, hash, key.len());
274272
self.store.set_len(index + 1);
273+
274+
// To whomever gets concerned: I got better results with
275+
// copy than write. Difference in benchmarks wasn't big though.
275276
ptr::copy_nonoverlapping(
276277
&node as *const Node,
277278
self.store.as_mut_ptr().offset(index as isize),
278279
1,
279280
);
281+
280282
// Since the Node has been copied, we need to forget about
281283
// the owned value, else we may run into use after free.
282284
mem::forget(node);
283285
}
284-
self.node_at_index_mut(index).attach_key(key, hash);
286+
self.node_at_index_mut(index).attach_key(key);
285287
} else {
286-
self.store.push(Node::new(value));
287-
self.node_at_index_mut(index).attach_key(key, hash);
288+
self.store.push(Node::new(value, hash, key.len()));
289+
self.node_at_index_mut(index).attach_key(key);
288290

291+
// Index up to the index (old length), we don't need to fix
292+
// anything on the Node that just got pushed.
289293
for i in 0 .. index {
290294
self.node_at_index_mut(i).fix_key_ptr();
291295
}
@@ -303,8 +307,8 @@ impl Object {
303307
let hash = hash_key(key);
304308

305309
if self.store.len() == 0 {
306-
self.store.push(Node::new(value));
307-
self.store[0].attach_key(key, hash);
310+
self.store.push(Node::new(value, hash, key.len()));
311+
self.store[0].attach_key(key);
308312
return;
309313
}
310314

src/short.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ impl Short {
2020
/// Typically you should avoid creating your own `Short`s, instead create a
2121
/// `JsonValue` (either using `"foo".into()` or `JsonValue::from("foo")`) out
2222
/// of a slice. This will automatically decide on `String` or `Short` for you.
23-
#[inline]
23+
#[inline(always)]
2424
pub unsafe fn from_slice(slice: &str) -> Self {
2525
let mut short = Short {
2626
value: [0; MAX_LEN],
@@ -69,6 +69,7 @@ impl fmt::Display for Short {
6969
impl Deref for Short {
7070
type Target = str;
7171

72+
#[inline(always)]
7273
fn deref(&self) -> &str {
7374
self.as_str()
7475
}

0 commit comments

Comments
 (0)