[#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 Que= ue#promote! and Queue#promote_all!. These methods require a block that acce= pts 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 fir= st such element and Queue#promote_all! applies to all matching elements (pr= eserving their relative order). Motivation for this enhancement: Our project has several worker threads wor= king 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 lik= ely 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 o= riginally 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 int= ended recipient, you are hereby notified that any disclosure, copying, dist= ribution, or use of the information contained herein (including any relianc= e thereon) is strictly prohibited. If you received this transmission in err= or, please immediately contact the sender and destroy the material in its e= ntirety, 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. */