on master help sign in
Optimize space for DocumentId with NonZeroUsize (#1097)

Now Option<DocumentId> uses one byte rather than two

commit67bf4250caf14d3a632abdbfa367c04b318d782c authorIvan Tham <pickfire@riseup.net> dateThu 25 Nov 2021, 10:07 (5 years ago) parente8f800a
2 files changed+27−16
helix-view/src/editor.rs+15−14 helix-view/src/lib.rs+12−2
helix-view/src/editor.rs+15−14
@@ -11,6 +11,7 @@ use futures_util::future;
1111use std::{
1212 collections::BTreeMap,
1313 io::stdin,
14+ num::NonZeroUsize,
1415 path::{Path, PathBuf},
1516 pin::Pin,
1617 sync::Arc,
@@ -154,7 +155,7 @@ impl std::fmt::Debug for Motion {
154155#[derive(Debug)]
155156pub struct Editor {
156157 pub tree: Tree,
157− pub next_document_id: usize,
158+ pub next_document_id: DocumentId,
158159 pub documents: BTreeMap<DocumentId, Document>,
159160 pub count: Option<std::num::NonZeroUsize>,
160161 pub selected_register: Option<char>,
@@ -198,7 +199,8 @@ impl Editor {
198199
199200 Self {
200201 tree: Tree::new(area),
201− next_document_id: 0,
202+ // Safety: 1 is non-zero
203+ next_document_id: DocumentId::default(),
202204 documents: BTreeMap::new(),
203205 count: None,
204206 selected_register: None,
@@ -367,16 +369,19 @@ impl Editor {
367369 self._refresh();
368370 }
369371
370− fn new_document(&mut self, mut document: Document) -> DocumentId {
371− let id = DocumentId(self.next_document_id);
372− self.next_document_id += 1;
373− document.id = id;
374− self.documents.insert(id, document);
372+ /// Generate an id for a new document and register it.
373+ fn new_document(&mut self, mut doc: Document) -> DocumentId {
374+ let id = self.next_document_id;
375+ // Safety: adding 1 from 1 is fine, probably impossible to reach usize max
376+ self.next_document_id =
377+ DocumentId(unsafe { NonZeroUsize::new_unchecked(self.next_document_id.0.get() + 1) });
378+ doc.id = id;
379+ self.documents.insert(id, doc);
375380 id
376381 }
377382
378− fn new_file_from_document(&mut self, action: Action, document: Document) -> DocumentId {
379− let id = self.new_document(document);
383+ fn new_file_from_document(&mut self, action: Action, doc: Document) -> DocumentId {
384+ let id = self.new_document(doc);
380385 self.switch(id, action);
381386 id
382387 }
@@ -435,11 +440,7 @@ impl Editor {
435440 doc.set_language_server(Some(language_server));
436441 }
437442
438− let id = DocumentId(self.next_document_id);
439− self.next_document_id += 1;
440− doc.id = id;
441− self.documents.insert(id, doc);
442− id
443+ self.new_document(doc)
443444 };
444445
445446 self.switch(id, action);
helix-view/src/lib.rs+12−2
@@ -12,8 +12,18 @@ pub mod theme;
1212pub mod tree;
1313pub mod view;
1414
15−#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Debug)]
16−pub struct DocumentId(usize);
15+use std::num::NonZeroUsize;
16+
17+// uses NonZeroUsize so Option<DocumentId> use a byte rather than two
18+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
19+pub struct DocumentId(NonZeroUsize);
20+
21+impl Default for DocumentId {
22+ fn default() -> DocumentId {
23+ // Safety: 1 is non-zero
24+ DocumentId(unsafe { NonZeroUsize::new_unchecked(1) })
25+ }
26+}
1727
1828slotmap::new_key_type! {
1929 pub struct ViewId;