.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.28) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "POE::Queue 3pm" .TH POE::Queue 3pm "2014-10-01" "perl v5.20.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" POE::Queue \- a flexible, generic priority queue API .SH "SYNOPSIS" .IX Header "SYNOPSIS" POE::Queue specifies additional methods not illustrated here. .PP .Vb 1 \& #!perl \& \& use warnings; \& use strict; \& use POE::Queue::Array; \& \& my $pqa = POE::Queue::Array\->new(); \& \& # Enqueue a few items. \& \& foreach my $priority (505, 404, 303, 202, 101) { \& $pqa\->enqueue($priority, "payload $priority"); \& } \& \& # Dequeue until the queue is drained. \& \& while (1) { \& my ($priority, $queue_id, $payload) = $pqa\->dequeue_next(); \& last unless defined $priority; \& \& print( \& "dequeued id($queue_id) ", \& "priority($priority) ", \& "payload($payload)\en", \& ); \& } .Ve .PP Sample output: .PP .Vb 5 \& dequeued id(5) priority(101) payload(payload 101) \& dequeued id(4) priority(202) payload(payload 202) \& dequeued id(3) priority(303) payload(payload 303) \& dequeued id(2) priority(404) payload(payload 404) \& dequeued id(1) priority(505) payload(payload 505) .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" Priority queues may be implemented a number of ways, but they tend to behave similar to lists that are kept in order by some kind of \&\*(L"priority\*(R". Enqueued items are stored such that the \*(L"next\*(R" item to be retrieved is the one with the highest priority. Subsequent fetches return the next lowest priority, and so on, until the queue is emptied. .PP Priority queues (also known as priority heaps) attempt to do this while consuming the fewest resources. Go read about it! It's fascinating stuff! .SS "POE::Queue Items" .IX Subsection "POE::Queue Items" POE::Queue items consist of three fields: A priority, a unique \s-1ID\s0 assigned at enqueue time, and a payload. The priority and payload are specified by the caller, and the unique \s-1ID\s0 is generated by POE::Queue when an item is enqueued. .PP POE::Queue imposes two limitations on priorities: Priorities must be numeric, and lower numbers indicate higher priorities. Aside from that, POE::Queue doesn't care what the numbers mean. .PP Unique IDs are handles into the queue. POE::Queue generates and returns them as new items are enqueued. Some methods manipulate items, and they take IDs to identify the items to alter. .PP Item payloads are arbitrary application data. POE::Queue does not examine or alter payloads itself. Any methods that need to examine payloads will accept a filter function. Filter functions examine payloads so POE::Queue need not. .SH "Public Methods" .IX Header "Public Methods" POE::Queue is an \s-1API\s0 specification. Subclasses like POE::Queue::Array provide actual implementations. .SS "new" .IX Subsection "new" Creates a new priority queue. Returns a reference to the queue. .PP .Vb 1 \& my $queue = POE::Queue::Array\->new(); .Ve .SS "enqueue \s-1PRIORITY, PAYLOAD\s0" .IX Subsection "enqueue PRIORITY, PAYLOAD" Enqueues a \s-1PAYLOAD,\s0 which can be just about anything that will fit into a Perl scalar, at a particular \s-1PRIORITY\s0 level. \fIenqueue()\fR returns a unique \s-1ID\s0 which can be used to manipulate the payload or its priority directly. .PP Following the \s-1UNIX\s0 tradition, lower priority numbers indicate higher priorities. The payload with the lowest priority number will be dequeued first. If two payloads have the same \s-1PRIORITY,\s0 then they will be dequeued in the order in which they were enqueued. .PP In this example, a queue is used to manage a number of alarms. The \&\*(L"next\*(R" alarm will be the one due soonest. .PP .Vb 1 \& my $payload_id = $queue\->enqueue($alarm_time, [ "stuff" ]); .Ve .SS "dequeue_next" .IX Subsection "dequeue_next" Removes the next item from the queue, returning it as three fields: priority, \s-1ID\s0 and payload. .PP The \*(L"next\*(R" item is the one with the lowest priority number. If multiple items exist with the same priority, \fIdequeue_next()\fR will return the one that was given the priority first. .PP .Vb 5 \& ITEM: while (1) { \& my ($priority, $id, $payload) = $queue\->dequeue_next(); \& last ITEM unless defined $priority; \& ...; \& } .Ve .SS "get_next_priority" .IX Subsection "get_next_priority" Returns the priority of the item at the head of the queue. This is the lowest numeric priority in the queue. .PP \&\fIget_next_priority()\fR can be useful for checking the queue to see if it's time to dequeue some items. In this case, the queue manages multiple alarms, and there's nothing to do if the next alarm isn't due yet. .PP .Vb 3 \& ALARM: while (1) { \& my $next_alarm_time = $queue\->get_next_priority(); \& last ALARM unless defined $next_alarm_time; \& \& if ($next_alarm_time \- time() > 0) { \& sleep($next_alarm_time \- time()); \& } \& \& my ($priority, $id, $payload) = $queue\->dequeue_next(); \& ...; \& } .Ve .SS "get_item_count" .IX Subsection "get_item_count" Returns the number of items in the queue. It's another way to tell whether the queue has been fully drained. Here's an alternative version of the example for \fIget_next_priority()\fR. .PP .Vb 5 \& ALARM: while ($queue\->get_item_count()) { \& my $next_alarm_time = $queue\->get_next_priority(); \& if ($next_alarm_time \- time() > 0) { \& sleep($next_alarm_time \- time()); \& } \& \& my ($priority, $id, $payload) = $queue\->dequeue_next(); \& ...; \& } .Ve .SS "remove_item \s-1ITEM_ID, FILTER_FUNCTION\s0" .IX Subsection "remove_item ITEM_ID, FILTER_FUNCTION" Removes a single item by its \s-1ID,\s0 but only if a \s-1FILTER_FUNCTION\s0 approves of the item's payload. .PP If a payload is found with the given \s-1ITEM_ID,\s0 it is passed to \&\s-1FILTER_FUNCTION\s0 for examination. If \s-1FILTER_FUNCTION\s0 returns true, the item is removed from the queue and is returned as three fields. .PP .Vb 3 \& my ($priority, $id, $payload) = $queue\->remove_item( \& $target_id, \e&monkeys \& ); \& \& sub monkeys { \& my $payload = shift; \& $payload\->{type} eq "monkey"; \& } .Ve .PP The returned \f(CW$priority\fR will be undef on failure, and $! will be set to the reason why the item couldn't be removed. That will be \s-1ESRCH\s0 if the \s-1ITEM_ID\s0 was not found in the queue, or \s-1EPERM\s0 if the filter function returned false. .SS "remove_items \s-1FILTER_FUNCTION\s0 [, \s-1MAX_ITEM_COUNT \s0]" .IX Subsection "remove_items FILTER_FUNCTION [, MAX_ITEM_COUNT ]" Removes and returns items from the queue that match a \s-1FILTER_FUNCTION.\s0 \&\fIremove_items()\fR will return immediately if \s-1MAX_ITEM_COUNT\s0 items is specified and that many items have been removed from the queue. \&\s-1MAX_ITEM_COUNT\s0 is a bit of optimization if the application knows in advance how many items will match the \s-1FILTER_FUNCTION.\s0 .PP Returns a list of items that were removed. Each item is an array reference containing a priority, item \s-1ID,\s0 and payload. Returns nothing if \s-1FILTER_FUNCTION\s0 matched nothing. .PP .Vb 11 \& # Remove up to 12 monkeys. \& my @monkeys = $queue\->remove_items(\e&monkeys, 12); \& foreach my $monkey (@monkeys) { \& my ($priority, $id, $payload) = @$monkey; \& print( \& "Removed monkey:\en", \& " priority = $priority\en", \& " queue id = $id\en", \& " payload = $payload\en", \& ); \& } .Ve .PP There is no guarantee which items will be removed if \s-1MAX_ITEM_COUNT\s0 is specified too low. .SS "peek_items \s-1FILTER_FUNCTION\s0 [, \s-1MAX_ITEM_COUNT \s0]" .IX Subsection "peek_items FILTER_FUNCTION [, MAX_ITEM_COUNT ]" \&\fIpeek_items()\fR returns up to \s-1MAX_ITEM_COUNT\s0 items that match a given \&\s-1FILTER_FUNCTION\s0 without removing them from the queue. .PP .Vb 10 \& my @entire_queue = $queue\->peek_items(sub { 1 }); \& foreach my $item (@entire_queue) { \& my ($priority, $id, $payload) = @$item; \& print( \& "Item:\en", \& " priority = $priority\en", \& " queue id = $id\en", \& " payload = $payload\en", \& ); \& } .Ve .SS "adjust_priority \s-1ITEM_ID, FILTER_FUNCTION, DELTA\s0" .IX Subsection "adjust_priority ITEM_ID, FILTER_FUNCTION, DELTA" Changes the priority of an item by \s-1DELTA. \s0 The item is identified by its \s-1ITEM_ID,\s0 and the change will only happen if the item's payload satisfies a \s-1FILTER_FUNCTION. \s0 Returns the new priority, which is the previous priority + \s-1DELTA. DELTA\s0 may be negative. .PP .Vb 3 \& my $new_priority = $queue\->adjust_priority( \& $item_id, \e&one_of_mine, 100 \& ); \& \& sub one_of_mine { \& my $payload = shift; \& return $payload\->{owner} == $me; \& } .Ve .PP Returns undef if the item's priority could not be adjusted, and sets $! to explain why: \s-1ESRCH\s0 means that the \s-1ITEM_ID\s0 could not be found, and \s-1EPERM\s0 means that the \s-1FILTER_FUNCTION\s0 was not satisfied. .SS "set_priority \s-1ITEM_ID, FILTER_FUNCTION, ABSOLUTE_PRIORITY\s0" .IX Subsection "set_priority ITEM_ID, FILTER_FUNCTION, ABSOLUTE_PRIORITY" Sets an item's priority to a new \s-1ABSOLUTE_PRIORITY. \s0 The item is identified by its \s-1ITEM_ID,\s0 and the change will only be allowed to happen if the item's payload satisfies a \s-1FILTER_FUNCTION. \s0 Returns the new priority, which should match \s-1ABSOLUTE_PRIORITY.\s0 .PP Returns undef if the item's priority could not be set, and sets $! to explain why: \s-1ESRCH\s0 means that the \s-1ITEM_ID\s0 could not be found, and \&\s-1EPERM\s0 means that the \s-1FILTER_FUNCTION\s0 was not satisfied. .PP .Vb 3 \& my $new_priority = $queue\->set_priority( \& $item_id, \e&one_of_mine, time() + 60 \& ); \& \& unless (defined $new_priority) { \& die "one of our submarines is missing: $item_id" if $! == ESRCH; \& die "set_priority disallowed for item $item_id" if $! == EPERM; \& die $!; \& } \& \& sub one_of_mine { \& $_[0]{owner} == $me; \& } .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" \&\s-1POE\s0, POE::Queue::Array .SH "BUGS" .IX Header "BUGS" None known. .SH "AUTHORS & COPYRIGHTS" .IX Header "AUTHORS & COPYRIGHTS" Please see \s-1POE\s0 for more information about authors, contributors, and \s-1POE\s0's licensing.