[#70843] Re: [ruby-cvs:58952] hsbt:r51801 (trunk): * lib/rubygems: Update to RubyGems HEAD(fe61e4c112). — Eric Wong <normalperson@...>
hsbt@ruby-lang.org wrote:
3 messages
2015/09/17
[ruby-core:70692] Queue enhancement - promote! and promote_all!
From:
Jonathan Cruz <JCruz@...>
Date:
2015-09-08 18:08:41 UTC
List:
ruby-core #70692
I'm submitting a patch to enhance the Queue class by adding the methods Queue#promote! and Queue#promote_all!. These methods require a block that accepts queue elements. Elements for which the block returns a truthy value are moved to the 'front' of the queue. Queue#promote! only applies to the first such element and Queue#promote_all! applies to all matching elements (preserving their relative order). Motivation for this enhancement: Our project has several worker threads working on long-running work units in a queue, trying to find a 'match'. The queue is pre-sorted with the most likely matches at the front and least likely at the back. However, there are cases where as we work on some elements, we gain new data that certain elements are more likely to match than we originally thought. We need a way to promote these elements to the front of the queue. -Jonathan Cruz ________________________________ This transmission may contain information that is privileged, confidential, and/or exempt from disclosure under applicable law. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the information contained herein (including any reliance thereon) is strictly prohibited. If you received this transmission in error, please immediately contact the sender and destroy the material in its entirety, whether in electronic or hard copy format.
Attachments (1)
ruby_queue_promote.patch
(2.82 KB, text/x-diff)
Index: ChangeLog
===================================================================
--- ChangeLog (revision 51752)
+++ ChangeLog (working copy)
@@ -1,3 +1,11 @@
+Tue Sep 9 02:43:13 2015 Jonathan Cruz <jcruz@trustwave.com>
+
+ * thread_sync.c: Add Queue#promote! and Queue#promote_all!
+ Promotes elements to the front of the queue for which the provided
+ block returns a truthy value. #promote! only applies to the first
+ such element. #promote_all! applies to all matching elements,
+ maintaining their relative order.
+
Thu Sep 3 21:12:12 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
* lib/cgi/session.rb (create_new_id): use SHA512 instead of MD5.
Index: thread_sync.c
===================================================================
--- thread_sync.c (revision 51752)
+++ thread_sync.c (working copy)
@@ -905,6 +905,64 @@
}
/*
+ * Document-method: Queue#promote!
+ * call-seq: promote!
+ *
+ * Promotes first object to the front of the queue for which the given +block+
+ * returns a true value.
+ */
+
+static VALUE
+rb_queue_promote(VALUE self)
+{
+ if (!rb_block_given_p()) {
+ rb_raise(rb_eThreadError, "must be called with a block");
+ }
+ return queue_do_promote(self, FALSE);
+}
+
+/*
+ * Document-method: Queue#promote_all!
+ * call-seq: promote_all!
+ *
+ *
+ * Promotes all objects to the front of the queue for which the given +block+
+ * returns a true value, preserving their relative order.
+ */
+
+static VALUE
+rb_queue_promote_all(VALUE self)
+{
+ if (!rb_block_given_p()) {
+ rb_raise(rb_eThreadError, "must be called with a block");
+ }
+ return queue_do_promote(self, TRUE);
+}
+
+static VALUE
+queue_do_promote(VALUE self, int promote_all)
+{
+ VALUE que = GET_QUEUE_QUE(self);
+ VALUE promote = rb_ary_new2(RARRAY_LEN(que));
+ long i;
+ for (i = 0; i < RARRAY_LEN(que); i++) {
+ VALUE obj = RARRAY_AREF(que, i);
+ if (RTEST(rb_yield(obj))) {
+ rb_ary_unshift(promote, obj);
+ if (!promote_all) break;
+ }
+ }
+
+ for (i = 0; i < RARRAY_LEN(promote); i++) {
+ VALUE obj = RARRAY_AREF(promote, i);
+ rb_ary_delete(que, obj);
+ rb_ary_unshift(que, obj);
+ }
+ return self;
+}
+
+
+/*
* Document-class: SizedQueue
*
* This class represents queues of specified size capacity. The push operation
@@ -1281,6 +1339,8 @@
rb_define_method(rb_cQueue, "clear", rb_queue_clear, 0);
rb_define_method(rb_cQueue, "length", rb_queue_length, 0);
rb_define_method(rb_cQueue, "num_waiting", rb_queue_num_waiting, 0);
+ rb_define_method(rb_cQueue, "promote!", rb_queue_promote, 0);
+ rb_define_method(rb_cQueue, "promote_all!", rb_queue_promote_all, 0);
rb_define_alias(rb_cQueue, "enq", "push"); /* Alias for #push. */
rb_define_alias(rb_cQueue, "<<", "push"); /* Alias for #push. */