summaryrefslogtreecommitdiffstats
path: root/third_party/rust/regex-automata/src/util/prefilter/memchr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/regex-automata/src/util/prefilter/memchr.rs')
-rw-r--r--third_party/rust/regex-automata/src/util/prefilter/memchr.rs186
1 files changed, 186 insertions, 0 deletions
diff --git a/third_party/rust/regex-automata/src/util/prefilter/memchr.rs b/third_party/rust/regex-automata/src/util/prefilter/memchr.rs
new file mode 100644
index 0000000000..3d44b83721
--- /dev/null
+++ b/third_party/rust/regex-automata/src/util/prefilter/memchr.rs
@@ -0,0 +1,186 @@
+use crate::util::{
+ prefilter::PrefilterI,
+ search::{MatchKind, Span},
+};
+
+#[derive(Clone, Debug)]
+pub(crate) struct Memchr(u8);
+
+impl Memchr {
+ pub(crate) fn new<B: AsRef<[u8]>>(
+ _kind: MatchKind,
+ needles: &[B],
+ ) -> Option<Memchr> {
+ #[cfg(not(feature = "perf-literal-substring"))]
+ {
+ None
+ }
+ #[cfg(feature = "perf-literal-substring")]
+ {
+ if needles.len() != 1 {
+ return None;
+ }
+ if needles[0].as_ref().len() != 1 {
+ return None;
+ }
+ Some(Memchr(needles[0].as_ref()[0]))
+ }
+ }
+}
+
+impl PrefilterI for Memchr {
+ fn find(&self, haystack: &[u8], span: Span) -> Option<Span> {
+ #[cfg(not(feature = "perf-literal-substring"))]
+ {
+ unreachable!()
+ }
+ #[cfg(feature = "perf-literal-substring")]
+ {
+ memchr::memchr(self.0, &haystack[span]).map(|i| {
+ let start = span.start + i;
+ let end = start + 1;
+ Span { start, end }
+ })
+ }
+ }
+
+ fn prefix(&self, haystack: &[u8], span: Span) -> Option<Span> {
+ let b = *haystack.get(span.start)?;
+ if self.0 == b {
+ Some(Span { start: span.start, end: span.start + 1 })
+ } else {
+ None
+ }
+ }
+
+ fn memory_usage(&self) -> usize {
+ 0
+ }
+
+ fn is_fast(&self) -> bool {
+ true
+ }
+}
+
+#[derive(Clone, Debug)]
+pub(crate) struct Memchr2(u8, u8);
+
+impl Memchr2 {
+ pub(crate) fn new<B: AsRef<[u8]>>(
+ _kind: MatchKind,
+ needles: &[B],
+ ) -> Option<Memchr2> {
+ #[cfg(not(feature = "perf-literal-substring"))]
+ {
+ None
+ }
+ #[cfg(feature = "perf-literal-substring")]
+ {
+ if needles.len() != 2 {
+ return None;
+ }
+ if !needles.iter().all(|n| n.as_ref().len() == 1) {
+ return None;
+ }
+ let b1 = needles[0].as_ref()[0];
+ let b2 = needles[1].as_ref()[0];
+ Some(Memchr2(b1, b2))
+ }
+ }
+}
+
+impl PrefilterI for Memchr2 {
+ fn find(&self, haystack: &[u8], span: Span) -> Option<Span> {
+ #[cfg(not(feature = "perf-literal-substring"))]
+ {
+ unreachable!()
+ }
+ #[cfg(feature = "perf-literal-substring")]
+ {
+ memchr::memchr2(self.0, self.1, &haystack[span]).map(|i| {
+ let start = span.start + i;
+ let end = start + 1;
+ Span { start, end }
+ })
+ }
+ }
+
+ fn prefix(&self, haystack: &[u8], span: Span) -> Option<Span> {
+ let b = *haystack.get(span.start)?;
+ if self.0 == b || self.1 == b {
+ Some(Span { start: span.start, end: span.start + 1 })
+ } else {
+ None
+ }
+ }
+
+ fn memory_usage(&self) -> usize {
+ 0
+ }
+
+ fn is_fast(&self) -> bool {
+ true
+ }
+}
+
+#[derive(Clone, Debug)]
+pub(crate) struct Memchr3(u8, u8, u8);
+
+impl Memchr3 {
+ pub(crate) fn new<B: AsRef<[u8]>>(
+ _kind: MatchKind,
+ needles: &[B],
+ ) -> Option<Memchr3> {
+ #[cfg(not(feature = "perf-literal-substring"))]
+ {
+ None
+ }
+ #[cfg(feature = "perf-literal-substring")]
+ {
+ if needles.len() != 3 {
+ return None;
+ }
+ if !needles.iter().all(|n| n.as_ref().len() == 1) {
+ return None;
+ }
+ let b1 = needles[0].as_ref()[0];
+ let b2 = needles[1].as_ref()[0];
+ let b3 = needles[2].as_ref()[0];
+ Some(Memchr3(b1, b2, b3))
+ }
+ }
+}
+
+impl PrefilterI for Memchr3 {
+ fn find(&self, haystack: &[u8], span: Span) -> Option<Span> {
+ #[cfg(not(feature = "perf-literal-substring"))]
+ {
+ unreachable!()
+ }
+ #[cfg(feature = "perf-literal-substring")]
+ {
+ memchr::memchr3(self.0, self.1, self.2, &haystack[span]).map(|i| {
+ let start = span.start + i;
+ let end = start + 1;
+ Span { start, end }
+ })
+ }
+ }
+
+ fn prefix(&self, haystack: &[u8], span: Span) -> Option<Span> {
+ let b = *haystack.get(span.start)?;
+ if self.0 == b || self.1 == b || self.2 == b {
+ Some(Span { start: span.start, end: span.start + 1 })
+ } else {
+ None
+ }
+ }
+
+ fn memory_usage(&self) -> usize {
+ 0
+ }
+
+ fn is_fast(&self) -> bool {
+ true
+ }
+}