[前][次][番号順一覧][スレッド一覧]

ruby-changes:73736

From: Samuel <ko1@a...>
Date: Mon, 26 Sep 2022 14:06:37 +0900 (JST)
Subject: [ruby-changes:73736] 025b8701c0 (master): Add several new methods for getting and setting buffer contents. (#6434)

https://git.ruby-lang.org/ruby.git/commit/?id=025b8701c0

From 025b8701c09813c40339bd8fa1c75e0e5eaf7120 Mon Sep 17 00:00:00 2001
From: Samuel Williams <samuel.williams@o...>
Date: Mon, 26 Sep 2022 18:06:12 +1300
Subject: Add several new methods for getting and setting buffer contents.
 (#6434)

---
 benchmark/buffer_each.yml   |  27 +++
 benchmark/buffer_get.yml    |  25 ++-
 common.mk                   |   1 +
 io_buffer.c                 | 509 +++++++++++++++++++++++++++++++++++---------
 test/ruby/test_io_buffer.rb |  50 ++++-
 5 files changed, 500 insertions(+), 112 deletions(-)
 create mode 100644 benchmark/buffer_each.yml

diff --git a/benchmark/buffer_each.yml b/benchmark/buffer_each.yml
new file mode 100644
index 0000000000..417941104e
--- /dev/null
+++ b/benchmark/buffer_each.yml
@@ -0,0 +1,27 @@ https://github.com/ruby/ruby/blob/trunk/benchmark/buffer_each.yml#L1
+prelude: |
+  # frozen_string_literal: true
+  Warning[:experimental] = false
+  string = "The quick brown fox jumped over the lazy dog."
+  array = string.bytes
+  buffer = IO::Buffer.for(string)
+benchmark:
+  string.each_byte: |
+    upcased = String.new
+    string.each_byte do |byte|
+      upcased << (byte ^ 32)
+    end
+  array.each: |
+    upcased = String.new
+    array.each do |byte|
+      upcased << (byte ^ 32)
+    end
+  buffer.each: |
+    upcased = String.new
+    buffer.each(:U8) do |offset, byte|
+      upcased << (byte ^ 32)
+    end
+  buffer.each_byte: |
+    upcased = String.new
+    buffer.each_byte do |byte|
+      upcased << (byte ^ 32)
+    end
diff --git a/benchmark/buffer_get.yml b/benchmark/buffer_get.yml
index bb9ca7e94a..9e1f99d64e 100644
--- a/benchmark/buffer_get.yml
+++ b/benchmark/buffer_get.yml
@@ -1,10 +1,25 @@ https://github.com/ruby/ruby/blob/trunk/benchmark/buffer_get.yml#L1
 prelude: |
   # frozen_string_literal: true
   Warning[:experimental] = false
-  buffer = IO::Buffer.new(32, IO::Buffer::MAPPED)
-  string = "\0" * 32
+  string = "The quick brown fox jumped over the lazy dog."
+  buffer = IO::Buffer.for(string)
+  format = [:U32, :U32, :U32, :U32]
 benchmark:
-  buffer.get_value: |
-    buffer.get_value(:U32, 0)
   string.unpack1: |
-    string.unpack1("N")
+    [
+      string.unpack1("N"),
+      string.unpack1("N", offset: 4),
+      string.unpack1("N", offset: 8),
+      string.unpack1("N", offset: 12),
+    ]
+  buffer.get_value: |
+    [
+      buffer.get_value(:U32, 0),
+      buffer.get_value(:U32, 4),
+      buffer.get_value(:U32, 8),
+      buffer.get_value(:U32, 12),
+    ]
+  buffer.get_values: |
+    buffer.get_values(format, 0)
+  string.unpack: |
+    string.unpack("NNNN")
diff --git a/common.mk b/common.mk
index 4678fd8940..51adabc783 100644
--- a/common.mk
+++ b/common.mk
@@ -7669,6 +7669,7 @@ io.$(OBJEXT): {$(VPATH)}util.h https://github.com/ruby/ruby/blob/trunk/common.mk#L7669
 io.$(OBJEXT): {$(VPATH)}vm_core.h
 io.$(OBJEXT): {$(VPATH)}vm_opts.h
 io_buffer.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+io_buffer.$(OBJEXT): $(top_srcdir)/internal/array.h
 io_buffer.$(OBJEXT): $(top_srcdir)/internal/bits.h
 io_buffer.$(OBJEXT): $(top_srcdir)/internal/compilers.h
 io_buffer.$(OBJEXT): $(top_srcdir)/internal/error.h
diff --git a/io_buffer.c b/io_buffer.c
index 98f1da1fc1..8ec5dc984b 100644
--- a/io_buffer.c
+++ b/io_buffer.c
@@ -6,6 +6,7 @@ https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L6
 
 **********************************************************************/
 
+#include "internal/array.h"
 #include "ruby/io.h"
 #include "ruby/io/buffer.h"
 #include "ruby/fiber/scheduler.h"
@@ -461,7 +462,6 @@ rb_io_buffer_map(VALUE io, size_t size, rb_off_t offset, enum rb_io_buffer_flags https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L462
  *
  *  Note that some operating systems may not have cache coherency between mapped
  *  buffers and file reads.
- *
  */
 static VALUE
 io_buffer_map(int argc, VALUE *argv, VALUE klass)
@@ -543,7 +543,6 @@ io_flags_for_size(size_t size) https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L543
  *    #  =>
  *    # #<IO::Buffer 0x000055b34497ea10+4 INTERNAL>
  *    # 0x00000000  74 65 73 74                                     test
- *
  */
 VALUE
 rb_io_buffer_initialize(int argc, VALUE *argv, VALUE self)
@@ -628,7 +627,6 @@ io_buffer_validate(struct rb_io_buffer *data) https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L627
  *
  *    puts IO::Buffer.new(4) # uses to_s internally
  *    # #<IO::Buffer 0x000055769f41b1a0+4 INTERNAL>
- *
  */
 VALUE
 rb_io_buffer_to_s(VALUE self)
@@ -756,7 +754,6 @@ rb_io_buffer_inspect(VALUE self) https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L754
  *
  *  Returns the size of the buffer that was explicitly set (on creation with ::new
  *  or on #resize), or deduced on buffer's creation from string or file.
- *
  */
 VALUE
 rb_io_buffer_size(VALUE self)
@@ -774,7 +771,6 @@ rb_io_buffer_size(VALUE self) https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L771
  *
  *  A buffer becomes invalid if it is a slice of another buffer which has been
  *  freed.
- *
  */
 static VALUE
 rb_io_buffer_valid_p(VALUE self)
@@ -790,7 +786,6 @@ rb_io_buffer_valid_p(VALUE self) https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L786
  *
  *  If the buffer was freed with #free or was never allocated in the first
  *  place.
- *
  */
 static VALUE
 rb_io_buffer_null_p(VALUE self)
@@ -807,7 +802,6 @@ rb_io_buffer_null_p(VALUE self) https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L802
  *  If the buffer has 0 size: it is created by ::new with size 0, or with ::for
  *  from an empty string. (Note that empty files can't be mapped, so the buffer
  *  created with ::map will never be empty.)
- *
  */
 static VALUE
 rb_io_buffer_empty_p(VALUE self)
@@ -828,7 +822,6 @@ rb_io_buffer_empty_p(VALUE self) https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L822
  *  memory.
  *
  *  External buffer can't be resized.
- *
  */
 static VALUE
 rb_io_buffer_external_p(VALUE self)
@@ -854,7 +847,6 @@ rb_io_buffer_external_p(VALUE self) https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L847
  *
  *  Internal buffers can be resized, and such an operation will typically
  *  invalidate all slices, but not always.
- *
  */
 static VALUE
 rb_io_buffer_internal_p(VALUE self)
@@ -877,7 +869,6 @@ rb_io_buffer_internal_p(VALUE self) https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L869
  *
  *  Mapped buffers can usually be resized, and such an operation will typically
  *  invalidate all slices, but not always.
- *
  */
 static VALUE
 rb_io_buffer_mapped_p(VALUE self)
@@ -901,7 +892,6 @@ rb_io_buffer_mapped_p(VALUE self) https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L892
  *    buffer.locked do
  *      buffer.write(io) # theoretical system call interface
  *    end
- *
  */
 static VALUE
 rb_io_buffer_locked_p(VALUE self)
@@ -928,7 +918,6 @@ rb_io_buffer_readonly_p(VALUE self) https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L918
  *  #set_value, #set_string or #copy and similar.
  *
  *  Frozen strings and read-only files create read-only buffers.
- *
  */
 static VALUE
 io_buffer_readonly_p(VALUE self)
@@ -1053,7 +1042,6 @@ rb_io_buffer_locked(VALUE self) https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L1042
  *     # => true
  *
  *  You can resize a freed buffer to re-allocate it.
- *
  */
 VALUE
 rb_io_buffer_free(VALUE self)
@@ -1115,7 +1103,6 @@ io_buffer_validate_range(struct rb_io_buffer *data, size_t offset, size_t length https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L1103
  *     # ...and original string
  *     string
  *     # => tost
- *
  */
 VALUE
 rb_io_buffer_slice(VALUE self, VALUE _offset, VALUE _length)
@@ -1166,7 +1153,7 @@ rb_io_buffer_get_bytes(VALUE self, void **base, size_t *size) https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L1153
     return 0;
 }
 
-static void
+inline static void
 io_buffer_get_bytes_for_writing(struct rb_io_buffer *data, void **base, size_t *size)
 {
     if (data->flags & RB_IO_BUFFER_READONLY) {
@@ -1238,7 +1225,6 @@ rb_io_buffer_get_bytes_for_reading(VALUE self, const void **base, size_t *size) https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L1225
  *     # #<IO::Buffer 0x0000000000000000+0 NULL>
  *     buffer.null?
  *     # => true
- *
  */
 VALUE
 rb_io_buffer_transfer(VALUE self)
@@ -1358,7 +1344,6 @@ rb_io_buffer_resize(VALUE self, size_t size) https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L1344
  *
  *  External buffer (created with ::for), and locked buffer
  *  can not be resized.
- *
  */
 static VALUE
 io_buffer_resize(VALUE self, VALUE size)
@@ -1373,7 +1358,6 @@ io_buffer_resize(VALUE self, VALUE size) https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L1358
  *
  * Buffers are compared by size and exact contents of the memory they are
  * referencing using +memcmp+.
- *
  */
 static VALUE
 rb_io_buffer_compare(VALUE self, VALUE other)
@@ -1399,7 +1383,7 @@ static void https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L1383
 io_buffer_validate_type(size_t size, size_t offset)
 {
     if (offset > size) {
-        rb_raise(rb_eArgError, "Type extends beyond end of buffer!");
+        rb_raise(rb_eArgError, "Type extends beyond end of buffer! (offset=%ld > size=%ld)", offset, size);
     }
 }
 
@@ -1449,8 +1433,8 @@ ruby_swapf64(double value) https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L1433
     return swap.value;
 }
 
-#define DECLARE_TYPE(name, type, endian, wrap, unwrap, swap) \
-static ID RB_IO_BUFFER_TYPE_##name; \
+#define IO_BUFFER_DECLARE_TYPE(name, type, endian, wrap, unwrap, swap) \
+static ID RB_IO_BUFFER_DATA_TYPE_##name; \
 \
 static VALUE \
 io_buffer_read_##name(const void* base, size_t size, size_t *offset) \
@@ -1471,67 +1455,123 @@ io_buffer_write_##name(const void* base, size_t size, size_t *offset, VALUE _val https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L1455
     if (endian != RB_IO_BUFFER_HOST_ENDIAN) value = swap(value); \
     memcpy((char*)base + *offset, &value, sizeof(type)); \
     *offset += sizeof(type); \
-}
-
-DECLARE_TYPE(U8, uint8_t, RB_IO_BUFFE (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]