1############################################################################### 2## ---------------------------------------------------------------------------- 3## Array helper class. 4## 5############################################################################### 6 7package MCE::Shared::Array; 8 9use strict; 10use warnings; 11 12use 5.010001; 13 14no warnings qw( threads recursion uninitialized numeric ); 15 16our $VERSION = '1.874'; 17 18## no critic (TestingAndDebugging::ProhibitNoStrict) 19 20use MCE::Shared::Base (); 21use base 'MCE::Shared::Base::Common'; 22 23use overload ( 24 q("") => \&MCE::Shared::Base::_stringify, 25 q(0+) => \&MCE::Shared::Base::_numify, 26 fallback => 1 27); 28 29############################################################################### 30## ---------------------------------------------------------------------------- 31## Based on Tie::StdArray from Tie::Array. 32## 33############################################################################### 34 35sub TIEARRAY { 36 my $self = bless [], shift; 37 @{ $self } = @_ if @_; 38 39 $self; 40} 41 42sub EXTEND { } 43 44sub FETCHSIZE { scalar @{ $_[0] } } 45sub STORESIZE { $#{ $_[0] } = $_[1] - 1 } 46 47sub STORE { $_[0]->[ $_[1] ] = $_[2] } 48sub FETCH { $_[0]->[ $_[1] ] } 49sub DELETE { delete $_[0]->[ $_[1] ] } 50sub EXISTS { exists $_[0]->[ $_[1] ] } 51sub CLEAR { @{ $_[0] } = () } 52sub POP { pop @{ $_[0] } } 53sub PUSH { my $ob = shift; push @{ $ob }, @_ } 54sub SHIFT { shift @{ $_[0] } } 55sub UNSHIFT { my $ob = shift; unshift @{ $ob }, @_ } 56 57# SPLICE ( offset [, length [, list ] ] ) 58 59sub SPLICE { 60 my $ob = shift; 61 my $sz = $ob->FETCHSIZE; 62 my $off = @_ ? shift : 0; 63 $off += $sz if $off < 0; 64 my $len = @_ ? shift : $sz-$off; 65 66 splice @{ $ob }, $off, $len, @_; 67} 68 69############################################################################### 70## ---------------------------------------------------------------------------- 71## _find, clone, flush, iterator, keys, pairs, values 72## 73############################################################################### 74 75# _find ( { getkeys => 1 }, "query string" ) 76# _find ( { getvals => 1 }, "query string" ) 77# _find ( "query string" ) # pairs 78 79sub _find { 80 my $self = shift; 81 my $params = ref($_[0]) eq 'HASH' ? shift : {}; 82 my $query = shift; 83 84 MCE::Shared::Base::_find_array( $self, $params, $query ); 85} 86 87# clone ( key [, key, ... ] ) 88# clone ( ) 89 90sub clone { 91 my $self = shift; 92 my $params = ref($_[0]) eq 'HASH' ? shift : {}; 93 my @data = ( @_ ) ? @{ $self }[ @_ ] : @{ $self }; 94 95 $self->clear() if $params->{'flush'}; 96 97 bless \@data, ref $self; 98} 99 100# flush ( key [, key, ... ] ) 101# flush ( ) 102 103sub flush { 104 shift()->clone( { flush => 1 }, @_ ); 105} 106 107# iterator ( key [, key, ... ] ) 108# iterator ( "query string" ) 109# iterator ( ) 110 111sub iterator { 112 my ( $self, @keys ) = @_; 113 114 if ( ! @keys ) { 115 @keys = ( 0 .. $#{ $self } ); 116 } 117 elsif ( @keys == 1 && $keys[0] =~ /^(?:key|val)[ ]+\S\S?[ ]+\S/ ) { 118 @keys = $self->keys($keys[0]); 119 } 120 121 return sub { 122 return unless @keys; 123 my $key = shift @keys; 124 return ( $key => $self->[ $key ] ); 125 }; 126} 127 128# keys ( key [, key, ... ] ) 129# keys ( "query string" ) 130# keys ( ) 131 132sub keys { 133 my $self = shift; 134 135 if ( @_ == 1 && $_[0] =~ /^(?:key|val)[ ]+\S\S?[ ]+\S/ ) { 136 $self->_find({ getkeys => 1 }, @_); 137 } 138 elsif ( wantarray ) { 139 @_ ? map { exists $self->[ $_ ] ? $_ : undef } @_ 140 : ( 0 .. $#{ $self } ); 141 } 142 else { 143 scalar @{ $self }; 144 } 145} 146 147# pairs ( key [, key, ... ] ) 148# pairs ( "query string" ) 149# pairs ( ) 150 151sub pairs { 152 my $self = shift; 153 154 if ( @_ == 1 && $_[0] =~ /^(?:key|val)[ ]+\S\S?[ ]+\S/ ) { 155 $self->_find(@_); 156 } 157 elsif ( wantarray ) { 158 @_ ? map { $_ => $self->[ $_ ] } @_ 159 : map { $_ => $self->[ $_ ] } 0 .. $#{ $self }; 160 } 161 else { 162 scalar @{ $self }; 163 } 164} 165 166# values ( key [, key, ... ] ) 167# values ( "query string" ) 168# values ( ) 169 170sub values { 171 my $self = shift; 172 173 if ( @_ == 1 && $_[0] =~ /^(?:key|val)[ ]+\S\S?[ ]+\S/ ) { 174 $self->_find({ getvals => 1 }, @_); 175 } 176 elsif ( wantarray ) { 177 @_ ? @{ $self }[ @_ ] 178 : @{ $self } 179 } 180 else { 181 scalar @{ $self }; 182 } 183} 184 185############################################################################### 186## ---------------------------------------------------------------------------- 187## assign, mdel, mexists, mget, mset, range, sort 188## 189############################################################################### 190 191# assign ( value [, value, ... ] ) 192 193sub assign { 194 $_[0]->clear; shift()->push(@_); 195} 196 197# mdel ( index [, index, ... ] ) 198 199sub mdel { 200 my $self = shift; 201 my ( $cnt, $key ) = ( 0 ); 202 203 while ( @_ ) { 204 $key = shift; 205 $cnt++, delete($self->[ $key ]) if ( exists $self->[ $key ] ); 206 } 207 208 $cnt; 209} 210 211# mexists ( index [, index, ... ] ) 212 213sub mexists { 214 my $self = shift; 215 my $key; 216 217 while ( @_ ) { 218 $key = shift; 219 return '' unless ( exists $self->[ $key ] ); 220 } 221 222 1; 223} 224 225# mget ( index [, index, ... ] ) 226 227sub mget { 228 my $self = shift; 229 230 @_ ? @{ $self }[ @_ ] : (); 231} 232 233# mset ( index, value [, index, value, ... ] ) 234 235sub mset { 236 my ( $self, $key ) = ( shift ); 237 238 while ( @_ ) { 239 $key = shift, $self->[ $key ] = shift; 240 } 241 242 defined wantarray ? scalar @{ $self } : (); 243} 244 245# range ( start, stop ) 246 247sub range { 248 my ( $self, $start, $stop ) = @_; 249 250 if ( $start !~ /^\-?\d+$/ || $stop !~ /^\-?\d+$/ || $start > $#{ $self } ) { 251 return (); 252 } 253 254 if ( $start < 0 ) { 255 $start = @{ $self } + $start; 256 $start = 0 if $start < 0; 257 } 258 259 if ( $stop < 0 ) { 260 $stop = @{ $self } + $stop; 261 $stop = 0 if $stop < 0; 262 } 263 else { 264 $stop = $#{ $self } if $stop > $#{ $self }; 265 } 266 267 @{ $self }[ $start .. $stop ]; 268} 269 270# sort ( "BY val [ ASC | DESC ] [ ALPHA ]" ) 271# sort ( "[ ASC | DESC ] [ ALPHA ]" ) # same as "BY val ..." 272 273sub sort { 274 my ( $self, $request ) = @_; 275 my ( $alpha, $desc ) = ( 0, 0 ); 276 277 if ( length $request ) { 278 $alpha = 1 if ( $request =~ /\balpha\b/i ); 279 $desc = 1 if ( $request =~ /\bdesc\b/i ); 280 } 281 282 # Return sorted values, leaving the data intact. 283 284 if ( defined wantarray ) { 285 if ( $alpha ) { ( $desc ) 286 ? CORE::sort { $b cmp $a } @{ $self } 287 : CORE::sort { $a cmp $b } @{ $self }; 288 } 289 else { ( $desc ) 290 ? CORE::sort { $b <=> $a } @{ $self } 291 : CORE::sort { $a <=> $b } @{ $self }; 292 } 293 } 294 295 # Sort values in-place otherwise, in void context. 296 297 elsif ( $alpha ) { ( $desc ) 298 ? do { @{ $self } = CORE::sort { $b cmp $a } @{ $self } } 299 : do { @{ $self } = CORE::sort { $a cmp $b } @{ $self } }; 300 } 301 else { ( $desc ) 302 ? do { @{ $self } = CORE::sort { $b <=> $a } @{ $self } } 303 : do { @{ $self } = CORE::sort { $a <=> $b } @{ $self } }; 304 } 305} 306 307############################################################################### 308## ---------------------------------------------------------------------------- 309## Sugar API, mostly resembles http://redis.io/commands#string primitives. 310## 311############################################################################### 312 313# append ( index, string ) 314 315sub append { 316 length( $_[0]->[ $_[1] ] .= $_[2] // '' ); 317} 318 319# decr ( index ) 320# decrby ( index, number ) 321# incr ( index ) 322# incrby ( index, number ) 323# getdecr ( index ) 324# getincr ( index ) 325 326sub decr { --$_[0]->[ $_[1] ] } 327sub decrby { $_[0]->[ $_[1] ] -= $_[2] || 0 } 328sub incr { ++$_[0]->[ $_[1] ] } 329sub incrby { $_[0]->[ $_[1] ] += $_[2] || 0 } 330sub getdecr { $_[0]->[ $_[1] ]-- // 0 } 331sub getincr { $_[0]->[ $_[1] ]++ // 0 } 332 333# getset ( index, value ) 334 335sub getset { 336 my $old = $_[0]->[ $_[1] ]; 337 $_[0]->[ $_[1] ] = $_[2]; 338 339 $old; 340} 341 342# len ( index ) 343# len ( ) 344 345sub len { 346 ( defined $_[1] ) 347 ? length $_[0]->[ $_[1] ] 348 : scalar @{ $_[0] }; 349} 350 351{ 352 no strict 'refs'; 353 354 *{ __PACKAGE__.'::new' } = \&TIEARRAY; 355 *{ __PACKAGE__.'::set' } = \&STORE; 356 *{ __PACKAGE__.'::get' } = \&FETCH; 357 *{ __PACKAGE__.'::delete' } = \&DELETE; 358 *{ __PACKAGE__.'::exists' } = \&EXISTS; 359 *{ __PACKAGE__.'::clear' } = \&CLEAR; 360 *{ __PACKAGE__.'::pop' } = \&POP; 361 *{ __PACKAGE__.'::push' } = \&PUSH; 362 *{ __PACKAGE__.'::shift' } = \&SHIFT; 363 *{ __PACKAGE__.'::unshift' } = \&UNSHIFT; 364 *{ __PACKAGE__.'::splice' } = \&SPLICE; 365 *{ __PACKAGE__.'::del' } = \&delete; 366 *{ __PACKAGE__.'::merge' } = \&mset; 367 *{ __PACKAGE__.'::vals' } = \&values; 368} 369 3701; 371 372__END__ 373 374############################################################################### 375## ---------------------------------------------------------------------------- 376## Module usage. 377## 378############################################################################### 379 380=head1 NAME 381 382MCE::Shared::Array - Array helper class 383 384=head1 VERSION 385 386This document describes MCE::Shared::Array version 1.874 387 388=head1 DESCRIPTION 389 390An array helper class for use as a standalone or managed by L<MCE::Shared>. 391 392=head1 SYNOPSIS 393 394 # non-shared or local construction for use by a single process 395 396 use MCE::Shared::Array; 397 398 my $ar = MCE::Shared::Array->new( @list ); 399 400 # construction for sharing with other threads and processes 401 402 use MCE::Shared; 403 404 my $ar = MCE::Shared->array( @list ); 405 406 # array-like dereferencing 407 408 my $val = $ar->[$index]; 409 $ar->[$index] = $val; 410 411 @{$ar} = (); 412 413 # OO interface 414 415 $val = $ar->set( $index, $val ); 416 $val = $ar->get( $index); 417 $val = $ar->delete( $index ); # del is an alias for delete 418 $bool = $ar->exists( $index ); 419 void = $ar->clear(); 420 $len = $ar->len(); # scalar @{ $ar } 421 $len = $ar->len( $index ); # length $ar->[ $index ] 422 $val = $ar->pop(); 423 $len = $ar->push( @list ); 424 $val = $ar->shift(); 425 $len = $ar->unshift( @list ); 426 @list = $ar->splice( $offset, $length, @list ); 427 428 $ar2 = $ar->clone( @indices ); # @indices is optional 429 $ar3 = $ar->flush( @indices ); 430 $iter = $ar->iterator( @indices ); # ($idx, $val) = $iter->() 431 @keys = $ar->keys( @indices ); 432 %pairs = $ar->pairs( @indices ); 433 @vals = $ar->values( @indices ); # vals is an alias for values 434 435 $len = $ar->assign( $idx/$val pairs ); # equivalent to ->clear, ->push 436 $cnt = $ar->mdel( @indices ); 437 @vals = $ar->mget( @indices ); 438 $bool = $ar->mexists( @indices ); # true if all indices exists 439 $len = $ar->mset( $idx/$val pairs ); # merge is an alias for mset 440 441 @vals = $ar->range( $start, $stop ); 442 443 @vals = $ar->sort(); # $a <=> $b default 444 @vals = $ar->sort( "desc" ); # $b <=> $a 445 @vals = $ar->sort( "alpha" ); # $a cmp $b 446 @vals = $ar->sort( "alpha desc" ); # $b cmp $a 447 448 # included, sugar methods without having to call set/get explicitly 449 450 $len = $ar->append( $index, $string ); # $val .= $string 451 $val = $ar->decr( $index ); # --$val 452 $val = $ar->decrby( $index, $number ); # $val -= $number 453 $val = $ar->getdecr( $index ); # $val-- 454 $val = $ar->getincr( $index ); # $val++ 455 $val = $ar->incr( $index ); # ++$val 456 $val = $ar->incrby( $index, $number ); # $val += $number 457 $old = $ar->getset( $index, $new ); # $o = $v, $v = $n, $o 458 459 # pipeline, provides atomicity for shared objects, MCE::Shared v1.09+ 460 461 @vals = $ar->pipeline( # ( "a_a", "b_b", "c_c" ) 462 [ "set", 0 => "a_a" ], 463 [ "set", 1 => "b_b" ], 464 [ "set", 2 => "c_c" ], 465 [ "mget", qw/ 0 1 2 / ] 466 ); 467 468For normal array behavior, the TIE interface is supported. 469 470 # non-shared or local construction for use by a single process 471 472 use MCE::Shared::Array; 473 474 tie my @ar, "MCE::Shared::Array"; 475 476 # construction for sharing with other threads and processes 477 478 use MCE::Shared; 479 480 tie my @ar, "MCE::Shared"; 481 482 # usage 483 484 my $val; 485 486 if ( !defined ( $val = $ar[some_index] ) ) { 487 $val = $ar[some_index] = "some_value"; 488 } 489 490 $ar[some_index] = 0; 491 492 tied(@ar)->incrby("some_index", 20); 493 tied(@ar)->incrby(some_index => 20); 494 495=head1 SYNTAX for QUERY STRING 496 497Several methods take a query string for an argument. The format of the string 498is described below. In the context of sharing, the query mechanism is beneficial 499for the shared-manager process. It is able to perform the query where the data 500resides versus the client-process grep locally involving lots of IPC. 501 502 o Basic demonstration 503 504 @keys = $ar->keys( "query string given here" ); 505 @keys = $ar->keys( "val =~ /pattern/" ); 506 507 o Supported operators: =~ !~ eq ne lt le gt ge == != < <= > >= 508 o Multiple expressions delimited by :AND or :OR, mixed case allowed 509 510 "key == 3 :or (val > 5 :and val < 9)" 511 "key =~ /pattern/i :And val =~ /pattern/i" 512 "val eq foo baz :OR key !~ /pattern/i" 513 514 * key matches on indices in the array 515 * likewise, val matches on values 516 517 o Quoting is optional inside the string 518 519 "key =~ /pattern/i :AND val eq 'foo bar'" # val eq "foo bar" 520 "key =~ /pattern/i :AND val eq foo bar" # val eq "foo bar" 521 522Examples. 523 524 # search capability key/val: =~ !~ eq ne lt le gt ge == != < <= > >= 525 # key/val means to match against actual key/val respectively 526 527 @keys = $ar->keys( "key == 3 :or (val > 5 :and val < 9)" ); 528 529 @keys = $ar->keys( "key =~ /$pattern/i" ); 530 @keys = $ar->keys( "key !~ /$pattern/i" ); 531 @keys = $ar->keys( "val =~ /$pattern/i" ); 532 @keys = $ar->keys( "val !~ /$pattern/i" ); 533 534 %pairs = $ar->pairs( "key == $number" ); 535 %pairs = $ar->pairs( "key != $number :and val > 100" ); 536 %pairs = $ar->pairs( "key < $number :or key > $number" ); 537 %pairs = $ar->pairs( "val <= $number" ); 538 %pairs = $ar->pairs( "val > $number" ); 539 %pairs = $ar->pairs( "val >= $number" ); 540 541 @vals = $ar->vals( "key eq $string" ); 542 @vals = $ar->vals( "key ne $string with space" ); 543 @vals = $ar->vals( "key lt $string :or val =~ /$pat1|$pat2/" ); 544 @vals = $ar->vals( "val le $string :and val eq 'foo bar'" ); 545 @vals = $ar->vals( "val le $string :and val eq foo bar" ); 546 @vals = $ar->vals( "val gt $string" ); 547 @vals = $ar->vals( "val ge $string" ); 548 549=head1 API DOCUMENTATION 550 551This module may involve TIE when accessing the object via array-like behavior. 552Only shared instances are impacted if doing so. Although likely fast enough for 553many use cases, the OO interface is recommended for best performance. 554 555=head2 MCE::Shared::Array->new ( val [, val, ... ] ) 556 557=head2 MCE::Shared->array ( val [, val, ... ] ) 558 559Constructs a new object, with an optional list of values. 560 561 # non-shared or local construction for use by a single process 562 563 use MCE::Shared::Array; 564 565 $ar = MCE::Shared::Array->new( @list ); 566 $ar = MCE::Shared::Array->new( ); 567 568 # construction for sharing with other threads and processes 569 570 use MCE::Shared; 571 572 $ar = MCE::Shared->array( @list ); 573 $ar = MCE::Shared->array( ); 574 575=head2 assign ( value [, value, ... ] ) 576 577Clears the list, then appends one or multiple values and returns the new length. 578This is equivalent to C<clear>, C<push>. 579 580 $len = $ar->assign( "val1", "val2" ); 581 $len = @{$ar} = ( "val1", "val2" ); 582 583API available since 1.007. 584 585=head2 clear 586 587Removes all elements from the array. 588 589 $ar->clear; 590 @{$ar} = (); 591 592=head2 clone ( index [, index, ... ] ) 593 594Creates a shallow copy, a C<MCE::Shared::Array> object. It returns an exact 595copy if no arguments are given. Otherwise, the object includes only the given 596indices in the same order. Indices that do not exist in the array will have 597the C<undef> value. 598 599 $ar2 = $ar->clone( 0, 1 ); 600 $ar2 = $ar->clone; 601 602=head2 delete ( index ) 603 604Deletes and returns the value associated by index or C<undef> if index exceeds 605the size of the list. 606 607 $val = $ar->delete( 20 ); 608 $val = delete $ar->[ 20 ]; 609 610=head2 del 611 612C<del> is an alias for C<delete>. 613 614=head2 exists ( index ) 615 616Determines if an element by its index exists in the array. The behavior is 617strongly tied to the use of delete on lists. 618 619 $ar->push(qw/ value0 value1 value2 value3 /); 620 621 $ar->exists( 2 ); # True 622 $ar->delete( 2 ); # value2 623 $ar->exists( 2 ); # False 624 625 $ar->exists( 3 ); # True 626 exists $ar->[ 3 ]; # True 627 628=head2 flush ( index [, index, ... ] ) 629 630Same as C<clone>. Though, clears all existing items before returning. 631 632=head2 get ( index ) 633 634Gets the value of an element by its index or C<undef> if the index does not 635exists. 636 637 $val = $ar->get( 2 ); 638 $val = $ar->[ 2 ]; 639 640=head2 iterator ( index [, index, ... ] ) 641 642Returns a code reference for iterating a list of index-value pairs stored in 643the array when no arguments are given. Otherwise, returns a code reference for 644iterating the given indices in the same order. Indices that do not exist will 645have the C<undef> value. 646 647The list of indices to return is set when the closure is constructed. New 648indices added later are not included. Subsequently, the C<undef> value is 649returned for deleted indices. 650 651 $iter = $ar->iterator; 652 $iter = $ar->iterator( 0, 1 ); 653 654 while ( my ( $index, $val ) = $iter->() ) { 655 ... 656 } 657 658=head2 iterator ( "query string" ) 659 660Returns a code reference for iterating a list of index-value pairs that match 661the given criteria. It returns an empty list if the search found nothing. 662The syntax for the C<query string> is described above. 663 664 $iter = $ar->iterator( "val eq some_value" ); 665 $iter = $ar->iterator( "key >= 50 :AND val =~ /sun|moon|air|wind/" ); 666 $iter = $ar->iterator( "val eq sun :OR val eq moon :OR val eq foo" ); 667 $iter = $ar->iterator( "key =~ /$pattern/" ); 668 669 while ( my ( $index, $val ) = $iter->() ) { 670 ... 671 } 672 673=head2 keys ( index [, index, ... ] ) 674 675Returns all indices in the array when no arguments are given. Otherwise, 676returns the given indices in the same order. Indices that do not exist will 677have the C<undef> value. In scalar context, returns the size of the array. 678 679 @keys = $ar->keys( 0, 1 ); 680 681 @keys = $ar->keys; # faster 682 @keys = keys @{$ar}; # involves TIE overhead 683 684 $len = $ar->keys; # ditto 685 $len = keys @{$ar}; 686 687=head2 keys ( "query string" ) 688 689Returns only indices that match the given criteria. It returns an empty list 690if the search found nothing. The syntax for the C<query string> is described 691above. In scalar context, returns the size of the resulting list. 692 693 @keys = $ar->keys( "val eq some_value" ); 694 @keys = $ar->keys( "key >= 50 :AND val =~ /sun|moon|air|wind/" ); 695 @keys = $ar->keys( "val eq sun :OR val eq moon :OR val eq foo" ); 696 $len = $ar->keys( "key =~ /$pattern/" ); 697 698=head2 len ( index ) 699 700Returns the size of the array when no arguments are given. For the given 701index, returns the length of the value stored at index or the C<undef> value 702if the index does not exists. 703 704 $len = $ar->len; 705 $len = $ar->len( 0 ); 706 $len = length $ar->[ 0 ]; 707 708=head2 mdel ( index [, index, ... ] ) 709 710Deletes one or more elements by its index and returns the number of indices 711deleted. A given index which does not exist in the list is not counted. 712 713 $cnt = $ar->mdel( 0, 1 ); 714 715=head2 mexists ( index [, index, ... ] ) 716 717Returns a true value if all given indices exists in the list. A false value is 718returned otherwise. 719 720 if ( $ar->mexists( 0, 1 ) ) { ... } 721 722=head2 mget ( index [, index, ... ] ) 723 724Gets multiple values from the list by its index. It returns C<undef> for indices 725which do not exists in the list. 726 727 ( $val1, $val2 ) = $ar->mget( 0, 1 ); 728 729=head2 mset ( index, value [, index, value, ... ] ) 730 731Sets multiple index-value pairs in the list and returns the length of the list. 732 733 $len = $ar->mset( 0 => "val1", 1 => "val2" ); 734 735=head2 merge 736 737C<merge> is an alias for C<mset>. 738 739=head2 pairs ( index [, index, ... ] ) 740 741Returns index-value pairs in the array when no arguments are given. Otherwise, 742returns index-value pairs for the given indices in the same order. Indices that 743do not exist will have the C<undef> value. In scalar context, returns the size 744of the array. 745 746 @pairs = $ar->pairs( 0, 1 ); 747 748 @pairs = $ar->pairs; 749 $len = $ar->pairs; 750 751=head2 pairs ( "query string" ) 752 753Returns only index-value pairs that match the given criteria. It returns an 754empty list if the search found nothing. The syntax for the C<query string> is 755described above. In scalar context, returns the size of the resulting list. 756 757 @pairs = $ar->pairs( "val eq some_value" ); 758 @pairs = $ar->pairs( "key >= 50 :AND val =~ /sun|moon|air|wind/" ); 759 @pairs = $ar->pairs( "val eq sun :OR val eq moon :OR val eq foo" ); 760 $len = $ar->pairs( "key =~ /$pattern/" ); 761 762=head2 pipeline ( [ func1, @args ], [ func2, @args ], ... ) 763 764Combines multiple commands for the object to be processed serially. For shared 765objects, the call is made atomically due to single IPC to the shared-manager 766process. The C<pipeline> method is fully C<wantarray>-aware and receives a list 767of commands and their arguments. In scalar or list context, it returns data 768from the last command in the pipeline. 769 770 @vals = $ar->pipeline( # ( "a_a", "b_b", "c_c" ) 771 [ "set", 0 => "a_a" ], 772 [ "set", 1 => "b_b" ], 773 [ "set", 2 => "c_c" ], 774 [ "mget", qw/ 0 1 2 / ] 775 ); 776 777 $len = $ar->pipeline( # 3, same as $ar->len 778 [ "set", 0 => "i_i" ], 779 [ "set", 1 => "j_j" ], 780 [ "set", 2 => "k_k" ], 781 [ "len" ] 782 ); 783 784 $ar->pipeline( 785 [ "set", 0 => "m_m" ], 786 [ "set", 1 => "n_n" ], 787 [ "set", 2 => "o_o" ] 788 ); 789 790Current API available since 1.809. 791 792=head2 pipeline_ex ( [ func1, @args ], [ func2, @args ], ... ) 793 794Same as C<pipeline>, but returns data for every command in the pipeline. 795 796 @vals = $ar->pipeline_ex( # ( "a_a", "b_b", "c_c" ) 797 [ "set", 0 => "a_a" ], 798 [ "set", 1 => "b_b" ], 799 [ "set", 2 => "c_c" ] 800 ); 801 802Current API available since 1.809. 803 804=head2 pop 805 806Removes and returns the last value of the list. If there are no elements in the 807list, returns the undefined value. 808 809 $val = $ar->pop; 810 $val = pop @{$ar}; 811 812=head2 push ( value [, value, ... ] ) 813 814Appends one or multiple values to the tail of the list and returns the new 815length. 816 817 $len = $ar->push( "val1", "val2" ); 818 $len = push @{$ar}, "val1", "val2"; 819 820=head2 set ( index, value ) 821 822Sets the value of the given array index and returns its new value. 823 824 $val = $ar->set( 2, "value" ); 825 $val = $ar->[ 2 ] = "value"; 826 827=head2 shift 828 829Removes and returns the first value of the list. If there are no elements in the 830list, returns the undefined value. 831 832 $val = $ar->shift; 833 $val = shift @{$ar}; 834 835=head2 range ( start, stop ) 836 837Returns the specified elements of the list. The offsets C<start> and C<stop> 838can also be negative numbers indicating offsets starting at the end of the 839list. 840 841An empty list is returned if C<start> is larger than the end of the list. 842C<stop> is set to the last index of the list if larger than the actual end 843of the list. 844 845 @list = $ar->range( 20, 29 ); 846 @list = $ar->range( -4, -1 ); 847 848=head2 sort ( "BY val [ ASC | DESC ] [ ALPHA ]" ) 849 850Returns sorted values in list context, leaving the elements intact. In void 851context, sorts the list in-place. By default, sorting is numeric when no 852arguments are given. The C<BY val> modifier is optional and may be omitted. 853 854 @vals = $ar->sort( "BY val" ); 855 856 $ar->sort(); 857 858If the list contains string values and you want to sort them lexicographically, 859specify the C<ALPHA> modifier. 860 861 @vals = $ar->sort( "BY val ALPHA" ); 862 863 $ar->sort( "ALPHA" ); 864 865The default is C<ASC> for sorting the list from small to large. In order to 866sort the list from large to small, specify the C<DESC> modifier. 867 868 @vals = $ar->sort( "DESC ALPHA" ); 869 870 $ar->sort( "DESC ALPHA" ); 871 872=head2 splice ( offset [, length [, list ] ] ) 873 874Removes the elements designated by C<offset> and C<length> from the array, and 875replaces them with the elements of C<list>, if any. The behavior is similar to 876the Perl C<splice> function. 877 878 @items = $ar->splice( 20, 2, @list ); 879 @items = $ar->splice( 20, 2 ); 880 @items = $ar->splice( 20 ); 881 882=head2 unshift ( value [, value, ... ] ) 883 884Prepends one or multiple values to the head of the list and returns the new 885length. 886 887 $len = $ar->unshift( "val1", "val2" ); 888 $len = unshift @{$ar}, "val1", "val2"; 889 890=head2 values ( index [, index, ... ] ) 891 892Returns all values in the array when no arguments are given. Otherwise, returns 893values for the given indices in the same order. Indices that do not exist will 894have the C<undef> value. In scalar context, returns the size of the array. 895 896 @vals = $ar->values( 0, 1 ); 897 898 @vals = $ar->values; # faster 899 @vals = values @{$ar}; # involves TIE overhead 900 901 $len = $ar->values; # ditto 902 $len = values @{$ar}; 903 904=head2 values ( "query string" ) 905 906Returns only values that match the given criteria. It returns an empty list 907if the search found nothing. The syntax for the C<query string> is described 908above. In scalar context, returns the size of the resulting list. 909 910 @keys = $ar->values( "val eq some_value" ); 911 @keys = $ar->values( "key >= 50 :AND val =~ /sun|moon|air|wind/" ); 912 @keys = $ar->values( "val eq sun :OR val eq moon :OR val eq foo" ); 913 $len = $ar->values( "key =~ /$pattern/" ); 914 915=head2 vals 916 917C<vals> is an alias for C<values>. 918 919=head1 SUGAR METHODS 920 921This module is equipped with sugar methods to not have to call C<set> 922and C<get> explicitly. In shared context, the benefit is atomicity and 923reduction in inter-process communication. 924 925The API resembles a subset of the Redis primitives 926L<http://redis.io/commands#strings> with key representing the array index. 927 928=head2 append ( key, string ) 929 930Appends a value to a key and returns its new length. 931 932 $len = $ar->append( 0, "foo" ); 933 934=head2 decr ( key ) 935 936Decrements the value of a key by one and returns its new value. 937 938 $num = $ar->decr( 0 ); 939 940=head2 decrby ( key, number ) 941 942Decrements the value of a key by the given number and returns its new value. 943 944 $num = $ar->decrby( 0, 2 ); 945 946=head2 getdecr ( key ) 947 948Decrements the value of a key by one and returns its old value. 949 950 $old = $ar->getdecr( 0 ); 951 952=head2 getincr ( key ) 953 954Increments the value of a key by one and returns its old value. 955 956 $old = $ar->getincr( 0 ); 957 958=head2 getset ( key, value ) 959 960Sets the value of a key and returns its old value. 961 962 $old = $ar->getset( 0, "baz" ); 963 964=head2 incr ( key ) 965 966Increments the value of a key by one and returns its new value. 967 968 $num = $ar->incr( 0 ); 969 970=head2 incrby ( key, number ) 971 972Increments the value of a key by the given number and returns its new value. 973 974 $num = $ar->incrby( 0, 2 ); 975 976=head1 CREDITS 977 978The implementation is inspired by L<Tie::StdArray>. 979 980=head1 INDEX 981 982L<MCE|MCE>, L<MCE::Hobo>, L<MCE::Shared> 983 984=head1 AUTHOR 985 986Mario E. Roy, S<E<lt>marioeroy AT gmail DOT comE<gt>> 987 988=cut 989 990