ConstValue LocalView::runReduce(const ConstValue &rows) const { AutoArray<KeyAndDocId, SmallAlloc<256> > keylist; AutoArray<ConstValue, SmallAlloc<256> > values; keylist.reserve(rows.length()); values.reserve(rows.length()); for (JSON::ConstIterator iter = rows->getFwConstIter(); iter.hasItems();) { const JSON::ConstValue &v = iter.getNext(); keylist.add(KeyAndDocId(v["key"],v["id"].getStringA())); values.add(v["value"]); } return reduce(keylist,values,false); }
ConstValue LocalView::searchKeys(const ConstValue &keys, natural groupLevel) const { Shared _(lock); Container rows = json.array(); bool grouped = groupLevel > 0 && groupLevel < naturalNull; for (natural i = 0; i < keys.length(); i++) { ConstValue subrows = searchOneKey(keys[i]); if (grouped) { ConstValue r = runReduce(subrows); if (r == null) grouped = false; else { subrows = json("key", keys[i]) ("value", r); } } rows.load(subrows); } if (groupLevel == 0) { ConstValue r = runReduce(rows); if (r != null) { rows = json << json("key",null) ("value",r); } } return json("rows",rows)("total_rows",keyToValueMap.length()); }
static bool canGroupKeys(const ConstValue &subj, const ConstValue &sliced) { if (sliced == null) return false; if (subj->isArray()) { natural cnt = subj.length(); if (cnt >= sliced.length()) { cnt = sliced.length(); } else { return false; } for (natural i = 0; i < cnt; i++) { if (compareJson(subj[i],sliced[i]) != cmpResultEqual) return false; } return true; } else { return compareJson(subj,sliced) == cmpResultEqual; } }
static ConstValue sliceKey(const ConstValue &key, natural groupLevel, const Json &json) { if (key->isArray()) { if (key.length() <= groupLevel) return key; Container out = json.array(); for (natural i = 0; i < groupLevel; i++) out.add(key[i]); return out; } else { return key; } }