<div dir="ltr"><div><div>+1<br><br></div>
<p class="MsoNormal"><span style="mso-ansi-language:EN-US" lang="EN-US">I presume
copyChain is a bit more expensive than copy (I didn’t measure it though). More
expensive but allways correct.</span></p><p class="MsoNormal"><span style="mso-ansi-language:EN-US" lang="EN-US"><br></span></p>
<p class="MsoNormal"><span style="mso-ansi-language:EN-US" lang="EN-US">If the
inexpensive copy is used extensively, and my suggestion is a performance killer,
then let’s keep current solution: cleverly use expensive copy exactly where we
now we are going to need it. Otherwise, I suggest renaming copyChain into copy,
and hence have something much more robust.</span></p>
</div><div class="gmail_extra"><br><div class="gmail_quote">2016-05-20 1:03 GMT+02:00 <span dir="ltr"><<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>></span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Levente Uzonyi uploaded a new version of Regex-Core to project The Trunk:<br>
<a href="http://source.squeak.org/trunk/Regex-Core-ul.52.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/trunk/Regex-Core-ul.52.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Regex-Core-ul.52<br>
Author: ul<br>
Time: 20 May 2016, 1:02:48.025069 am<br>
UUID: 25d06172-cbd2-4454-a5e7-0dcfc27525b4<br>
Ancestors: Regex-Core-pre.51<br>
<br>
RxmLink changes:<br>
- implemented #copyChain, #copyUsing: and #postCopyUsing: to create a copy of the matcher chain without creating duplicates of links being referenced from more than one place<br>
- implemented missing #postCopy methods<br>
- removed unused variables from subclasses<br>
<br>
- use #copyChain instead of #veryDeepCopy in RxMatcher >> #makeQuantified:min:max: to avoid unnecessary duplication of non-link objects<br>
<br>
=============== Diff against Regex-Core-pre.51 ===============<br>
<br>
Item was changed:<br>
----- Method: RxMatcher>>makeQuantified:min:max: (in category 'private') -----<br>
makeQuantified: anRxmLink min: min max: max<br>
"Perform recursive poor-man's transformation of the {<min>,<max>} quantifiers."<br>
| aMatcher |<br>
<br>
"<atom>{,<max>} ==> (<atom>{1,<max>})?"<br>
min = 0 ifTrue: [<br>
^ self makeOptional: (self makeQuantified: anRxmLink min: 1 max: max) ].<br>
<br>
"<atom>{<min>,} ==> <atom>{<min>-1, <min>-1}<atom>+"<br>
max ifNil: [<br>
+ ^ (self makeQuantified: anRxmLink min: 1 max: min-1) pointTailTo: (self makePlus: anRxmLink copyChain) ].<br>
- ^ (self makeQuantified: anRxmLink min: 1 max: min-1) pointTailTo: (self makePlus: anRxmLink veryDeepCopy) ].<br>
<br>
"<atom>{<max>,<max>} ==> <atom><atom> ... <atom>"<br>
min = max<br>
ifTrue: [<br>
+ aMatcher := anRxmLink copyChain.<br>
+ (min-1) timesRepeat: [ aMatcher pointTailTo: anRxmLink copyChain ].<br>
- aMatcher := anRxmLink veryDeepCopy.<br>
- (min-1) timesRepeat: [ aMatcher pointTailTo: anRxmLink veryDeepCopy ].<br>
^ aMatcher ].<br>
<br>
"<atom>{<min>,<max>} ==> <atom>{<min>,<min>}(<atom>{1,<max>-1})?"<br>
+ aMatcher := self makeOptional: anRxmLink copyChain.<br>
- aMatcher := self makeOptional: anRxmLink veryDeepCopy.<br>
(max - min - 1) timesRepeat: [<br>
+ aMatcher := self makeOptional: (anRxmLink copyChain pointTailTo: aMatcher) ].<br>
- aMatcher := self makeOptional: (anRxmLink veryDeepCopy pointTailTo: aMatcher) ].<br>
^ (self makeQuantified: anRxmLink min: min max: min) pointTailTo: aMatcher!<br>
<br>
Item was added:<br>
+ ----- Method: RxmBranch>>postCopyUsing: (in category 'copying') -----<br>
+ postCopyUsing: anIdentityDictionary<br>
+<br>
+ super postCopyUsing: anIdentityDictionary.<br>
+ alternative ifNotNil: [<br>
+ alternative := alternative copyUsing: anIdentityDictionary ]!<br>
<br>
Item was added:<br>
+ ----- Method: RxmLink>>copyChain (in category 'copying') -----<br>
+ copyChain<br>
+ "Create a full copy of all the links in this chain, including branches, while letting them share and reuse non-link objects as much as possible."<br>
+<br>
+ ^self copyUsing: IdentityDictionary new!<br>
<br>
Item was added:<br>
+ ----- Method: RxmLink>>copyUsing: (in category 'copying') -----<br>
+ copyUsing: anIdentityDictionary<br>
+ "Copy the receiver if it's not present in the argument dictionary, or just return the previously made copy. The rest of the object graph will be copied by #postCopyUsing:."<br>
+<br>
+ ^anIdentityDictionary<br>
+ at: self<br>
+ ifAbsent: [<br>
+ "It may be tempting to use #at:ifAbsentPut: instead, but the argument block must not modify the receiver, so that wouldn't work."<br>
+ anIdentityDictionary<br>
+ at: self<br>
+ put: (self shallowCopy<br>
+ postCopyUsing: anIdentityDictionary;<br>
+ yourself) ]!<br>
<br>
Item was added:<br>
+ ----- Method: RxmLink>>postCopyUsing: (in category 'copying') -----<br>
+ postCopyUsing: anIdentityDictionary<br>
+ "Copy the rest of the chain the same way as it's done in #copyUsing:."<br>
+<br>
+ next ifNotNil: [<br>
+ next := next copyUsing: anIdentityDictionary ]!<br>
<br>
Item was changed:<br>
RxmLink subclass: #RxmLookahead<br>
+ instanceVariableNames: 'lookahead'<br>
- instanceVariableNames: 'lookahead positive'<br>
classVariableNames: ''<br>
poolDictionaries: ''<br>
category: 'Regex-Core'!<br>
<br>
!RxmLookahead commentStamp: '<historical>' prior: 0!<br>
Instance holds onto a lookead which matches but does not consume anything.<br>
<br>
Instance variables:<br>
predicate <RxmLink>!<br>
<br>
Item was removed:<br>
- ----- Method: RxmLookahead>>initialize (in category 'initialization') -----<br>
- initialize<br>
- super initialize.<br>
- positive := true.!<br>
<br>
Item was added:<br>
+ ----- Method: RxmLookahead>>postCopy (in category 'copying') -----<br>
+ postCopy<br>
+<br>
+ super postCopy.<br>
+ lookahead := lookahead copy!<br>
<br>
Item was added:<br>
+ ----- Method: RxmLookahead>>postCopyUsing: (in category 'copying') -----<br>
+ postCopyUsing: anIdentityDictionary<br>
+<br>
+ super postCopyUsing: anIdentityDictionary.<br>
+ lookahead := lookahead copyUsing: anIdentityDictionary!<br>
<br>
Item was changed:<br>
RxmLink subclass: #RxmSubstring<br>
+ instanceVariableNames: 'sampleStream ignoreCase'<br>
- instanceVariableNames: 'sampleStream caseSensitive ignoreCase'<br>
classVariableNames: ''<br>
poolDictionaries: ''<br>
category: 'Regex-Core'!<br>
<br>
!RxmSubstring commentStamp: 'Tbn 11/12/2010 23:14' prior: 0!<br>
-- Regular Expression Matcher v 1.1 (C) 1996, 1999 Vassili Bykov<br>
--<br>
Instance holds onto a string and matches exactly this string, and exactly once.<br>
<br>
Instance variables:<br>
string <String>!<br>
<br>
Item was added:<br>
+ ----- Method: RxmSubstring>>postCopy (in category 'copying') -----<br>
+ postCopy<br>
+<br>
+ super postCopy.<br>
+ sampleStream := sampleStream copy!<br>
<br>
Item was added:<br>
+ ----- Method: RxmSubstring>>postCopyUsing: (in category 'copying') -----<br>
+ postCopyUsing: anIdentityDictionary<br>
+<br>
+ super postCopyUsing: anIdentityDictionary.<br>
+ sampleStream := sampleStream copy!<br>
<br>
<br>
</blockquote></div><br></div></div>