<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p>Hey Roman,</p>
<p>I agree with you that this looks like a bug. I can reproduce it
here as well (thanks for the nice reproducer!). The check fails to
take the offsets passed to mismatch into account. Previously we
only had the instance mismatch method, for which this check would
have been correct. However, when offsets are involved, it is not.</p>
<p>Thanks for reporting this! I have filed:
<a class="moz-txt-link-freetext" href="https://bugs.openjdk.org/browse/JDK-8323524">https://bugs.openjdk.org/browse/JDK-8323524</a><br>
<br>
As a workaround, you could create slices first and then compare
those using the instance mismatch method:<br>
<br>
<font face="monospace">long mismatch =
memory.asSlice(searchTermOffset,
len).mismatch(memory.asSlice(checkOffset, len));</font><br>
</p>
<p>Jorn<br>
</p>
<div class="moz-cite-prefix">On 10/01/2024 13:33, Roman Stoffel
wrote:<br>
</div>
<blockquote type="cite" cite="mid:CADi0+UsK4W45_FFTxrGqa+6a4LSLUMY3_3YacL7n5Z_BFoBHZA@mail.gmail.com">
<div dir="ltr">
<div>Hi</div>
<div><br>
</div>
<div>First, I'm not sure if I am at the right place, let me know
if I'm wrong.<br>
</div>
<div><br>
</div>
<div>I was trying to compare different sections of Memory and
used MemorySegment.mismatch.</div>
<div>My program got unexpected results and failed.</div>
<div><br>
</div>
<div>The issue boiled down to that I compared the same
MemorySegment with itself, but on different range. Example
program, which demonstrates the issue:</div>
<div><br>
</div>
<div>
<div style="background-color:rgb(255,255,255);color:rgb(8,8,8)">
<pre style="font-family:"JetBrains Mono",monospace;font-size:9.8pt"><span style="color:rgb(0,51,179)">public class </span><span style="color:rgb(0,0,0)">UnexpectedMismatchBehavior </span>{
<span style="color:rgb(0,51,179)">public static void </span><span style="color:rgb(0,98,122)">main</span>(<span style="color:rgb(0,0,0)">String</span>[] <span style="color:rgb(0,0,0)">args</span>) {
<span style="color:rgb(0,51,179)">byte</span>[] <span style="color:rgb(0,0,0)">exampleData </span>= <span style="color:rgb(0,51,179)">new byte</span>[]{<span style="color:rgb(23,80,235)">1</span>, <span style="color:rgb(23,80,235)">2</span>, <span style="color:rgb(23,80,235)">3</span>, <span style="color:rgb(23,80,235)">4</span>,
-<span style="color:rgb(23,80,235)">1</span>, -<span style="color:rgb(23,80,235)">1</span>, -<span style="color:rgb(23,80,235)">1</span>, -<span style="color:rgb(23,80,235)">1</span>,
<span style="color:rgb(23,80,235)">1</span>, <span style="color:rgb(23,80,235)">2</span>, <span style="color:rgb(23,80,235)">8</span>, <span style="color:rgb(23,80,235)">8</span>,
-<span style="color:rgb(23,80,235)">1</span>, -<span style="color:rgb(23,80,235)">1</span>, -<span style="color:rgb(23,80,235)">1</span>, -<span style="color:rgb(23,80,235)">1</span>};
<span style="color:rgb(140,140,140);font-style:italic">// In the real world, this is a large memory mapped file
</span><span style="color:rgb(140,140,140);font-style:italic"> </span><span style="color:rgb(0,0,0)">MemorySegment memory </span>= <span style="color:rgb(0,0,0)">MemorySegment</span>.<span style="font-style:italic">ofArray</span>(<span style="color:rgb(0,0,0)">exampleData</span>);
<span style="color:rgb(140,140,140);font-style:italic">// In the real app these are of course dynamic
</span><span style="color:rgb(140,140,140);font-style:italic"> </span><span style="color:rgb(0,51,179)">int </span><span style="color:rgb(0,0,0)">searchTermOffset </span>= <span style="color:rgb(23,80,235)">0</span>;
<span style="color:rgb(0,51,179)">int </span><span style="color:rgb(0,0,0)">len </span>= <span style="color:rgb(23,80,235)">4</span>;
<span style="color:rgb(0,51,179)">int </span><span style="color:rgb(0,0,0)">checkOffset </span>= <span style="color:rgb(23,80,235)">8</span>;
<span style="color:rgb(0,51,179)">long </span><span style="color:rgb(0,0,0)">missMatch </span>= <span style="color:rgb(0,0,0)">MemorySegment</span>.<span style="font-style:italic">mismatch</span>(<span style="color:rgb(0,0,0)">memory</span>, <span style="color:rgb(0,0,0)">searchTermOffset</span>, <span style="color:rgb(0,0,0)">searchTermOffset</span>+<span style="color:rgb(0,0,0)">len</span>, <span style="color:rgb(0,0,0)">memory</span>, <span style="color:rgb(0,0,0)">checkOffset</span>, <span style="color:rgb(0,0,0)">checkOffset</span>+<span style="color:rgb(0,0,0)">len</span>);
<span style="color:rgb(0,51,179)">int </span><span style="color:rgb(0,0,0)">debug </span>= <span style="color:rgb(0,0,0)">Arrays</span>.<span style="font-style:italic">mismatch</span>(<span style="color:rgb(0,0,0)">exampleData</span>,<span style="color:rgb(0,0,0)">searchTermOffset</span>, <span style="color:rgb(0,0,0)">searchTermOffset</span>+<span style="color:rgb(0,0,0)">len</span>,<span style="color:rgb(0,0,0)">exampleData</span>, <span style="color:rgb(0,0,0)">checkOffset</span>, <span style="color:rgb(0,0,0)">checkOffset</span>+<span style="color:rgb(0,0,0)">len</span>);
<span style="color:rgb(0,51,179)">if</span>(<span style="color:rgb(0,0,0)">missMatch </span>== -<span style="color:rgb(23,80,235)">1</span>){
<span style="color:rgb(0,0,0)">System</span>.<span style="color:rgb(135,16,148);font-style:italic">out</span>.println(<span style="color:rgb(6,125,23)">"Unexpected match!!!"</span>);
<span style="color:rgb(0,0,0)">System</span>.<span style="color:rgb(135,16,148);font-style:italic">out</span>.println(<span style="color:rgb(6,125,23)">"Array.mismatch gives: " </span>+ <span style="color:rgb(0,0,0)">debug</span>);
<span style="color:rgb(0,51,179)">throw new </span>Exception(<span style="color:rgb(6,125,23)">"What, should not match?"</span>);
} <span style="color:rgb(0,51,179)">else</span>{
<span style="color:rgb(0,0,0)">System</span>.<span style="color:rgb(135,16,148);font-style:italic">out</span>.println(<span style="color:rgb(6,125,23)">"Missmatch, as expected"</span>);
}
}
}
</pre>
</div>
</div>
<div><br>
</div>
<div>Overall, I would expect the same behavior as
Arrays.missmatch.</div>
<div><br>
</div>
<div>The cuprid seems this check in the implementation: <br>
<div style="background-color:rgb(255,255,255);color:rgb(8,8,8)">
<pre style="font-family:"JetBrains Mono",monospace;font-size:9.8pt"><span style="color:rgb(0,0,0)">AbstractMemorySegmentImpl.mismatch(...)
...
</span></pre>
<div style="background-color:rgb(255,255,255);color:rgb(8,8,8)">
<pre style="font-family:"JetBrains Mono",monospace;font-size:9.8pt"><span style="color:rgb(0,51,179)">if </span>(<span style="color:rgb(0,0,0)">dstImpl </span>== <span style="color:rgb(0,0,0)">srcImpl</span>) {
<span style="color:rgb(0,0,0)">srcImpl</span>.checkValidState();
<span style="color:rgb(0,51,179)">return </span>-<span style="color:rgb(23,80,235)">1</span>;
}
</pre>
<pre style="font-family:"JetBrains Mono",monospace;font-size:9.8pt">The current behavior is in my opinion problementatic.
I consider it a bug. Because I get the same return value as if there would be no match, the program
</pre>
<pre style="font-family:"JetBrains Mono",monospace;font-size:9.8pt">continues on with the wrong value.
</pre>
<pre style="font-family:"JetBrains Mono",monospace;font-size:9.8pt">What would instead expect:
</pre>
<pre style="font-family:"JetBrains Mono",monospace;font-size:9.8pt">- Best would be if it behaves like Arrays.missmatch
</pre>
<pre style="font-family:"JetBrains Mono",monospace;font-size:9.8pt">- Second best option: It throws an exception.
</pre>
<pre style="font-family:"JetBrains Mono",monospace;font-size:9.8pt">- Last option: Mention the limitation in the JavaDoc: But still many bugs will be written because
</pre>
<pre style="font-family:"JetBrains Mono",monospace;font-size:9.8pt"> the 'fine' print isn't read.
</pre>
<pre style="font-family:"JetBrains Mono",monospace;font-size:9.8pt">Best regards
</pre>
<pre style="font-family:"JetBrains Mono",monospace;font-size:9.8pt">Roman Stoffel
</pre>
<pre style="font-family:"JetBrains Mono",monospace;font-size:9.8pt">
</pre>
</div>
</div>
</div>
</div>
</blockquote>
</body>
</html>