On Mar 5, 2009, at 4:59 PM, Wout Mertens wrote:

Actually, I just did some tests around this, and it turns out that if you always query with group=true, CouchDB never runs the final rereduce!

So based on this, I created this reduce function for reducing a maps emit(key,value) to unique values per key:

function(k,v,r) {
        function unique_inplace(an_array) {
                var first = 0;
                var last = an_array.length;
                // Find first non-unique pair
                for(var firstb; (firstb = first) < last && ++first < last; ) {
                        if(an_array[firstb] == an_array[first]) {
                                // Start copying, skipping uniques
                                for(; ++first < last; ) {
                                        if (!(an_array[firstb] == 
an_array[first])) {
                                                an_array[++firstb] = 
an_array[first];
                                        }
                                }
                                // firstb is at the last element of the new 
array
                                ++firstb;
                                an_array.length = firstb;
                                return;
                        }
                }
        }

        if(r) {
                var arr=[];
                for (var i=0; i<v.length; i++) {
                        arr=arr.concat(v[i]);
                }
                arr=arr.sort();
                unique_inplace(arr);
                return(arr);
        } else {
                var arr=v.sort();
                unique_inplace(arr);
                return(arr);
        }
}

It's not optimal yet, ideally the if(r) section should use an n-way mergesort+uniq since it receives sorted arrays as values. But this also works :).

Thoughts?

Wout.

Reply via email to