Skip to content
Permalink
Browse files

Chaging signature of MapReduce::__construct()

  • Loading branch information...
lorenzo committed Aug 21, 2013
1 parent df43cd8 commit b2756db2c2813368167de0cb440d8eae27e2ff5c
@@ -105,28 +105,18 @@ class MapReduce implements IteratorAggregate {
* }}}
*
* @param \Traversable $data the original data to be processed
* @param array $routines containing the keys `mapper` and `reducer`
* and invokable objects as values
* @param callable $mapper the mapper callback. This function will receive 3 arguments.
* The first one is the current results key, second the current value and third is
* this class instance so you can call the result emitters.
* @param callable $reducer the reducer callback. This function will receive 3 arguments.
* The first one is a bucket name that was mapped before, second one is the list
* of values inside the bucket and third one is an instance of this class.
* @return void
*/
public function __construct(\Traversable $data, array $routines) {
public function __construct(\Traversable $data, callable $mapper, callable $reducer = null) {
$this->_data = $data;
if (empty($routines['mapper'])) {
throw new \InvalidArgumentException(
__d('cake_dev', 'A mapper is required to run MapReduce')
);
}
foreach ($routines as $method) {
if (!method_exists($method, '__invoke')) {
throw new \InvalidArgumentException(
__d('cake_dev', 'Can only pass invokable objects to MapReduce')
);
}
}
$this->_mapper = $routines['mapper'];
$this->_reducer = isset($routines['reducer']) ? $routines['reducer'] : null;
$this->_mapper = $mapper;
$this->_reducer = $reducer;
}
/**
@@ -175,13 +165,15 @@ public function emit($value, $key = null) {
* @return void
*/
protected function _execute() {
$mapper = $this->_mapper;
foreach ($this->_data as $key => $value) {
$this->_mapper->__invoke($key, $value, $this);
$mapper($key, $value, $this);
}
$this->_data = null;
$reducer = $this->_reducer;
foreach ($this->_intermediate as $key => $list) {
$this->_reducer->__invoke($key, $list, $this);
$reducer($key, $list, $this);
}
$this->_intermediate = [];
$this->_executed = true;
@@ -532,7 +532,7 @@ public function applyOptions(array $options) {
* Register a new MapReduce routine to be executed on top of the database results
* Both the mapper and caller callable should be invokable objects.
*
* The MapReduce routing will only be ran when the query is executed and the first
* The MapReduce routing will only be run when the query is executed and the first
* result is attempted to be fetched.
*
* If the first argument is set to null, it will return the list of previously
@@ -553,7 +553,7 @@ public function mapReduce(callable $mapper = null, callable $reducer = null, $ov
if ($mapper === null) {
return $this->_mapReduce;
}
$this->_mapReduce[] = array_filter(compact('mapper', 'reducer'));
$this->_mapReduce[] = compact('mapper', 'reducer');
return $this;
}
@@ -565,8 +565,8 @@ public function mapReduce(callable $mapper = null, callable $reducer = null, $ov
* @return Cake\ORM\ResultCollectionTrait
*/
protected function _applyFormatters($result) {
foreach ($this->_mapReduce as $mappers) {
$result = new MapReduce($result, $mappers);
foreach ($this->_mapReduce as $functions) {
$result = new MapReduce($result, $functions['mapper'], $functions['reducer']);
}
if (!empty($this->_mapReduce)) {
@@ -47,7 +47,7 @@ public function testInvertedIndexCreation() {
$reducer = function($word, $documents, $mr) {
$mr->emit(array_unique($documents), $word);
};
$results = new MapReduce(new ArrayIterator($data), compact('mapper', 'reducer'));
$results = new MapReduce(new ArrayIterator($data), $mapper, $reducer);
$expected = [
'dogs' => array('document_1', 'document_3'),
'are' => array('document_1'),
@@ -81,44 +81,9 @@ public function testEmitFinalInMapper() {
$mr->emit($number);
}
};
$results = new MapReduce(new ArrayIterator($data), compact('mapper'));
$results = new MapReduce(new ArrayIterator($data), $mapper);
$expected = ['one', 'two', 'three', 'four'];
$this->assertEquals($expected, iterator_to_array($results));
}
/**
* Tests that a mapper function is required
*
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage A mapper is required to run MapReduce
* @return void
*/
public function testMapReduceNoMapper() {
new MapReduce(new ArrayIterator([]), ['reducer' => function() {}]);
}
/**
* Tests that the mapper should be invokable
*
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Can only pass invokable objects to MapReduce
* @return void
*/
public function testMapperIsInvokable() {
new MapReduce(new ArrayIterator([]), ['mapper' => [$this, 'setUp']]);
}
/**
* Tests that the reducer should be invokable
*
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Can only pass invokable objects to MapReduce
* @return void
*/
public function testReducerIsInvokable() {
new MapReduce(new ArrayIterator([]), [
'mapper' => function() {},
'reducer' => 'strtolower'
]);
}
}
@@ -913,11 +913,20 @@ public function testMapReduceOnlyMapper() {
$mapper2 = function() {};
$query = new Query($this->connection, $this->table);
$this->assertSame($query, $query->mapReduce($mapper1));
$this->assertSame([['mapper' => $mapper1]], $query->mapReduce());
$this->assertEquals(
[['mapper' => $mapper1, 'reducer' => null]],
$query->mapReduce()
);
$this->assertSame($query, $query->mapReduce($mapper1));
$this->assertEquals($query, $query->mapReduce($mapper1));
$result = $query->mapReduce();
$this->assertEquals([['mapper' => $mapper1], ['mapper' => $mapper2]], $result);
$this->assertEquals(
[
['mapper' => $mapper1, 'reducer' => null],
['mapper' => $mapper2, 'reducer' => null]
],
$result
);
}
/**
@@ -932,13 +941,13 @@ public function testMapReduceBothMethods() {
$reducer2 = function() {};
$query = new Query($this->connection, $this->table);
$this->assertSame($query, $query->mapReduce($mapper1, $reducer1));
$this->assertSame(
$this->assertEquals(
[['mapper' => $mapper1, 'reducer' => $reducer1]],
$query->mapReduce()
);
$this->assertSame($query, $query->mapReduce($mapper2, $reducer2));
$this->assertSame(
$this->assertEquals(
[
['mapper' => $mapper1, 'reducer' => $reducer1],
['mapper' => $mapper2, 'reducer' => $reducer2]
@@ -958,14 +967,14 @@ public function testOverwriteMapReduce() {
$reducer1 = function() {};
$reducer2 = function() {};
$query = new Query($this->connection, $this->table);
$this->assertSame($query, $query->mapReduce($mapper1, $reducer1));
$this->assertSame(
$this->assertEquals($query, $query->mapReduce($mapper1, $reducer1));
$this->assertEquals(
[['mapper' => $mapper1, 'reducer' => $reducer1]],
$query->mapReduce()
);
$this->assertSame($query, $query->mapReduce($mapper2, $reducer2, true));
$this->assertSame(
$this->assertEquals($query, $query->mapReduce($mapper2, $reducer2, true));
$this->assertEquals(
[['mapper' => $mapper2, 'reducer' => $reducer2]],
$query->mapReduce()
);

0 comments on commit b2756db

Please sign in to comment.
You can’t perform that action at this time.