Compare two bson_t in C / C++ - c++

I need to compare two bson_t. I found that two bson_t s may have different sequence of key-value pairs. for example {"key1": "val1", "key2" : "val2"} and {"key2": "val2", "key1" : "val1"}. But they are the same in my project. bson_compare() and bson_equal() will return false in this case. How to solve this problem in C/C++?
By the way, how to sort these key-value pairs in C or C++?
Thanks

bson_compare and bson_equal check if two content buffers are equal (not only values # two buffers (or memory locations)). It uses memcmp internally to compare two objects. Hence, x==y does not imply that memcmp(x,y)==0.

Two methods:
(1) It is easy to do this in Python. Write a python function. And call this python function from C++ program.
(2) Using bson_iter_t to iterate each key-value pair in bson_t and do comparison recursively.
The second method seems more complex. But I decided to use it. Now, I already finished part of the method.

Related

Tuple Concatenation in Chapel

Let's say I'm generating tuples and I want to concatenate them as they come. How do I do this? The following does element-wise addition:
if ts = ("foo", "cat"), t = ("bar", "dog")
ts += t gives ts = ("foobar", "catdog"),
but what I really want is ts = (("foo","cat"),("bar","dog")).
So I guess the first question is "does Chapel support tuple concatention?", then "is there a binary operator/function for it?", then "if not, what is a good way to do it?", and lastly "make my life easier if you know a better way of living".
Please address the questions in order.
I appreciate the help!!
the first question is "does Chapel support tuple concatention?"
I believe the answer here is "no" for the following reason: (1) A Chapel variable has a single static type that cannot change over its lifetime, and (2) a tuple's type is defined as its static number of elements as well as the type of each element. Thus, given your variable ts
ts = ("foo", "cat")
its type is 2*string ("a 2-tuple of strings") and this would prevent it from ever being able to store the value (("foo","cat"),("bar","dog")) since its type is 2*(2*string) ("a 2-tuple of 2-tuples of strings"). So while these two tuples have the same number of elements (2), they differ in their element types ("string" vs. "2-tuple of string") and therefore aren't the same type (aren't compatible).
"is there a binary operator/function for it?"
Due to the above, no.
then "if not, what is a good way to do it?"
A few things come to mind, but may or may not be helpful depending on your specific situation. Rather than trying to re-assign ts, you could create a new tuple that was a tuple-of-tuples:
const ts2 = (ts, t);
and you could even do this recursively in a routine, though that would likely end up blowing up your code size if the tuple grew to any significant length (because each call to the function would generate a tuple of a different type and unique code for it).
From what I'm seeing in your question, I think you may want to use a list of tuples or a 1D array (vector) of tuples. Here's a list-based approach:
use List;
var listOfTups: list(2*string);
listOfTups.append(("foo", "cat"));
listOfTups.append(("bar", "dog"));
writeln(listOfTups);
And here's an array-based approach:
var arrOfTups: [1..0] 2*string;
arrOfTups.push_back(("foo", "cat"));
arrOfTups.push_back(("bar", "dog"));
writeln(arrOfTups);
Of the two, I would recommend the array-based approach because arrays are much more first-class and powerful in Chapel (they enjoy syntactic support, permit data parallelism, support promotion of scalar functions and operators, etc.) whereas lists are just a convenience library.
and lastly "make my life easier if you know a better way of living".
One other related thing I can think of to mention if you're not aware of it is that "varargs" functions in Chapel effectively convert those arguments to tuples. So given:
proc myFunc(x...) {
writeln(x.type:string);
}
myFunc(("foo", "cat"), ("bar", "dog"));
the output is:
2*2*string

Why do CouchDB reduce functions receive 'keys' as an argument

With a CouchDB reduce function:
function(keys, values, rereduce) {
// ...
}
That gets called like this:
reduce( [[key1,id1], [key2,id2], [key3,id3]], [value1,value2,value3], false )
Question 1
What is the reason for passing keys to the reduce function? I have only written relatively simple CouchDB views with reduce functions and would like to know what the use case is for receiving a list of [key1, docid], [key2, docid], etc is.
Also. is there ever a time when key1 != key2 != keyX when a reduce function executes?
Question 2
CouchDB's implementation of MapReduce allows for rereduce=true, in which case the reduce function is called like this:
reduce(null, [intermediate1,intermediate2,intermediate3], true)
Where the keys argument is null (unlike when rereduce=false). Why would there not be a use case for a keys argument in this case if there was a use for when rereduce=false?
What is the use case of keys argument when rereduce = true?
There isn't one. That's why the keys argument is null in this case.
From the documentation (emphasis added):
Reduce and Rereduce Functions
redfun(keys, values[, rereduce])
Arguments:
keys – Array of pairs of key-docid for related map function results. Always null if rereduce is running (has true value).
values – Array of map function result values.
rereduce – Boolean flag to indicate a rereduce run.
Perhaps what you're meaning to ask is: Why is the same function used for both reduce and rereduce? I expect there's some history involved, but I can also imagine that it's because it's quite common that the same logic can be used for both functions, and by not having separate function definitions duplication can be reduced. Suppose a simple sum reduce function:
function(keys, values) {
return sum(values);
}
Here both keys and rereduce can be ignored entirely. Many other (re)reduce functions follow the same pattern. If two functions had to be used, then this identical function would have to be specified twice.
In response to the additional question in comments:
what use cases exist for the keys argument when rereduce=false?
Remember, keys and values can be anything, based on the map function. A common pattern is to emit([foo,bar,baz],null). That is to say, the value may be null, if all the data you care about is already present in the key. In such a case, any reduce function more complex than a simple sum would require use of the keys.
Further, for grouping operations, using the keys makes sense. Consider a map function with emit(doc.countryCode, ... ), a possible (incomplete) reduce function:
function(keys, values, rereduce) {
const sums = {};
if (!rereduce) {
keys.forEach((key) => ++sums[key]);
}
return sums;
}
Then given documents:
{"countryCode": "us", ...}
{"countryCode": "us", ...}
{"countryCode": "br", ...}
You'd get emitted values (from the map function) of:
["us", ...]
["br", ...]
You'd a reduced result of:
{"us": 2, "br": 1}

Prolog: take a list of two elements, return true if and only if the first element is same as second

I'm a newbie prolog programmer, and for an assignment, I have to have a basic program that succeeds if and only if list X is a list of two elements, with the first as the same as the second.
From my view of prolog, programs seem to be pretty small, so I typed this in:
firstPair(x,x).
When I run it under swipl, I get this as output:
Syntax error: Operator expected
Is there something more that needs to be done? I thought that if I executed this with say, firstPair(1,2). this would be all it would need to know that it is false.
First, lowercase x is not a variable, it's an atom. Make x uppercase to fix the problem:
firstPair(X,X).
Second, you do not type this into the interpreter. Rather, you write it into a file firstPair.pl, and then read that file into Prolog.
At the command prompt, type this:
['firstPair.pl'].
Press enter. Now you can use your firstPair/2 rule.
Finally, since the assignment talks about lists, I think the instructor wanted you to write firstPair/1, not firstPair/2:
firstPair([X,X]).
Your program/fact
firstPair(X,X).
will succeed if the two arguments given it can be unified, whether they are lists, atoms, variables, etc. To meet your specification, a
program that succeeds if and only if list X is a list of two elements,
with the first as the same as the second.
You need something like this:
list_of_two_elements( [X,X] ).
This will succeed if passed a single term that is (or can be unified with) a list of two elements that are, or can be made through unification, identical. For instance, all of the following will succeed:
list_of_two_elements( X ).
on success, the variable X will be unified with a list of two elements containing the same unbound variable, something like [V1,V1].
list_of_two_elements( [1,1] ).
list_of-two_elements( [1,X] ). (on success, X here will have been unified with the integer 1.)

Python array management C++ equivalent

I know SO is not rent-a-coder, but I have a really simple python example that I need help translating to C++
grey_image_as_array = numpy.asarray( cv.GetMat( grey_image ) )
non_black_coords_array = numpy.where( grey_image_as_array > 3 )
# Convert from numpy.where()'s two separate lists to one list of (x, y) tuples:
non_black_coords_array = zip( non_black_coords_array[1], non_black_coords_array[0] )
First one is rather simple I guess - a linear indexable array is created with what bytes are retruned from cv.GetMat, right?
What would be an equivalent of pyton's where and especially this zip functions?
I don't know about OpenCV, so I can't tell you what cv.GetMat() does. Apparently, it returns something that can be used as or converted to a two-dimensional array. The C or C++ interface to OpenCV that you are using will probably have a similarly names function.
The following lines create an array of index pairs of the entries in grey_image_as_array that are bigger than 3. Each entry in non_black_coords_array are zero based x-y-coordinates into grey_image_as_array. Given such a coordinates pair x, y, you can access the corresponsing entry in the two-dimensional C++ array grey_image_as_array with grey_image_as_array[y][x].
The Python code has to avoid explicit loops over the image to achieve good performance, so it needs to make to with the vectorised functions NumPy offers. The expression grey_image_as_array > 3 is a vectorised comparison and results in a Boolean array of the same shape as grey_image_as_array. Next, numpy.where() extracts the indices of the True entries in this Boolean array, but the result is not in the format described above, so we need zip() to restructure it.
In C++, there's no need to avoid explicit loops, and an equivalent of numpy.where() would be rather pointless -- you just write the loops and store the result in the format of your choice.

Sorting names with numbers correctly

For sorting item names, I want to support numbers correctly. i.e. this:
1 Hamlet
2 Ophelia
...
10 Laertes
instead of
1 Hamlet
10 Laertes
2 Ophelia
...
Does anyone know of a comparison functor that already supports that?
(i.e. a predicate that can be passed to std::sort)
I basically have two patterns to support: Leading number (as above), and number at end, similar to explorer:
Dolly
Dolly (2)
Dolly (3)
(I guess I could work that out: compare by character, and treat numeric values differently. However, that would probably break unicode collaiton and whatnot)
That's called alphanumeric sorting.
Check out this link: The Alphanum Algorithm
i think u can use a pair object and then make vector > and then sort this vector.
Pairs are compared based on their first elements. So, this way you can get the sort you desire.