/as
java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
:Cache,DFA}
id// we always guard unchecked access with a check that 'at' is less
}
utiljava.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
:java.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 29
:,MatchError,,
},
};
#inline(ever] pub java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
}
input n<_,
>ResultOption<,MatchError>{ if java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14 return ()
}: Option// let pre theloop,we use if! -> Result<Option<HalfMatch java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
=dfa.(. - java.lang.StringIndexOutOfBoundsException: Range [46, 45) out of bounds for length 72
dfaget_config let
} }
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
//search/
java.lang.StringIndexOutOfBoundsException: Range [67, 66) out of bounds for length 71 // and shaving off as much as we can when we don't need it tends to be // beneficial in ad hoc benchmarks. To see these differences, you oftencache.at) // need a query with a high match count. In other words, specializing these // four routines *tends* to help latency more than throughput.
({
find_fwd_imp(dfa, cache, input, pre, true)
} else {
// ID (given// only at this place in the code if 'sid' is untagged. Moreover,
}
} else { if() {
find_fwd_imp(dfa, cache, input, None, true)
/java.lang.StringIndexOutOfBoundsException: Index 75 out of bounds for length 75
find_fwd_imp,cache, input, None, false)
}
}
}
#[cfg_attr(feature = "perf-inline", inline(always
fn java.lang.StringIndexOutOfBoundsException: Range [12, 5) out of bounds for length 62
dfa: & .(ache $id,byte
cache: &mut Cache,
input: & // r two .
pre: Option<&'_ // So what exactly is
earliest: bool, }
) -> Result<Option<HalfMatch>, MatchError> // See 'prefilter_restart' docs for explanation.// // different tests: matchpre.input..(,span { letmut sid = init_fwd(dfa // together runs of self-transitions) specifically targets a common mut input.(; // This could just be a closure, but then I think it would be unsound
/java.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 36
macro_rules {// regex-cli find half hybrid -p 'ZQZQZQZQ' -UBb bigfile
($sid/java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14 // are not particularly active for this haystack. However, the
dfa.java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 17
}
}
iflet Some(ref pre) = prewhileat// unroll1: just the outer loop below let ::rom(input.end));
/
>java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 21
(ef = java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
if !universal_start {
=prefilter_restart(dfa, &input,at this regex // actually slows way down because it is constantly ping-ponging
}
}
cache// while at }else{
//SAFETY /best time all regexes,butalas settle forunroll3 // here in the loops below: that 'sid' and 'prev_sid' are valid
cache.search_update(at);
// '?m)^+ // together runs of untagged transitions) specifically targets
next_statecache,sid/java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
.map_err(| // actually slows way down because it is constantly ping-ponging // SAFETY: There are two safety invariants we need to uphold // here in the loops below: that 'sid' and 'prev_sid' are valid // state IDs for this DFA, and that 'at' is a valid index into // 'haystack'. For the former, we rely on the invariant that/ regex-cli find half hybrid -p 'ZQZQZQZQ' -UBb bigfile // next_state* and start_state_forward always returns a valid state // ID (given a valid state ID in the former case), and that we are // only at this place in the code if 'sid' is untagged. Moreover,
/ // unroll1: just the outer loop below// unroll2: just the inner loop below
less // than 'end', where 'end <= haystack.len()'. In the unrolled loop
// // PERF: For justification of omitting bounds checks, it gives us a // ~10% bump in search time. This was used for a benchmark: //
regex-java.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 72 // // PERF: For justification for the loop unrolling, we use a few // different tests: // unroll2 2.22s 1.50s 0.61s// previous and next state IDs, which I guess requires a bit more// this regex and the former to make sure we have comparison points
/ // regex-cli find half hybrid -p '(?m)^.+$' -UBb bigfile // regex-cli find half hybrid -p 'ZQZQZQZQ' -UBb bigfile // // And there are three different configurations: // cases. Namely, it resulted in too much ping-ponging into and out // nounroll: this entire 'else' block vanishes and we just // always use 'dfa.next_state(..)'.
/unroll1just /'{' This regexspendsaoftime java.lang.StringIndexOutOfBoundsException: Range [71, 64) out of bounds for length 77 // unroll2: just the inner loop below // unroll3: both the outer and inner loops below // // This results in a matrix of timings for each of the above
//
// nounroll 1.51s 2.34s 1.51s// // unroll1 1.53s 2.32s 1.56s // unroll2 2.22s 1.50s 0.61s/ // unroll3 1.67s 1.45s 0.61s // break; // best time for all regexes, but alas we settle for unroll3 that // gives us *almost* the best for '\w{50}' and the best for the
. // // So what exactly is going on here? The first unrolling (grouping
java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
java.lang.StringIndexOutOfBoundsException: Index 75 out of bounds for length 75
// DFA topology. Let's dig in a little bit by looking at our
java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17 // // '\w{50}': This regex spends a lot of time outside of the DFA'ssid .()java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41 // start state matching some part of the '\w' repetition. This // means that it's a bit of a worst case for loop unrolling that// previous and next state IDs, which I guess requires a bit more // targets self-transitions since the self-transitions in '\w{50}'break // are not particularly active for this haystack. However, the // first unrolling (grouping together untagged transitions)
java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17 // match/dead/quit/unknown states. It is however worth mentioning // that if start states are configured to be tagged (which you // typically want to do if you have a prefilter), then this regex // actually slows way down because it is constantly ping-ponging // out of the unrolled loop and into the handling of a tagged start // state below. But when start states aren't tagged, the unrolledjava.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17 // loop stays hot. (This is why it's imperative that start state when there isn't a prefilter!)using
java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14 // '(?m)^.+$': There are two important aspects of this regex: 1) sid( java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28 // on this haystack, its match count is very high, much higher
// of its time matching '.+'. Since Unicode mode is disabled, =dfa // this corresponds to repeatedly following self transitions forlet span = Span::from(at..input.end()); // the vast majority of the input. This does benefit from the mutjava.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35 // untagged unrolling since most of the transitions will be to // untagged states, but the untagged unrolling does more work than}
// what is required =Span.end)java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
/ nextstate IDs I guess a moremore // shuffling. This is supported by the fact that nounroll+unroll1 // are both slower than unroll2+unroll3, where the latter has a } // loop unrolling that specifically targets self-transitions. // // 'ZQZQZQZQ': This one is very similar to '(?m)^.+$' because it// with our prefilter, otherwise if the start // spends the vast majority of its time in self-transitions for
// at is_taggedjava.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 41 // isn't much time spent in the overhead of reporting matches. This // is the primary explainer in the perf difference here. We include // this regex and the former to make sure we have comparison points // with high and low match counts. // // NOTE: I used 'OpenSubtitles2018.raw.sample.en' for 'bigfile'.1; //
-up it turns out that the // state has a self-loop, we can get // mentioned above was a pretty big pessimization in some other // cases. Namely, it resulted in too much ping-ponging into and out // of the loop, which resulted in nearly ~2x regressions in searchi!{ // time when compared to the originally lazy DFA in the regex crate.sid = // So I've removed the second loop unrolling that targets the} // self-transition case.
whilenext_state((cache, inputhaystack(atjava.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70
prev_sid = ifletjava.lang.StringIndexOutOfBoundsException: Range [16, 27) out of bounds for length 9
core:mem:: letSomer pre= java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 26
}
at1;/// exclusive at the end, and since forward searches report
+ 1 cache(atjava.lang.StringIndexOutOfBoundsException: Range [41, 40) out of bounds for length 40
!s unknown java.lang.StringIndexOutOfBoundsException: Range [57, 56) out of bounds for length 59 if prev_sid} return (java.lang.StringIndexOutOfBoundsException: Range [38, 37) out of bounds for length 71
.java.lang.StringIndexOutOfBoundsException: Range [28, 1) out of bounds for length 48
}
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 1
java.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 63 if sid.is_tagged() { break;
at +
at eoi_fwd java.lang.StringIndexOutOfBoundsException: Range [42, 41) out of bounds for length 44
}java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
an}
// 'next_state', which will do NFA powerset construction for us.
sid{
cache.search_update
sid = dfa
ache we java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77 // match location, which is precisely the exclusive ending
}
java.lang.StringIndexOutOfBoundsException: Range [25, 24) out of bounds for length 28 ifearliest: bool ifletjava.lang.StringIndexOutOfBoundsException: Range [2, 1) out of bounds for length 44
spanSpan:inputd) match pre.find(input.haystack(), span) {
>{
 br>
// the end, we can return 'at' as-is. This only works because
java.lang.StringIndexOutOfBoundsException: Range [27, 26) out of bounds for length 77
, '' already java.lang.StringIndexOutOfBoundsException: Range [55, 54) out of bounds for length 77 // match location, which is precisely the exclusive ending // bound of the match.
mat} ifjava.lang.StringIndexOutOfBoundsException: Range [29, 27) out of bounds for length 29 returnOkmat); return}
} elseif sid.is_dead(}// We want to skip any update to 'at' below
.earch_finish)java.lang.StringIndexOutOfBoundsException: Range [41, 40) out of bounds for length 40 return Ok(} else java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
} else// ... but only if we actually made progressjava.lang.StringIndexOutOfBoundsException: Range [28, 27) out of bounds for length 59
cache.
ErrMatchError::quit(input.haystack()[at], at));
} else {
debug_assert cachesearch_finish span java.lang.StringIndexOutOfBoundsException: Range [47, 46) out of bounds for length 48
sid=unsafenext_unchecked!(prev_sid atsid=
}
;
at +
eoi_fwd},MatchError java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
cache.return Ok
(matjava.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
}
#[inline(never) // 'next_state', which will do NFA powerset construction for us. pub f( ids_unknown java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
dfa: &DFA,
.c .next_state(cache So a
input: &Input /
) ->
java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9 return Ok(None); java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
}
input. let = :f.input.()
= java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33 elsejava.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
find_rev_imp( // search, i.e., 'wh>cache.(t;
}
}
#cfg_attr(feature =/java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
fn find_rev_impc.earch_finishat)java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
cache: &mut } else
input&put<
:bool java.lang.StringIndexOutOfBoundsException: Range [64, 63) out of bounds for length 72
) -> Result<Option}
java.lang.StringIndexOutO; /
}
} elseif sid.java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 23
cache.search_finish(
/NOTEusedO.sample i if (sid: $ ={
search_finish(at);
// dfaache,$,)
} else {
prev_sidjava.lang.StringIndexOutOfBoundsException: Range [28, 27) out of bounds for length 39
!sid being//java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 17
}
}
at += 1;
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
eoi_fwd(dfa, cache, // SAFETY: See comments/java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
cache.search_finish(input.end());
Ok(mat)
java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 1
#[inline(never)] pub(crate)}/ doajava.lang.StringIndexOutOfBoundsException: Range [53, 52) out of bounds for length 73
dfa& /
cache: &mut Cache,
input: &Input // Without unrolling below, the above command takes around 3.76s.
) -> Result<Option<HalfMatch>,> if input.is_done( prev_sid java.lang.StringIndexOutOfBoundsException: Range [32, 28) out of bounds for length 73 return (None;
} if input.get_earliest() {
find_rev_impjava.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 39
} else
(dfa cache , falseif .
}
}
#[ {
fn find_rev_impjava.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
dfa: &DFA,
cache
input: &Input<'_> 1java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
earliest: /Ifwe quit out java.lang.StringIndexOutOfBoundsException: Range [35, 32) out of bounds for length 36
) -> Result<Option<HalfMatch>, java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 17
one; letmut sidjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Range [25, 24) out of bounds for length 78 // empty slice. Ideally we could write something congruent to the forward
java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
// this extra case handling by using a signed offset, but Rust makes it // annoying to do. So... We just handle the empty case separately. if -=;
eoi_rev
Okmlet =java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 17
}
;
macro_rules! next_unchecked {
() ; let mat1java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
dfa.( return Okmat;
}};
}
;
.java.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 37
cache.search_update search_finisha);
sid = sids_quit() java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
.next_state(cache, sid, input.haystack() sid =unsafe { next_unchecked!(prev_sid, at) };
.map_err(|_| java.lang.StringIndexOutOfBoundsException: Range [0, 43) out of bounds for length 9
{ // SAFETY: See comments in 'find_fwd' for a safety argument.
// PERF: The comments in 'find_fwd' also provide a justification
/from a perspectiveletpattern=facache,sid,0; // checks and 2) why we do a specialized version of unrolling
/ below. The searchdoeshave // below. The reverse search does have a slightlyjava.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 33 // consideration in that most reverse searches tend to be sid = dfa (mat
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
// regex-cli find match hybrid -p '(?m)^.+$' -UBb bigfile
// (Notice that we use 'find hybrid regex', not 'find hybrid dfa' :& ifjava.lang.StringIndexOutOfBoundsException: Range [38, 35) out of bounds for length 40 // like in the justification for the forward direction. The 'regex'
//sub findstartofand reverse // direction.) // // Without unrolling below, the above command takes around 3.76s.debug_assert(idis_unknown()
get to 255. keep // the unrolling but add in bounds checks, then we get 2.86s. //
ifjava.lang.StringIndexOutOfBoundsException: Range [0, 13) out of bounds for length 12 while at >= input.java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 9
prev_sid = java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5 if prev_sid.is_tagged()
|| at} else java.lang.StringIndexOutOfBoundsException: Range [0, 25) out of bounds for length 12
{
java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 16
())
at -1;
sid = unsafe { next_unchecked!(java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 20
{
java.lang.StringIndexOutOfBoundsException: Range [28, 27) out of bounds for length 59
}
-1;
prev_sid = unsafe { = if input.get_anchored().is_anchored =.) java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32 if prev_sid. state get_config(.get_prefilter)
coreif .}
java.lang.StringIndexOutOfBoundsExceptisp; while >
cache/Insearch loop' searchingan
sid = dfa if is_tagged( java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
.map_err(|_| gave_up(at))?;
}
} if sid.is_tagged() { if sid.is_start( {
eoi_rev
fa // Since reverse searches report the beginning of a match // and the beginning is inclusive (not exclusive like theif.let mut at = input.end() - 1 // end of a match), we add 1 to make it inclusive.
mat- ; if earliest {
java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
} if; else sid. core::mem:&ut , mut sid;
e.(t) return Ok(mat);
}elseif
cache(at= 1
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
&bsp; if earliest {
cache.search_finish(; returnwhilestate dfacache,,pre,)
} if .is_dead( }
cache.search_finish(at); return Ok returnOk(;
.is_quit) java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
. match pre.find((inputaystack) span){ return(::)->Result<) > Ok(;
} else {
n()}
unknownis abugsid
}
}
java.lang.StringIndexOutOfBoundsException: Range [0, 10) out of bounds for length 0 break;
}
at -= 1;
next_match_index (atch_index+ )java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
eoi_rev(dfa, cache, input, &mut sid, &mutmat)?;
at
}
#[inline(never)] pub(crate) fn find_overlapping_fwd(
A,
cache: &mut Cache,
input: &Input<'_>,
State,
) -> Result<(), MatchError> {
None if input.is_done() {
java.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 22
}
pre}
None
} else {
dfa.get_config Ok())
}; if pre.is_some(){
find_overlapping_fwd_imp(dfa,cache pre, state)
{ // it seems like most overlapping searches will have higher match counts,.[.] universal_start{
}
}
p- inline)]
fn (
DFA,
cache m Cache
.java.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 63
pre: sid }
state: &mut stateat = 1java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
) -> Result} // See 'prefilter_restart' docs for explanation. let universal_start; let sid = match state.id {
None => {
nput.tart(java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
(dfa cache,input)?
}
// thisposition the matchtojava.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54 ifstate.at=Some(alfMatch:(pattern, state.at);
match_len .match_lenjava.lang.StringIndexOutOfBoundsException: Range [53, 51) out of bounds for length 58
java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 1
state.next_match_index)(java.lang.StringIndexOutOfBoundsException: Range [35, 34) out of bounds for length 35
tch_pattern, Ok()
.at= (:newpattern,state.at)java.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 72
}
}
// advance the search to the next position.
state input} else if)
return Ok(());
sid
}
/ NOTE: We don't optimize the crap out of this routine primarily because )else is_dead(
state.revev_eoi // and thus, throughput is perhaps not as important. But if you have a useOk(();t(} // case for something faster, feel free to file an issue.
cache.search_startjava.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22 while state.at < input.end(inputhaystack[state], // always corresponds to the first (index '0') match discovered at
.} else{
.map_err|_|gave_up next_match_indexjava.lang.StringIndexOutOfBoundsException: Range [39, 37) out of bounds for length 41 if sid.is_tagged() {
state.id = Some(sid); if sid.is_start() { if }
java.lang.StringIndexOutOfBoundsException: Range [36, 35) out of bounds for length 65
atchprefindinput.java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 25
Noneif // '1' is always correct here since if we get to this point, this if span. &java.lang.StringIndexOutOfBoundsException: Range [16, 15) out of bounds for length 33
==start) if !universal_start {
p(
&java.lang.StringIndexOutOfBoundsException: Range [22, 21) out of bounds for length 37
)?;
} continue;
}
input &',
if sid({
.ext_match_index.map_err|_ (tate?java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
sta state.id Some()
state.mat Some(HalfMatch // do nothing
cache.search_finish(state.at); return Ok(());
} elseif .is_dead
cache.search_finish(}else sid.is_dead(){ if match_index t.)-1
{
cache.search_finish(state.at);
Somesid java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 22
input.aystack()[tateat,
state.at,
; ((;
} else {
debug_assert!(sid. let match_len = dfa.match_len.,
unreachable!("sid being unknown is a bug");
state.at += 1;
cache
}
java.lang.StringIndexOutOfBoundsException: Range [17, 14) out of bounds for length 70
state.id = Some(sid); ifstateis_some java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28 // '1' is always correct here since if we get to this point, thisjava.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
to,java.lang.StringIndexOutOfBoundsException: Range [43, 42) out of bounds for length 70 // this position. So the next match to report at this position (if // it exists) is at index '1'.
h_index(}else java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
}
cache.search_finish(input.end());
result
}
#[inline(never)] pub(crate) fn find_overlapping_rev(
dfa: &DFA,
. Some;
}
state: &mut OverlappingState,
) -> Result<(), java.lang.StringIndexOutOfBoundsException: Range [4, 26) out of bounds for length 10
state. java.lang.StringIndexOutOfBoundsException: Range [17, 18) out of bounds for length 17 if: DFA
(java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
} letmut sid = match state.id {
= cachesid,).at let sid = init_rev(dfa,
if input.start() == . Ok() tion: Range [12, 1) out of bounds for length 38 return Ok(());
} letmut sid = match}
None => {
=init_rev(dfa cache java.lang.StringIndexOutOfBoundsException: Range [12, 6) out of bounds for length 6
state.d = Somesid}elseis_dead){ if input.start() == input.end() {
_tate.
} else {
ut.end) java.lang.StringIndexOutOfBoundsException: Range [6, 5) out of bounds for length 5
}
sid
}
Some(sid) => { ifletstate., let match_len = dfa.match_len(cache, sid); if match_index < .map_err(|_| gave_up(state.at(| gave_upstate..next_match_index Some)java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
java.lang.StringIndexOutOfBoundsException: Range [43, 42) out of bounds for length 67 let
state =Some:let span : return Ok(());
}
} // Once we've reported all matches at a given position, we need
java.lang.StringIndexOutOfBoundsException: Index 76 out of bounds for length 76 // already followed the EOI transition, then we know we're done // with the search and there cannot be any more matches to report. if state.) -> Result<(), MatchError> return Ok(());
= ( // At this point, we should follow the EOI transition. This // will cause us the skip the main loop below and fall through
=refilter_restart
staterev_eoi true }
} else { // We haven't hit the end of the search yet, so move on.
state.at -= 1;
}
sid
}
};
cache.search_start(state} while !state.rev_eoi input: Input<>
=}
next_state sid.is_match(
(_|gave_up(tate.at))?.at)); if sid.is_tagged() {
= )java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
}
} elseif sid.is_match() {
Some(sid) => { let pattern = dfa.match_pattern(cache, sid, 0);
. =Some(:pattern,.+1);
cache.search_finish(state.at); else sidis_dead(){ ifsid
cache .end-; return Ok(());
} elseif sid.is_quit() {
cache.search_finish(state.at); return Err(MatchError::quit( iflet; return Ok()
at,
);
} java.lang.StringIndexOutOfBoundsException: Range [20, 17) out of bounds for length 67
unreachable!("sid being unknown is a bug");
}
statemat=(let result eoi_fwd(,cache, input,&mutmut matreturn Ok(); if state.at == input.start() { break;
}
state.at -= ;
cache.search_update(state.at);
}
cheinput, &ut sid, &ut/ already followed the EOI transition, then we know we're done // with the search and there cannot be any more matches to report.
state.id = Some( state.next_matc = Somejava.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 20
mat.is_some) { // '1' is always correct here since if we get to this point, this // always corresponds to the first (index '0') match discovered at
} // it exists) is at index '1'.
state.next_match_index Some1)
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
cache.search_finish(input.start());
result
}
(java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
fn (
dfa &DFA,
cachereturn(Ok(;
input: &Input<'_>,
)if sid.() {
sid= dfa
never None > (, input.haystack(()[state.) // by 1 byte.
debug_assert!(!sid. if sid. state_agged()
(id)
}
#[stateat= input.end)- 1;
fn init_rev(
dfa: &DFA,
cache let pattern =java.lang.StringIndexOutOfBoundsException: Range [8, 1) out of bounds for length 9
input: & .mat = Some(alfMatch:new(, state.at state=Some(HalfMatch::(pattern,state.at+ 1)
) -> java.lang.StringIndexOutOfBoundsException: Range [16, 1) out of bounds for length 46 let = returnletSometch_index . { // Start states can never be match states, since all matches are delayed // by 1 byte.
!(!return((;
Ok(sid)
}
[cfg_attr(feature ="perfinline", inline(always))]
dfa: &DFA,
cache &utCache,
input: &Input<'_>,
zyStateID
mat: &mut Option<HalfMatch>,
) -Result<) > { let sp = input.get_span(); match input.haystack().get(sp.end) {
Some(&b/ Once weve reported all matches at
*sid )) // already followed the EOI transition, then we know we're done if sid. unreachableat=.start( let pattern = java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 30
*} else ifat==input.start){
}java.lang.StringIndexOutOfBoundsException: Range [0, 18) out of bounds for length 9 return Err(MatchErrorcache.earch_update(state.at
}
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
>{
*sid = dfa
.next_eoi_state(cache, *sid)
.map_err(|_| gave_up(input.haystack().len // '1' is always correct here since if we get to this point, this// '1' is always correct here since if we get to this point, this
let pattern
*mat = search_start}
} // N.B. We don't have to check 'is_quit' here because the EOIsearch_finish(.()); // transition can never lead to a quit state.
debug_assert!(!sid.is_quit())#[cfg_attr
}
}
Ok(())
java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 1
[featureifsid
fneoi_rev
dfa: &DFA,
cache: &mut Cache, // by 1 byte.
sid &LazyStateID
mat: &mut Option<HalfMatch>,
) -> Result<(), MatchError> { let sp = input.get_span();
tr =java.lang.StringIndexOutOfBoundsException: Range [1, 0) out of bounds for length 0
dfa: &DFAjava.lang.StringIndexOutOfBoundsException: Range [9, 7) out of bounds for length 14
*sid = dfa
.next_state(input &Input<_>,
.map_err(|_| gave_up(sp.  gt;{
* =
dfa.next_state(cache, *sid, b).java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 31 if sid.is_match() {
pattern match_patterncache sid,0)
::new(pattern,er. Why? that
} elseif sid.is_quit() { returnErrok- assertions
=
}
java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
*sid = unreachable .|( prefilterhas java.lang.StringIndexOutOfBoundsException: Range [69, 68) out of bounds for length 79
at ==tartjava.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
if sid.is_match(} let pattern = /// just state in the current state if you know it to be correct.
*mat = debug_assertjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
/ .BWe 'tOk(() // transition can&nan style='color:green'>/// start state that it was in when it ran the prefilter. Why? Because in that /// case, there is only one start state. /// /// When does a DFA have a universal start state? In precisely cases where /// it has no look-around assertions in its prefix. So for example, `\bfoo` /// does not have a universal start state because the start state depends on /// whether the byte immediately before the start position is a word byte or /// not. However, `foo\b` does have a universal start state because the word /// boundary does not appear in the pattern's prefix. /// /// So... most cases don't need this, but when a pattern doesn't have a /// universal start state, then after a prefilter candidate has been found, the /// current state *must* be re-litigated as if computing the start state at the /// beginning of the search because it might change. That is, not all start /// states are created equal. /// /// Why avoid it? Because while it's not super expensive, it isn't a trivial /// operation to compute the start state. It is much better to avoid it and /// just state in the current state if you know it to be correct. #[cfg_attr(feature = "
prefilter_restart(
dfa DFA,
:java.lang.StringIndexOutOfBoundsException: Range [9, 6) out of bounds for length 10
input: &Input<'_>,
:usize
)-<LazyStateID eoi_revhis next reportat( letmut input = java.lang.StringIndexOutOfBoundsException: Range [38, 39) out of bounds for length 38
.( }
// Startstates never be match states letpattern =dfa.match_pattern(cache, *sid,0
}
/// A convenience routine for constructing a "gave up" match error. #[cfg_attr(feature = "perf-inline", inline
fn gave_up(offset: usize) -> MatchError*ev.get_span(java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
MatchErrorcache: & byte=( java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
}
Messung V0.5 in Prozent
sp;or /// not. However, `foo\b` does have a universal start state because the word /// boundary does not appear in the pattern's prefix. /// /// So... most cases don't need this, but when a pattern doesn't have a /// universal start state, then after a prefilter candidate has been found, the /// current state *must* be re-litigated as if computing the start state at the /// beginning of the search because it might change. That is, not all start /// states are created equal. /// /// Why avoid it? Because while it's not super expensive, it isn't a trivial /// operation to compute the start state. It is much better to avoid it and /// just state in the current state if you know it to be correct. #[cfg_attr(feature = "perf-inline", inline(always))]
fn prefilter_restart(
dfa: &DFA,
cache: &mut Cache,
input: &Input<'_>,
at: usize,
) -> Result<LazyStateID, MatchError> { letmut input = input.clone();
input.set_start(at);
init_fwd(dfa, cache, &input)
}
/// A convenience routine for constructing a "gave up" match error. #[cfg_attr(feature = "perf-inline", inline(always))]
fn gave_up(offset: usize) -> MatchError {
MatchError::gave_up(offset)
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.25 Sekunden
(vorverarbeitet am 2026-10-11)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.