Reduce function rereduce question

Just a question about the reduce function documentation, as this is difficult to test, I want to be sure I’m handling it properly.

The reduce function is defined as:

  typedef __nonnull id (^CBLReduceBlock)(NSArray* __nonnull keys,
                                   NSArray* __nonnull values,
                                   BOOL rereduce);

Swift translates this to:

  typealias CBLReduceBlock = ([Any], [Any], Bool) -> Any

However the documentation describes the reduce block as such:

/** A “reduce” function called to summarize the results of a view.
@param keys An array of keys to be reduced (or nil if this is a rereduce).
@param values A parallel array of values to be reduced, corresponding 1::1 with the keys.
@param rereduce YES if the input values are the results of previous reductions.
@return The reduced value; almost always a scalar or small fixed-size object. */

Specifically, the key will be “nil if this is a rereduce.” However, since the key is not an optional–it cannot be nil–am I correct in assuming the key will actually be an empty array if the function is called during a rereduce? Is this is just a documentation bug?


Yeah- the documentation seems misaligned because clearly the function definition states that it is __nonnull. Interestingly, this macro definition aligns with the documentation

#define REDUCEBLOCK(BLOCK) ^id(NSArray* keys, NSArray* values, BOOL rereduce){BLOCK}

Tagging @jens

Looks like the function signature is wrong — the keys parameter should be marked as __nullable in the header file.

However, rereduce isn’t actually implemented in CBL; and since we no longer use map/reduce in CBL 2, it’s safe to say it will never be implemented. So your reduce function will never be called with a nil keys array.

(The purpose of rereduce is to allow the database to perform the reduction incrementally. Couchbase Server has a clever mechanism built into its b-tree storage engine that allows it to persist reduced values, making reduced queries very fast. There wasn’t any straightforward way to do this in CBL since we use SQLite’s existing storage engine.)