Advertisement
parent5446

Untitled

Jun 10th, 2013
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 10.41 KB | None | 0 0
  1. <?php
  2.  
  3. if ( class_exists( 'SplDoublyLinkedList' ) ) {
  4.     return;
  5. }
  6.  
  7. class SplInternalItem {
  8.     public $data = null;
  9.     public $next = null;
  10.     public $prev = null;
  11. }
  12.  
  13. class SplDoublyLinkedList implements Iterator, ArrayAccess, Countable, Serializable {
  14.     const IT_MODE_LIFO = 2;
  15.  
  16.     const IT_MODE_FIFO = 0;
  17.  
  18.     const IT_MODE_DELETE = 1;
  19.  
  20.     const IT_MODE_KEEP = 0;
  21.  
  22.     protected $head = null;
  23.  
  24.     protected $tail = null;
  25.  
  26.     protected $key = 0;
  27.  
  28.     protected $current = null;
  29.  
  30.     protected $count = 0;
  31.  
  32.     protected $mode = 0;
  33.  
  34.     public function bottom() {
  35.         if ( $head === null ) {
  36.             throw new RuntimeException( 'List is empty' );
  37.         }
  38.         return $head->data;
  39.     }
  40.  
  41.     public function top() {
  42.         if ( $tail === null ) {
  43.             throw new RuntimeException( 'List is empty' );
  44.         }
  45.         return $tail->data();
  46.     }
  47.  
  48.     public function isEmpty() {
  49.         return !$this->count;
  50.     }
  51.  
  52.     public function push( $value ) {
  53.         $node = new SplInternalItem;
  54.         $node->data = $value;
  55.  
  56.         if ( $this->isEmpty() ) {
  57.             $this->head = $node;
  58.             $this->tail = $node;
  59.         } else {
  60.             $node->prev = $this->tail;
  61.             $this->tail->next = $node;
  62.             $this->tail = $node;
  63.         }
  64.  
  65.         ++$this->count;
  66.         return;
  67.     }
  68.  
  69.     public function pop() {
  70.         $retval = $this->top();
  71.         $tail = $tail->prev;
  72.         --$this->count;
  73.         return $retval;
  74.     }
  75.  
  76.     public function unshift( $value ) {
  77.         $node = new SplInternalItem;
  78.         $node->data = $value;
  79.  
  80.         if ( $this->isEmpty() ) {
  81.             $this->head = $this->tail = $node;
  82.         } else {
  83.             $node->next = $this->head;
  84.             $this->head->prev = $node;
  85.             $this->head = $node;
  86.         }
  87.  
  88.         ++$this->count;
  89.         return;
  90.     }
  91.  
  92.     public function shift() {
  93.         $retval = $this->bottom();
  94.         $head = $head->next;
  95.         --$this->count;
  96.         return $retval;
  97.     }
  98.  
  99.  
  100.     public function current() {
  101.         return $this->current->data;
  102.     }
  103.  
  104.     public function key() {
  105.         return $this->key;
  106.     }
  107.  
  108.     public function next() {
  109.         ++$this->key;
  110.  
  111.         if ( $this->mode & IT_MODE_DELETE ) {
  112.             --$this->count;
  113.             if ( $this->current->prev !== null ) {
  114.                 $this->current->prev->next = $this->current->next;
  115.             }
  116.             if ( $this->current->next !== null ) {
  117.                 $this->current->next->prev = $this->current->prev;
  118.             }
  119.         }
  120.  
  121.         if ( $this->mode & self::IT_MODE_LIFO ) {
  122.             $this->current = $this->current->prev;
  123.         } else {
  124.             $this->current = $this->current->next;
  125.         }
  126.     }
  127.  
  128.     public function prev() {
  129.         --$this->key;
  130.  
  131.         if ( $this->mode & IT_MODE_DELETE ) {
  132.             --$this->count;
  133.             if ( $this->current->prev !== null ) {
  134.                 $this->current->prev->next = $this->current->next;
  135.             }
  136.             if ( $this->current->next !== null ) {
  137.                 $this->current->next->prev = $this->current->prev;
  138.             }
  139.         }
  140.  
  141.         if ( $this->mode & self::IT_MODE_LIFO ) {
  142.             $this->current = $this->current->next;
  143.         } else {
  144.             $this->current = $this->current->prev;
  145.         }
  146.     }
  147.  
  148.     public function rewind() {
  149.         $this->key = 0;
  150.         if ( $this->mode & self::IT_MODE_LIFO ) {
  151.             $this->current = $this->tail;
  152.         } else {
  153.             $this->current = $this->head;
  154.         }
  155.     }
  156.  
  157.     public function valid() {
  158.         return $this->current !== null;
  159.     }
  160.  
  161.     public function getIteratorMode() {
  162.         return $this->mode;
  163.     }
  164.  
  165.     public function setIteratorMode( $mode ) {
  166.         $this->mode = mode;
  167.     }
  168.  
  169.  
  170.     public function offsetExists( $index ) {
  171.         return $index < $this->count;
  172.     }
  173.  
  174.     public function offsetGet( $index ) {
  175.         $node = $this->head;
  176.         for ( $i = 0; $i < $index && $node !== null; ++$i ) {
  177.             $node = $node->next;
  178.         }
  179.         return $node ? $node->data : null;
  180.     }
  181.  
  182.     public function offsetSet( $index, $newval ) {
  183.         $node = $this->head;
  184.         if ( $index === null ) {
  185.             $index = $this->count;
  186.         }
  187.         for ( $i = 0; $i < index; ++$i ) {
  188.             if ( $node->next === null ) {
  189.                 ++$this->count;
  190.                 $node->next = new SplInternalItem;
  191.                 $node->next->prev = $node;
  192.             }
  193.             $node = $node->next;
  194.         }
  195.         $node->data = $newval;
  196.     }
  197.  
  198.     public function offsetUnset( $index ) {
  199.         $node = $this->head;
  200.         for ( $i = 0; $i < $index && $node !== null; ++$i ) {
  201.             $node = $node->next;
  202.         }
  203.         if ( $node ) {
  204.             --$this->count;
  205.             $node->prev->next = $node->next;
  206.             $node->next->prev = $node->prev;
  207.         }
  208.     }
  209.  
  210.  
  211.     public function count() {
  212.         return $this->count;
  213.     }
  214.  
  215.  
  216.     public function serialize() {
  217.         $data = array();
  218.         while ( !$this->isEmpty() ) {
  219.             $data[] = $this->shift();
  220.         }
  221.         return serialize( $data );
  222.     }
  223.  
  224.     public function unserialize( $serialized ) {
  225.         $obj = new self;
  226.         foreach ( unserialize( $serialized ) as $data ) {
  227.             $this->push( $data );
  228.         }
  229.     }
  230. }
  231.  
  232. class SplQueue extends SplDoublyLinkedList implements Iterator, ArrayAccess, Countable {
  233.     public function dequeue() {
  234.         return $this->pop();
  235.     }
  236.  
  237.     public function enqueue( $value ) {
  238.         $this->unshift( $value );
  239.     }
  240.  
  241.     public function setIteratorMode( $mode ) {
  242.         if ( $mode & self::IT_MODE_LIFO ) {
  243.             throw new RuntimeException( 'SplQueue can only be used in FIFO mode.' );
  244.         }
  245.         parent::setIteratorMode( $mode );
  246.     }
  247. }
  248.  
  249. class SplStack extends SplDoublyLinkedList implements Iterator, ArrayAccess, Countable {
  250.     public function __construct() {
  251.         $this->setIteratorMode( self::IT_MODE_LIFO | self::IT_MODE_KEEP );
  252.     }
  253.  
  254.     public function setIteratorMode( $mode ) {
  255.         if ( $mode & self::IT_MODE_FIFO ) {
  256.             throw new RuntimeException( 'SplStack can only be used in LIFO mode.' );
  257.         }
  258.         parent::setIteratorMode( $mode );
  259.     }
  260. }
  261.  
  262. class SplFixedArray implements Iterator, ArrayAccess, Countable {
  263.     protected $data = array();
  264.  
  265.     protected $current = 0;
  266.  
  267.     public function __construct( $size = 0 ) {
  268.         if ( $size > 0 ) {
  269.             $this->data = array_fill( 0, $size, null );
  270.         }
  271.     }
  272.  
  273.     public function current() {
  274.         return current( $this->data );
  275.     }
  276.  
  277.     public function key() {
  278.         return key( $this->data );
  279.     }
  280.  
  281.     public function next() {
  282.         next( $this->data );
  283.     }
  284.  
  285.     public function rewind() {
  286.         reset( $this->data );
  287.     }
  288.  
  289.     public function valid() {
  290.         return isset( $this->data[$this->current] );
  291.     }
  292.  
  293.  
  294.     public function offsetExists( $index ) {
  295.         return $index < count( $this->data );
  296.     }
  297.  
  298.     public function offsetGet( $index ) {
  299.         return $this->data[$index];
  300.     }
  301.  
  302.     public function offsetSet( $index, $newval ) {
  303.         if ( $index === null ) {
  304.             throw new RuntimeException( 'Must specify key for fixed array' );
  305.         }
  306.         $this->data[$index] = $newval;
  307.     }
  308.  
  309.     public function offsetUnset( $index ) {
  310.         $this->data[$index] = null;
  311.     }
  312.  
  313.  
  314.     public function count() {
  315.         return count( $this->data );
  316.     }
  317. }
  318.  
  319. abstract class SplHeap implements Iterator, Countable {
  320.     protected $heap = array();
  321.  
  322.     protected $count = 0;
  323.  
  324.     protected $key = 0;
  325.  
  326.     abstract protected function compare( $value1, $value2 );
  327.  
  328.     public function extract() {
  329.         $index = 0;
  330.         $value = $this->heap[$index];
  331.         $this->heap[$index] = $this->heap[count( $this->heap ) - 1];
  332.         unset( $this->heap[count( $this->heap ) - 1] );
  333.  
  334.         while ( $index < count( $this->heap ) ) {
  335.             $child1 = $index * 2;
  336.             $child2 = $child1 + 1;
  337.  
  338.             $min = $index;
  339.  
  340.             if (
  341.                 isset( $this->heap[$child1] ) &&
  342.                 $this->compare( $this->heap[$child1], $this->heap[$min] ) < 0
  343.             ) {
  344.                 $min = $child1;
  345.             }
  346.  
  347.             if (
  348.                 isset( $this->heap[$child2] ) &&
  349.                 $this->compare( $this->heap[$child2], $this->heap[$min] ) < 0
  350.             ) {
  351.                 $min = $child2;
  352.             }
  353.  
  354.             if ( $min !== $index ) {
  355.                 $tmp = $this->heap[$index];
  356.                 $this->heap[$index] = $this->heap[$min];
  357.                 $this->heap[$min] = $tmp;
  358.                 $index = $min;
  359.             }
  360.         }
  361.  
  362.         return $value;
  363.     }
  364.  
  365.     public function insert( $value ) {
  366.         $index = count( $this->heap );
  367.         $this->heap[$index] = $value;
  368.  
  369.         while ( $index ) {
  370.             $parent = floor( $index / 2 );
  371.             if ( $this->compare( $this->heap[$index], $this->heap[$parent] ) < 0 ) {
  372.                 $this->heap[$index] = $this->heap[$parent];
  373.                 $this->heap[$parent] = $value;
  374.             }
  375.             $index = $parent;
  376.         }
  377.     }
  378.  
  379.     public function isEmpty() {
  380.         return $this->head === null;
  381.     }
  382.  
  383.     public function recoverFromCorruption() {
  384.     }
  385.  
  386.     public function top() {
  387.         if ( $this->head === null ) {
  388.             return null;
  389.         } else {
  390.             return $this->head->data;
  391.         }
  392.     }
  393.  
  394.  
  395.     public function current() {
  396.         return $this->top();
  397.     }
  398.  
  399.     public function key() {
  400.         return $this->key;
  401.     }
  402.  
  403.     public function next() {
  404.         ++$this->key;
  405.         $this->extract();
  406.     }
  407.  
  408.     public function rewind() {
  409.         $this->key = 0;
  410.     }
  411.  
  412.     public function valid() {
  413.         return $this->head !== null;
  414.     }
  415.  
  416.  
  417.     public function count() {
  418.         return $this->count;
  419.     }
  420. }
  421.  
  422. class SplMaxHeap extends SplHeap {
  423.     protected function compare( $value1, $value2 ) {
  424.         if ( $value1 < $value2 ) {
  425.             return -1;
  426.         } elseif ( $value1 > $value2 ) {
  427.             return 1;
  428.         } else {
  429.             return 0;
  430.         }
  431.     }
  432. }
  433.  
  434. class SplMinHeap extends SplHeap {
  435.     protected function compare( $value1, $value2 ) {
  436.         if ( $value1 < $value2 ) {
  437.             return 1;
  438.         } elseif ( $value1 > $value2 ) {
  439.             return -1;
  440.         } else {
  441.             return 0;
  442.         }
  443.     }
  444. }
  445.  
  446. class SplPriorityQueue implements Iterator, Countable {
  447.     const EXTR_DATA = 1;
  448.  
  449.     const EXTR_PRIORITY = 2;
  450.  
  451.     const EXTR_BOTH = 3;
  452.  
  453.     protected $flags = 1;
  454.  
  455.     protected $heap;
  456.  
  457.     public function __construct() {
  458.         $this->heap = new SplMaxHeap;
  459.     }
  460.  
  461.     public function extract() {
  462.         $info = $this->heap->extract();
  463.         if ( $this->flags === self::EXTR_DATA ) {
  464.             return $info[1];
  465.         } elseif ( $this->flags === self::EXTR_PRIORITY ) {
  466.             return $info[0];
  467.         } else {
  468.             return $info;
  469.         }
  470.     }
  471.  
  472.     public function insert( $value, $priority ) {
  473.         $this->heap->insert( array( $value, $priority ) );
  474.     }
  475.  
  476.     public function isEmpty() {
  477.         return $this->heap->isEmpty();
  478.     }
  479.  
  480.     public function recoverFromCorruption() {
  481.         $this->heap->recoverFromCorruption();
  482.     }
  483.  
  484.     public function setExtractFlags( $flags ) {
  485.         $this->flags = $flags;
  486.     }
  487.  
  488.     public function top() {
  489.         return $this->heap->top();
  490.     }
  491.  
  492.  
  493.     public function current() {
  494.         $info = $this->heap->current();
  495.         if ( $this->flags === self::EXTR_DATA ) {
  496.             return $info[1];
  497.         } elseif ( $this->flags === self::EXTR_PRIORITY ) {
  498.             return $info[0];
  499.         } else {
  500.             return $info;
  501.         }
  502.     }
  503.  
  504.     public function key() {
  505.         return $this->heap->key();
  506.     }
  507.  
  508.     public function next() {
  509.         return $this->heap->next();
  510.     }
  511.  
  512.     public function rewind() {
  513.         return $this->heap->rewind();
  514.     }
  515.  
  516.     public function valid() {
  517.         return $this->heap->valid();
  518.     }
  519.  
  520.  
  521.     public function count() {
  522.         return $this->heap->count();
  523.     }
  524. }
  525.  
  526. class SplTempFileObject extends SplFileObject {
  527.     public function __construct( $maxMemory = null ) {
  528.         if ( $maxMemory === null ) {
  529.             parent::construct( 'php://temp', 'r+' );
  530.         } else {
  531.             parent::construct( "php://temp/maxmemory:$maxMemory", 'r+' );
  532.         }
  533.     }
  534. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement