From 85aae59a804091977b28015ac93f03edc0da6190 Mon Sep 17 00:00:00 2001 From: "slav.babanin" Date: Thu, 24 Apr 2025 16:31:04 -0700 Subject: [PATCH 01/16] Add SWAR optimization for computing CString length. JAVA-5842 --- .../main/org/bson/io/ByteBufferBsonInput.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/bson/src/main/org/bson/io/ByteBufferBsonInput.java b/bson/src/main/org/bson/io/ByteBufferBsonInput.java index f8be97ddaa..94a4244673 100644 --- a/bson/src/main/org/bson/io/ByteBufferBsonInput.java +++ b/bson/src/main/org/bson/io/ByteBufferBsonInput.java @@ -182,11 +182,58 @@ public void skipCString() { buffer.position(pos + length); } + /** + * Detects the position of the first NULL (0x00) byte in a 64-bit word using SWAR technique. + * + */ private int computeCStringLength(final int prevPos) { ensureOpen(); int pos = buffer.position(); int limit = buffer.limit(); + int chunks = (limit - pos) >>> 3; + // Process 8 bytes at a time. + for (int i = 0; i < chunks; i++) { + long word = buffer.getLong(pos); + /* + Subtract 0x0101010101010101L to cause a borrow on 0x00 bytes. + if original byte is 00000000 -> 00000000 - 00000001 = 11111111 (borrow causes high bit set to 1). + */ + long mask = word - 0x0101010101010101L; + /* + mask will only have high bits set iff it was a 0x00 byte (0x00 becomes 0xFF because of the borrow). + ~word will have bits that were originally 0 set to 1. + mask & ~word will have high bits set iff original byte was 0x00. + */ + mask &= ~word; + /* + 0x8080808080808080: + 10000000 10000000 10000000 10000000 10000000 10000000 10000000 10000000 + + mask: + 00000000 00000000 11111111 00000000 00000001 00000001 00000000 00000111 + + ANDing mask with 0x8080808080808080 isolates the high bit (0x80) in positions where + the original byte was 0x00, setting the high bit to 1 only at the 0x00 byte position. + + result: + 00000000 00000000 10000000 00000000 00000000 00000000 00000000 00000000 + ^^^^^^^^ + The high bit is set only at the 0x00 byte position. + */ + mask &= 0x8080808080808080L; + if (mask != 0) { + /* + * Performing >>> 3 (i.e., dividing by 8) gives the byte offset from the least significant bit (LSB). + */ + int offset = Long.numberOfTrailingZeros(mask) >>> 3; + // Find the NULL terminator at pos + offset + return (pos - prevPos) + offset + 1; + } + pos += 8; + } + + // Process remaining bytes one-by-one. while (pos < limit) { if (buffer.get(pos++) == 0) { return (pos - prevPos); From ad83abc1118ad066a2ee4d98d801bbbcabba1da8 Mon Sep 17 00:00:00 2001 From: "slav.babanin" Date: Mon, 28 Apr 2025 10:32:51 -0700 Subject: [PATCH 02/16] Change Javadoc. JAVA-5842 --- bson/src/main/org/bson/io/ByteBufferBsonInput.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bson/src/main/org/bson/io/ByteBufferBsonInput.java b/bson/src/main/org/bson/io/ByteBufferBsonInput.java index 94a4244673..14a877508e 100644 --- a/bson/src/main/org/bson/io/ByteBufferBsonInput.java +++ b/bson/src/main/org/bson/io/ByteBufferBsonInput.java @@ -218,7 +218,7 @@ private int computeCStringLength(final int prevPos) { result: 00000000 00000000 10000000 00000000 00000000 00000000 00000000 00000000 - ^^^^^^^^ + ^^^^^^^^ The high bit is set only at the 0x00 byte position. */ mask &= 0x8080808080808080L; From b1ed69f578e83faef36a0438b84d7d9c313254b4 Mon Sep 17 00:00:00 2001 From: Viacheslav Babanin Date: Mon, 28 Apr 2025 12:21:32 -0700 Subject: [PATCH 03/16] Update bson/src/main/org/bson/io/ByteBufferBsonInput.java Co-authored-by: Jeff Yemin --- bson/src/main/org/bson/io/ByteBufferBsonInput.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bson/src/main/org/bson/io/ByteBufferBsonInput.java b/bson/src/main/org/bson/io/ByteBufferBsonInput.java index 14a877508e..06c07a3e0d 100644 --- a/bson/src/main/org/bson/io/ByteBufferBsonInput.java +++ b/bson/src/main/org/bson/io/ByteBufferBsonInput.java @@ -219,7 +219,7 @@ private int computeCStringLength(final int prevPos) { result: 00000000 00000000 10000000 00000000 00000000 00000000 00000000 00000000 ^^^^^^^^ - The high bit is set only at the 0x00 byte position. + The high bit is set only at the 0x00 byte position. */ mask &= 0x8080808080808080L; if (mask != 0) { From 4ce70a23b9177e821374a00661b5bb8b0e3cdf92 Mon Sep 17 00:00:00 2001 From: "slav.babanin" Date: Mon, 28 Apr 2025 12:33:57 -0700 Subject: [PATCH 04/16] Change code comments. JAVA-5842 --- bson/src/main/org/bson/io/ByteBufferBsonInput.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bson/src/main/org/bson/io/ByteBufferBsonInput.java b/bson/src/main/org/bson/io/ByteBufferBsonInput.java index 06c07a3e0d..e6cd8d8167 100644 --- a/bson/src/main/org/bson/io/ByteBufferBsonInput.java +++ b/bson/src/main/org/bson/io/ByteBufferBsonInput.java @@ -134,6 +134,7 @@ public String readString() { @Override public String readCString() { + ensureOpen(); int size = computeCStringLength(buffer.position()); return readString(size); } @@ -184,10 +185,9 @@ public void skipCString() { /** * Detects the position of the first NULL (0x00) byte in a 64-bit word using SWAR technique. - * + * */ private int computeCStringLength(final int prevPos) { - ensureOpen(); int pos = buffer.position(); int limit = buffer.limit(); @@ -197,7 +197,7 @@ private int computeCStringLength(final int prevPos) { long word = buffer.getLong(pos); /* Subtract 0x0101010101010101L to cause a borrow on 0x00 bytes. - if original byte is 00000000 -> 00000000 - 00000001 = 11111111 (borrow causes high bit set to 1). + if original byte is 00000000, then 00000000 - 00000001 = 11111111 (borrow causes high bit set to 1). */ long mask = word - 0x0101010101010101L; /* @@ -214,7 +214,7 @@ private int computeCStringLength(final int prevPos) { 00000000 00000000 11111111 00000000 00000001 00000001 00000000 00000111 ANDing mask with 0x8080808080808080 isolates the high bit (0x80) in positions where - the original byte was 0x00, setting the high bit to 1 only at the 0x00 byte position. + the original byte was 0x00, by setting the high bit to 1 only at the 0x00 byte position. result: 00000000 00000000 10000000 00000000 00000000 00000000 00000000 00000000 From 022f5c1315bd34b0b971ca82975a5cddf746d7e5 Mon Sep 17 00:00:00 2001 From: "slav.babanin" Date: Mon, 28 Apr 2025 12:35:49 -0700 Subject: [PATCH 05/16] Change code comments. JAVA-5842 --- bson/src/main/org/bson/io/ByteBufferBsonInput.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bson/src/main/org/bson/io/ByteBufferBsonInput.java b/bson/src/main/org/bson/io/ByteBufferBsonInput.java index e6cd8d8167..0038856779 100644 --- a/bson/src/main/org/bson/io/ByteBufferBsonInput.java +++ b/bson/src/main/org/bson/io/ByteBufferBsonInput.java @@ -233,7 +233,7 @@ private int computeCStringLength(final int prevPos) { pos += 8; } - // Process remaining bytes one-by-one. + // Process remaining bytes one by one. while (pos < limit) { if (buffer.get(pos++) == 0) { return (pos - prevPos); From 55ba0b1a6b8598b29b210bfaccbc015f748d1d5e Mon Sep 17 00:00:00 2001 From: "slav.babanin" Date: Mon, 28 Apr 2025 14:06:46 -0700 Subject: [PATCH 06/16] Change 'by' to 'thereby' for correct implication. JAVA-5842 --- bson/src/main/org/bson/io/ByteBufferBsonInput.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bson/src/main/org/bson/io/ByteBufferBsonInput.java b/bson/src/main/org/bson/io/ByteBufferBsonInput.java index 0038856779..6648f497eb 100644 --- a/bson/src/main/org/bson/io/ByteBufferBsonInput.java +++ b/bson/src/main/org/bson/io/ByteBufferBsonInput.java @@ -214,7 +214,7 @@ private int computeCStringLength(final int prevPos) { 00000000 00000000 11111111 00000000 00000001 00000001 00000000 00000111 ANDing mask with 0x8080808080808080 isolates the high bit (0x80) in positions where - the original byte was 0x00, by setting the high bit to 1 only at the 0x00 byte position. + the original byte was 0x00, thereby setting the high bit to 1 only at the 0x00 byte position. result: 00000000 00000000 10000000 00000000 00000000 00000000 00000000 00000000 From b8ccdfaf3b5de43d8596a2bed0fb84a65b846c6e Mon Sep 17 00:00:00 2001 From: Viacheslav Babanin Date: Tue, 29 Apr 2025 17:10:49 -0700 Subject: [PATCH 07/16] Update bson/src/main/org/bson/io/ByteBufferBsonInput.java Co-authored-by: Valentin Kovalenko --- bson/src/main/org/bson/io/ByteBufferBsonInput.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bson/src/main/org/bson/io/ByteBufferBsonInput.java b/bson/src/main/org/bson/io/ByteBufferBsonInput.java index 6648f497eb..1a7f21b734 100644 --- a/bson/src/main/org/bson/io/ByteBufferBsonInput.java +++ b/bson/src/main/org/bson/io/ByteBufferBsonInput.java @@ -188,7 +188,7 @@ public void skipCString() { * */ private int computeCStringLength(final int prevPos) { - int pos = buffer.position(); + int pos = prevPos; int limit = buffer.limit(); int chunks = (limit - pos) >>> 3; From 67e2bae9169be6ed8ba1efcbab2d3b888c98ff36 Mon Sep 17 00:00:00 2001 From: Viacheslav Babanin Date: Tue, 29 Apr 2025 17:11:14 -0700 Subject: [PATCH 08/16] Update bson/src/main/org/bson/io/ByteBufferBsonInput.java Co-authored-by: Valentin Kovalenko --- bson/src/main/org/bson/io/ByteBufferBsonInput.java | 1 + 1 file changed, 1 insertion(+) diff --git a/bson/src/main/org/bson/io/ByteBufferBsonInput.java b/bson/src/main/org/bson/io/ByteBufferBsonInput.java index 1a7f21b734..f8f311418c 100644 --- a/bson/src/main/org/bson/io/ByteBufferBsonInput.java +++ b/bson/src/main/org/bson/io/ByteBufferBsonInput.java @@ -191,6 +191,7 @@ private int computeCStringLength(final int prevPos) { int pos = prevPos; int limit = buffer.limit(); + // `>>> 3` means dividing without remainder by `Long.BYTES` because `Long.BYTES` is 2^3 int chunks = (limit - pos) >>> 3; // Process 8 bytes at a time. for (int i = 0; i < chunks; i++) { From 1bc094c4959d028ed43f20aac9eb28e9a52a87c4 Mon Sep 17 00:00:00 2001 From: Viacheslav Babanin Date: Tue, 29 Apr 2025 17:11:30 -0700 Subject: [PATCH 09/16] Update bson/src/main/org/bson/io/ByteBufferBsonInput.java Co-authored-by: Valentin Kovalenko --- bson/src/main/org/bson/io/ByteBufferBsonInput.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bson/src/main/org/bson/io/ByteBufferBsonInput.java b/bson/src/main/org/bson/io/ByteBufferBsonInput.java index f8f311418c..25e9b441ea 100644 --- a/bson/src/main/org/bson/io/ByteBufferBsonInput.java +++ b/bson/src/main/org/bson/io/ByteBufferBsonInput.java @@ -193,7 +193,7 @@ private int computeCStringLength(final int prevPos) { // `>>> 3` means dividing without remainder by `Long.BYTES` because `Long.BYTES` is 2^3 int chunks = (limit - pos) >>> 3; - // Process 8 bytes at a time. + // Process `Long.BYTES` at a time. for (int i = 0; i < chunks; i++) { long word = buffer.getLong(pos); /* From 7be6593b22c9d7748dbc2aedbb790bd3b72cc481 Mon Sep 17 00:00:00 2001 From: "slav.babanin" Date: Tue, 29 Apr 2025 18:46:21 -0700 Subject: [PATCH 10/16] Rename variables and change loop structure. JAVA-5842 --- .../main/org/bson/io/ByteBufferBsonInput.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/bson/src/main/org/bson/io/ByteBufferBsonInput.java b/bson/src/main/org/bson/io/ByteBufferBsonInput.java index 25e9b441ea..02fe2ab915 100644 --- a/bson/src/main/org/bson/io/ByteBufferBsonInput.java +++ b/bson/src/main/org/bson/io/ByteBufferBsonInput.java @@ -193,20 +193,21 @@ private int computeCStringLength(final int prevPos) { // `>>> 3` means dividing without remainder by `Long.BYTES` because `Long.BYTES` is 2^3 int chunks = (limit - pos) >>> 3; - // Process `Long.BYTES` at a time. - for (int i = 0; i < chunks; i++) { - long word = buffer.getLong(pos); + // `<< 3` means multiplying by `Long.BYTES` because `Long.BYTES` is 2^3 + int toPos = pos + (chunks << 3); + for (; pos < toPos; pos += Long.BYTES) { + long chunk = buffer.getLong(pos); /* Subtract 0x0101010101010101L to cause a borrow on 0x00 bytes. - if original byte is 00000000, then 00000000 - 00000001 = 11111111 (borrow causes high bit set to 1). + if original byte is 00000000, then 00000000 - 00000001 = 11111111 (borrow causes the MSB set to 1). */ - long mask = word - 0x0101010101010101L; + long mask = chunk - 0x0101010101010101L; /* - mask will only have high bits set iff it was a 0x00 byte (0x00 becomes 0xFF because of the borrow). - ~word will have bits that were originally 0 set to 1. - mask & ~word will have high bits set iff original byte was 0x00. + mask will only have the MSB set iff it was a 0x00 byte (0x00 becomes 0xFF because of the borrow). + ~chunk will have bits that were originally 0 set to 1. + mask & ~chunk will have the MSB set iff original byte was 0x00. */ - mask &= ~word; + mask &= ~chunk; /* 0x8080808080808080: 10000000 10000000 10000000 10000000 10000000 10000000 10000000 10000000 @@ -214,24 +215,23 @@ private int computeCStringLength(final int prevPos) { mask: 00000000 00000000 11111111 00000000 00000001 00000001 00000000 00000111 - ANDing mask with 0x8080808080808080 isolates the high bit (0x80) in positions where - the original byte was 0x00, thereby setting the high bit to 1 only at the 0x00 byte position. + ANDing mask with 0x8080808080808080 isolates the MSB (0x80) in positions where + the original byte was 0x00, thereby setting the MSB to 1 only at the 0x00 byte position. result: 00000000 00000000 10000000 00000000 00000000 00000000 00000000 00000000 ^^^^^^^^ - The high bit is set only at the 0x00 byte position. + The MSB is set only at the 0x00 byte position. */ mask &= 0x8080808080808080L; if (mask != 0) { /* - * Performing >>> 3 (i.e., dividing by 8) gives the byte offset from the least significant bit (LSB). + * Performing >>> 3 (i.e., dividing by 8) gives the byte offset from the LSB. */ int offset = Long.numberOfTrailingZeros(mask) >>> 3; // Find the NULL terminator at pos + offset return (pos - prevPos) + offset + 1; } - pos += 8; } // Process remaining bytes one by one. From 546198312dca8663b53ad922381edf9b153a6a8e Mon Sep 17 00:00:00 2001 From: "slav.babanin" Date: Wed, 30 Apr 2025 13:59:19 -0700 Subject: [PATCH 11/16] Clarify most significant bit and add detailed comment. JAVA-5842 --- .../main/org/bson/io/ByteBufferBsonInput.java | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/bson/src/main/org/bson/io/ByteBufferBsonInput.java b/bson/src/main/org/bson/io/ByteBufferBsonInput.java index 02fe2ab915..108a9c7e57 100644 --- a/bson/src/main/org/bson/io/ByteBufferBsonInput.java +++ b/bson/src/main/org/bson/io/ByteBufferBsonInput.java @@ -199,13 +199,13 @@ private int computeCStringLength(final int prevPos) { long chunk = buffer.getLong(pos); /* Subtract 0x0101010101010101L to cause a borrow on 0x00 bytes. - if original byte is 00000000, then 00000000 - 00000001 = 11111111 (borrow causes the MSB set to 1). + if original byte is 00000000, then 00000000 - 00000001 = 11111111 (borrow causes the MSb set to 1). */ long mask = chunk - 0x0101010101010101L; /* - mask will only have the MSB set iff it was a 0x00 byte (0x00 becomes 0xFF because of the borrow). + mask will only have the MSb set iff it was a 0x00 byte (0x00 becomes 0xFF because of the borrow). ~chunk will have bits that were originally 0 set to 1. - mask & ~chunk will have the MSB set iff original byte was 0x00. + mask & ~chunk will have the MSb set iff original byte was 0x00. */ mask &= ~chunk; /* @@ -215,18 +215,24 @@ private int computeCStringLength(final int prevPos) { mask: 00000000 00000000 11111111 00000000 00000001 00000001 00000000 00000111 - ANDing mask with 0x8080808080808080 isolates the MSB (0x80) in positions where - the original byte was 0x00, thereby setting the MSB to 1 only at the 0x00 byte position. + ANDing mask with 0x8080808080808080 isolates the MSb (0x80) in positions where + the original byte was 0x00, thereby setting the MSb to 1 only at the 0x00 byte position. result: 00000000 00000000 10000000 00000000 00000000 00000000 00000000 00000000 ^^^^^^^^ - The MSB is set only at the 0x00 byte position. + The MSb is set only at the 0x00 byte position. */ mask &= 0x8080808080808080L; if (mask != 0) { /* - * Performing >>> 3 (i.e., dividing by 8) gives the byte offset from the LSB. + The UTF-8 data is endian-independent and stored in left-to-right order in the buffer, with the first byte at the lowest index. + After calling getLong() in little-endian mode, the first UTF-8 byte ends up in the least significant byte of the long (bits 0–7), + and the last one in the most significant byte (bits 56–63). + + numberOfTrailingZeros scans from the least significant bit (LSb), which aligns with the position of the first UTF-8 byte. + We then use >>> 3, which means dividing without remainder by Long.BYTES because Long.BYTES is 2^3, computing the byte offset + of the NULL terminator in the original UTF-8 data. */ int offset = Long.numberOfTrailingZeros(mask) >>> 3; // Find the NULL terminator at pos + offset From 8bf0ab193c9e3628dec80b3e7c86baeed54676ca Mon Sep 17 00:00:00 2001 From: "slav.babanin" Date: Wed, 30 Apr 2025 14:02:42 -0700 Subject: [PATCH 12/16] Remove abbreviations. JAVA-5842 --- bson/src/main/org/bson/io/ByteBufferBsonInput.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/bson/src/main/org/bson/io/ByteBufferBsonInput.java b/bson/src/main/org/bson/io/ByteBufferBsonInput.java index 108a9c7e57..11a0eb141e 100644 --- a/bson/src/main/org/bson/io/ByteBufferBsonInput.java +++ b/bson/src/main/org/bson/io/ByteBufferBsonInput.java @@ -199,13 +199,13 @@ private int computeCStringLength(final int prevPos) { long chunk = buffer.getLong(pos); /* Subtract 0x0101010101010101L to cause a borrow on 0x00 bytes. - if original byte is 00000000, then 00000000 - 00000001 = 11111111 (borrow causes the MSb set to 1). + if original byte is 00000000, then 00000000 - 00000001 = 11111111 (borrow causes the most significant bit set to 1). */ long mask = chunk - 0x0101010101010101L; /* - mask will only have the MSb set iff it was a 0x00 byte (0x00 becomes 0xFF because of the borrow). + mask will only have the most significant bit set iff it was a 0x00 byte (0x00 becomes 0xFF because of the borrow). ~chunk will have bits that were originally 0 set to 1. - mask & ~chunk will have the MSb set iff original byte was 0x00. + mask & ~chunk will have the most significant bit set iff original byte was 0x00. */ mask &= ~chunk; /* @@ -215,13 +215,13 @@ private int computeCStringLength(final int prevPos) { mask: 00000000 00000000 11111111 00000000 00000001 00000001 00000000 00000111 - ANDing mask with 0x8080808080808080 isolates the MSb (0x80) in positions where - the original byte was 0x00, thereby setting the MSb to 1 only at the 0x00 byte position. + ANDing mask with 0x8080808080808080 isolates the most significant bit (0x80) in positions where + the original byte was 0x00, thereby setting the most significant bit to 1 only at the 0x00 byte position. result: 00000000 00000000 10000000 00000000 00000000 00000000 00000000 00000000 ^^^^^^^^ - The MSb is set only at the 0x00 byte position. + The most significant bit is set only at the 0x00 byte position. */ mask &= 0x8080808080808080L; if (mask != 0) { @@ -230,7 +230,7 @@ private int computeCStringLength(final int prevPos) { After calling getLong() in little-endian mode, the first UTF-8 byte ends up in the least significant byte of the long (bits 0–7), and the last one in the most significant byte (bits 56–63). - numberOfTrailingZeros scans from the least significant bit (LSb), which aligns with the position of the first UTF-8 byte. + numberOfTrailingZeros scans from the least significant bit, which aligns with the position of the first UTF-8 byte. We then use >>> 3, which means dividing without remainder by Long.BYTES because Long.BYTES is 2^3, computing the byte offset of the NULL terminator in the original UTF-8 data. */ From a8e8334cbbc7bd833635cd02028c7437e646d97f Mon Sep 17 00:00:00 2001 From: Viacheslav Babanin Date: Wed, 30 Apr 2025 15:16:12 -0700 Subject: [PATCH 13/16] Update bson/src/main/org/bson/io/ByteBufferBsonInput.java Co-authored-by: Valentin Kovalenko --- bson/src/main/org/bson/io/ByteBufferBsonInput.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bson/src/main/org/bson/io/ByteBufferBsonInput.java b/bson/src/main/org/bson/io/ByteBufferBsonInput.java index 11a0eb141e..74d1249413 100644 --- a/bson/src/main/org/bson/io/ByteBufferBsonInput.java +++ b/bson/src/main/org/bson/io/ByteBufferBsonInput.java @@ -215,8 +215,8 @@ private int computeCStringLength(final int prevPos) { mask: 00000000 00000000 11111111 00000000 00000001 00000001 00000000 00000111 - ANDing mask with 0x8080808080808080 isolates the most significant bit (0x80) in positions where - the original byte was 0x00, thereby setting the most significant bit to 1 only at the 0x00 byte position. + ANDing mask with 0x8080808080808080 isolates the most significant bit in each byte where + the original byte was 0x00, thereby setting the most significant bit to 1 in each 0x00 original byte. result: 00000000 00000000 10000000 00000000 00000000 00000000 00000000 00000000 From 8a5ce2d78999afc3d1fe3e4beede6ab21b2655d4 Mon Sep 17 00:00:00 2001 From: Viacheslav Babanin Date: Wed, 30 Apr 2025 15:16:19 -0700 Subject: [PATCH 14/16] Update bson/src/main/org/bson/io/ByteBufferBsonInput.java Co-authored-by: Valentin Kovalenko --- bson/src/main/org/bson/io/ByteBufferBsonInput.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bson/src/main/org/bson/io/ByteBufferBsonInput.java b/bson/src/main/org/bson/io/ByteBufferBsonInput.java index 74d1249413..794d414a0a 100644 --- a/bson/src/main/org/bson/io/ByteBufferBsonInput.java +++ b/bson/src/main/org/bson/io/ByteBufferBsonInput.java @@ -205,7 +205,7 @@ private int computeCStringLength(final int prevPos) { /* mask will only have the most significant bit set iff it was a 0x00 byte (0x00 becomes 0xFF because of the borrow). ~chunk will have bits that were originally 0 set to 1. - mask & ~chunk will have the most significant bit set iff original byte was 0x00. + mask & ~chunk will have the most significant bit in each byte set iff original byte was 0x00. */ mask &= ~chunk; /* From 149f13458b99b27d4f9d19b387bb26585765c532 Mon Sep 17 00:00:00 2001 From: Viacheslav Babanin Date: Wed, 30 Apr 2025 15:16:44 -0700 Subject: [PATCH 15/16] Update bson/src/main/org/bson/io/ByteBufferBsonInput.java Co-authored-by: Valentin Kovalenko --- bson/src/main/org/bson/io/ByteBufferBsonInput.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bson/src/main/org/bson/io/ByteBufferBsonInput.java b/bson/src/main/org/bson/io/ByteBufferBsonInput.java index 794d414a0a..a5ce780109 100644 --- a/bson/src/main/org/bson/io/ByteBufferBsonInput.java +++ b/bson/src/main/org/bson/io/ByteBufferBsonInput.java @@ -203,7 +203,7 @@ private int computeCStringLength(final int prevPos) { */ long mask = chunk - 0x0101010101010101L; /* - mask will only have the most significant bit set iff it was a 0x00 byte (0x00 becomes 0xFF because of the borrow). + mask will only have the most significant bit in each byte set iff it was a 0x00 byte (0x00 becomes 0xFF because of the borrow). ~chunk will have bits that were originally 0 set to 1. mask & ~chunk will have the most significant bit in each byte set iff original byte was 0x00. */ From 176db5b7b4ce98fbe3804437e3df5e32ef44be4d Mon Sep 17 00:00:00 2001 From: Viacheslav Babanin Date: Wed, 30 Apr 2025 15:27:31 -0700 Subject: [PATCH 16/16] Update bson/src/main/org/bson/io/ByteBufferBsonInput.java Co-authored-by: Valentin Kovalenko --- bson/src/main/org/bson/io/ByteBufferBsonInput.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bson/src/main/org/bson/io/ByteBufferBsonInput.java b/bson/src/main/org/bson/io/ByteBufferBsonInput.java index a5ce780109..2819bdcb09 100644 --- a/bson/src/main/org/bson/io/ByteBufferBsonInput.java +++ b/bson/src/main/org/bson/io/ByteBufferBsonInput.java @@ -221,7 +221,7 @@ private int computeCStringLength(final int prevPos) { result: 00000000 00000000 10000000 00000000 00000000 00000000 00000000 00000000 ^^^^^^^^ - The most significant bit is set only at the 0x00 byte position. + The most significant bit is set in each 0x00 byte, and only there. */ mask &= 0x8080808080808080L; if (mask != 0) {