How do I handle multiple notification of ReadDirectoryChangesW()? - readdirectorychangesw

I implemented using ReadDirectoryChangesW() function to figure out any change information of files of the specific directory.
However, the API sent me duplicated notifications. For example, I monitor the directory "C:\abc\" using only FILE_NOTIFY_CHANGE_SIZE flag without watching subdirectory. And, I tried edit and save a image file on the directory. ex) C:\abc\imageFile.png
Then, two or much more the notifications were sent me. Actually, I understand why there are multiple notifications. I read this article. (http://blogs.msdn.com/b/oldnewthing/archive/2014/05/07/10523172.aspx)
But, I don't know how to handle the multiple notifications.
My goal is synchronizing the image files on some win32 application when the images are changed.

The documentation for FILE_NOTIFY_INFORMATION tells us:
NextEntryOffset
The number of bytes that must be skipped to get to the next record. A value of zero indicates that this is the last record.
So we check that field, and if it isn't zero, we create a new pointer which is that many bytes past the old one. The code will look something like this:
FILE_NOTIFY_INFORMATION* p = &s.changeInformation;
while (1) {
std::wcout << L" action " << p->Action << L"\n";
std::wcout << L" file ";
std::wcout.write(p->FileName, p->FileNameLength / sizeof (wchar_t)) << L"\n";
if (!p->NextEntryOffset) break;
p = reinterpret_cast<decltype(p)>(p->NextEntryOffset + reinterpret_cast<uintptr_t>(p));
}
We have to cast, because the value is in bytes, and pointer arithmetic automatically measures distances in objects not bytes.

Related

MPI_Send does not work with higher buffer size?

When MPI_Send buffer size is 100 program works, but it stucks when it is 1000 or greater. Why?
if(id == 0){
rgb_image = stbi_load(argv[1], &width, &height, &bpp, CHANNEL_NUM);
for(int i = 0; i < size -1; i++)
MPI_Send(rgb_image,1000,MPI_UINT8_T,i,0,MPI_COMM_WORLD);
}
uint8_t *part = (uint8_t*) malloc(sizeof(uint8_t)*(1000));
if(id != size-1 && size > 1)
MPI_Recv(part,1000,MPI_UINT8_T,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
This program is not valid w.r.t. MPI Standard since there is no matching receive (on rank 0) for
MPI_Send(..., dest=0, ...)
MPI_Send() is allowed to block until a matching receive is posted (and that generally happens when the message is "large") ... and the required matching receive never gets posted.
A typical fix would be to issue a MPI_Irecv(...,src = 0,...) on rank 0 before the MPI_Send() (and MPI_Wait() after), or to handle 0 -> 0 communication with MPI_Sendrecv().
That being said, it would likely more efficient to create a communicator will all the ranks minus the last one, and MPI_Bcast() in this communicator.
If a program works for small buffers but not for large, you are probably running into "eager sends". Normally, a send & receive transaction involves the sender & receiver talking back and forth, confirming that the data went across. This is overhead, so for small messages, many MPIs will just send the data, without confirmation. The data then goes into some secret buffer on the receiver.
But this means that your program will "succeed" if it's not a correct program. As is the case here. See #Giles answer.

Why should we use OutputStream.write(byte[] b, int off, int len) instead of OutputStream.write(byte[] b)?

Sorry, everybody. It's a Java beginner question, but I think it will be helpful for a lot of java learners.
FileInputStream fis = new FileInputStream(file);
OutputStream os = socket.getOutputStream();
byte[] buffer = new byte[1024];
int len;
while((len=fis.read(buffer)) != -1){
os.write(buffer, 0, len);
}
The code above is part of FileSenderClient class which is for sending files from client to a server using java.io and java.net.Socket.
My question is that: in the above code, why should we use
os.write(buffer, 0, len)
instead of
os.write(buffer)
In another way to ask this question: what is the point of having a "len" parameter for "OutputStream.write()" method?
It seems both codes are working fine.
while((len=fis.read(buffer)) != -1){
os.write(buffer, 0, len);
}
Because you only want to write data that you actually read. Consider the case where the input consists of N buffers plus one byte. Without the len parameter you would write (N+1)*1024 bytes instead of N*1024+1 bytes. Consider also the case of reading from a socket, or indeed the general case of reading: the actual contract of InputStream.read() is that it transfers at least one byte, not that it fills the buffer. Often it can't, for one reason or another.
It seems both codes are working fine.
No they're not.
It actually does not work in the same way.
It is very likely you used a very small text file to test. But if you look carefully, you will still find there is a lot of extra spaces in the end of you file you received, and the size of the file you received is larger than the file you send.
The reason is that you have created a byte array in a size of 1024 but you don't have so many data to put (or read()) into that byte array. Therefore, the byte array is full with NULL in the end part. When it comes to writing to file, these NULLs are still written into the file and show as spaces " " in Windows Notepad...
If you use advanced text editors like Notepad++ or Sublime Text to view the file you received, you will see these NULL characters.

Static lookup table (litteral bit map)

I am receiving some data which is parsed in a Ruby script, a sample of the parsed data looks like this;
{"address":"00","data":"FF"}
{"address":"01","data":"00"}
That data relates to the status (on/off) of plant items (Fans, coolers, heaters etc.) the address is a HEX number to tell you which set of bits the data refers to. So in the example above the lookup table would be; Both of these values are received as HEX as in this example.
Bit1 Bit2 Bit3 Bit4 Bit5 Bit6 Bit7 Bit8
Address 00: Fan1 Fan2 Fan3 Fan4 Cool1 Cool2 Cool3 Heat1
Address 01: Hum1 Hum2 Fan5 Fan6 Heat2 Heat3 Cool4 Cool5
16 Addresses per block (This example is 00-0F)
Data: FF tells me that all items in Address 00 are set on (high/1) I then need to output the result of the lookup for each individual bit e.g
{"element":"FAN1","data":{"type":"STAT","state":"1"}}
{"element":"FAN2","data":{"type":"STAT","state":"1"}}
{"element":"FAN3","data":{"type":"STAT","state":"1"}}
{"element":"FAN4","data":{"type":"STAT","state":"1"}}
{"element":"COOL1","data":{"type":"STAT","state":"1"}}
{"element":"COOL2","data":{"type":"STAT","state":"1"}}
{"element":"COOL3","data":{"type":"STAT","state":"1"}}
{"element":"HEAT1","data":{"type":"STAT","state":"1"}}
A lookup table could be anything up to 2048 bits (though I don't have anything that size in use at the moment - this is maximum I'd need to scale to)
The data field is the status of the all 8 bits per address, some may be on some may be off and this updates every time my source pushes new data at me.
I'm looking for a way to do this in code ideally for the lay-person as I'm still very new to doing much with Ruby. There was a code example here, but it was not used in the end and has been removed from the question so as not to confuse.
Based on the example below I've used the following code to make some progress. (note this integrates with an existing script all of which is not shown here. Nor is the lookup table shown as its quite big now.)
data = [feeder]
data.each do |str|
hash = JSON.parse(str)
address = hash["address"]
number = hash["data"].to_i(16)
binary_str = sprintf("%0.8b", number)
binary_str.reverse.each_char.with_index do |char, i|
break if i+1 > max_binary_digits
mouse = {"element"=>+table[address][i], "data"=>{"type"=>'STAT', "state"=>char}}
mousetrap = JSON.generate(mouse)
puts mousetrap
end
end
This gives me an output of {"element":"COOL1","data":{"type":"STAT","state":"0"}} etc... which in turn gives the correct output via my node.js script.
I have a new problem/query having got this to work and captured a whole bunch of data from last night & this morning. It appears that now I've built my lookup table I need some of the results to be modified based on the result of the lookup. I have other sensors which need to generate a different output to feed my SVG for example;
FAN objects need to output {"element":"FAN1","data":{"type":"STAT","state":"1"}}
DOOR objects need to output {"element":"DOOR1","data":{"type":"LAT","state":"1"}}
SWIPE objects need to output {"element":"SWIPE6","data":{"type":"ROUTE","state":"1"}}
ALARM objects need to output {"element":"PIR1","data":{"type":"PIR","state":"0"}}
This is due to the way the SVG deals with updating - I'm not in a position to modify the DOM stuff so would need to fix this in my Ruby script.
So to address this what I ended up doing was making an exact copy of my existing lookup table and rather than listing the devices I listed the type of output like so;
Address 00: STAT STAT STAT ROUTE ROUTE LAT LAT PIR
Address 01: PIR PIR STAT ROUTE ROUTE LAT LAT PIR
This might be very dirty (and it also means I have to duplicate my lookup table, but it actually might be better for my specific needs as devices within the dataset could have any name (I have no control over the received data) Having built a new lookup table I modified the code I had been provided with below and already used for the original lookup but I had to remove these 2 lines. Without removing them I was getting the result of the lookup output 8 times!
binary_str.reverse.each_char.with_index do |char, i|
break if i+1 > max_binary_digits
The final array was built using the following;
mouse = {"element"=>+table[address][i], "data"=>{"type"=>typetable[address][i], "state"=>char}}
mousetrap = JSON.generate(mouse)
puts mousetrap
This gave me exactly the output I require and was able to integrate with both the existing script, node.js websocket & mongodb 'state' database (which is read on initial load)
There is one last thing I'd like to try and do with this code, when certain element states are set to 1 I'd like to be able to look something else up (and then use that result) I'm thinking this may be best done with a find query to my MongoDB and then just use the result. Doing that would hit the db for every query, but there would only ever be a handful or results so most things would return null which is fine. Am I along the right method of thinking?
require 'json'
table = {
"00" => ["Fan1", "Fan2", "Fan3"],
"01" => ["Hum1", "Hum2", "Fan5"],
}
max_binary_digits = table.first[1].size
data = [
%Q[{"address": "00","data":"FF"}],
%Q[{"address": "01","data":"00"}],
%Q[{"address": "01","data":"03"}],
]
data.each do |str|
hash = JSON.parse(str)
address = hash["address"]
number = hash["data"].to_i(16)
binary_str = sprintf("%0.8b", number)
p binary_str
binary_str.reverse.each_char.with_index do |char, i|
break if i+1 > max_binary_digits
puts %Q[{"element":#{table[address][i]},"data":{"type":"STAT","state":"#{char}"}}}]
end
puts "-" * 20
end
--output:--
"11111111"
{"element":Fan1,"data":{"type":"STAT","state":"1"}}}
{"element":Fan2,"data":{"type":"STAT","state":"1"}}}
{"element":Fan3,"data":{"type":"STAT","state":"1"}}}
--------------------
"00000000"
{"element":Hum1,"data":{"type":"STAT","state":"0"}}}
{"element":Hum2,"data":{"type":"STAT","state":"0"}}}
{"element":Fan5,"data":{"type":"STAT","state":"0"}}}
--------------------
"00000011"
{"element":Hum1,"data":{"type":"STAT","state":"1"}}}
{"element":Hum2,"data":{"type":"STAT","state":"1"}}}
{"element":Fan5,"data":{"type":"STAT","state":"0"}}}
--------------------
My answer assumes Bit1 in your table is the least significant bit, if that is not the case remove .reverse in the code.
You can ask me anything you want about the code.

Proper save/restore of RNG state in boost::random behaving unexpectedly

I have a small test program that attempts to save and restore the state of a random number generator using boost::random, but it is not behaving as the documentation indicates. From the boost docs:
Classes which model a pseudo-random number generator should also model the Streamable concept, i.e. implement operator<< and operator>>. If so, operator<< writes all current state of the pseudo-random number generator to the given ostream so that operator>> can restore the state at a later time. The state shall be written in a platform-independent manner, but it is assumed that the locales used for writing and reading be the same. The pseudo-random number generator with the restored state and the original at the just-written state shall be equivalent.
As I understand it, if a RNG state is saved and then a number is pulled from it, the state should change. If the state is later restored, this should allow the exact same number to be generated as the generator has been rolled back. I made a test program that examines this, but at first glance it seems like the state is not restored. Consider the code:
unsigned int s = static_cast<unsigned int>(std::time(0));
//typedef boost::minstd_rand base_generator_type;
typedef boost::mt19937 base_generator_type;
base_generator_type randgen(s);
boost::uniform_01<base_generator_type> getrand(randgen);
//boost::normal_distribution<float> noise(0,1);
//boost::variate_generator<base_generator_type,
//boost::normal_distribution<float> > getrand(randgen, noise);
double numsbefore[2], numsrightafter[2], numsnew[4];
//generate a short sequence, save it, and display
numsbefore[0] = getrand();
numsbefore[1] = getrand();
cout << "First Sequence, before save: "
<< numsbefore[0] << " "
<< numsbefore[1] << endl;
//save the current RNG state to a file using the stream interface
std::ofstream rngfileout("test_rngfile.txt");
rngfileout << randgen;
rngfileout.close();
//generate the next two numbers and display
numsrightafter[0] = getrand();
numsrightafter[1] = getrand();
cout << "Next, right after save: "
<< numsrightafter[0] << " "
<< numsrightafter[1] << endl;
//read in the RNG state that was saved, back into the RNG, restoring the state
//to be such as it was prior to the most recent two calls to randgen()
std::ifstream rngfilein("test_rngfile.txt", ifstream::in);
if(!rngfilein.good())
{
cout << "Couldn't read from file\n";
return 0;
}
rngfilein >> randgen;
rngfilein.close();
//declare and initialize a new variate generator to the newly-restored generator
boost::uniform_01<base_generator_type> getrand2(randgen);
// boost::variate_generator<base_generator_type,
// boost::normal_distribution<float> > getrand2(randgen, noise);
//copy the new variate function into the old one, to allow us to use
//the old one on the restored generator
getrand = getrand2;
//generate the next sequence
//The first two should be the same as the most recent two called
//The next two should be new random numbers
numsnew[0] = getrand();
numsnew[1] = getrand();
numsnew[2] = getrand();
numsnew[3] = getrand();
cout << "Restored, Next: "
<< numsnew[0] << " "
<< numsnew[1] << " "
<< numsnew[2] << " "
<< numsnew[3] << endl;
The output for a given time seed is:
First Sequence, before save: 0.970021 0.266862
Next, right after save: 0.110485 0.267466
Restored, Next: 0.970021 0.266862 0.110485 0.267466
The code's comments illustrate what I think should be happening. Also, some lines include commented code to do the same test with a different generator and different distribution. The same problem occurs for any of those: the next two values taken from the generator randgen after the state has been restored are not the same as the two that are generated immediately after the save, as they should be.
Upon closer inspection (debugging), it appears that calls to the variate generator getrand() do not change the state of the generator randgen at all no matter how many times I call getrand() on it, and so when I save it, it remains the same as if it were just created, and thus, when I pull from it again after restoration, it just starts from the beginning.
Shouldn't each call to the generator cause the state to advance? How am I even getting sequences that are not the same numbers if the RNG state never changes? Is the generator I'm viewing/saving not the "real" one, or something?
Also, the assignment operation of getrand = getrand2 might look sketchy but the = operator is defined for those,and replacing the last 4 calls with getrand2() doesn't make a difference.
Is the generator I'm viewing/saving not the "real" one, or something?
That is indeed the case. The uniform_01 constructor you're using actually makes a copy of the provided engine, rather than taking a reference.
If you're using Boost 1.39 or later, you can use it like this instead:
boost::uniform_01<> getrand;
getrand(randgen);
If you're stuck on an older Boost and you don't need getrand to be copyable, changing uniform_01's type parameter from base_generator_type to base_generator_type& should also work.

Is it possible to send several different datatypes at once with boost::asio without casting?

At the moment I'm filling an std::vector with all of my data and then sending it with async_write. All of the packets I send have a 2 byte header and this tells receiver how much further to read (if any further at all). The code which generates this std::vector is:
std::vector<boost::asio::const_buffer> BasePacket::buffer()
{
std::vector<boost::asio::const_buffer> buffers;
buffers.push_back(boost::asio::buffer(headerBytes_)); // This is just a boost::array<uint8_t, 2>
return buffers;
}
std::vector<boost::asio::const_buffer> UpdatePacket::buffer()
{
printf("Making an update packet into a buffer.\n");
std::vector<boost::asio::const_buffer> buffers = BasePacket::buffer();
boost::array<uint16_t, 2> test = { 30, 40 };
buffers.push_back(boost::asio::buffer(test));
return buffers;
}
This is read by:
void readHeader(const boost::system::error_code& error, size_t bytesTransferred)
{
if(error)
{
printf("Error reading header: %s\n", error.message().c_str());
return;
}
// At this point 2 bytes have been read into boost::array<uint8_t, 2> header
uint8_t primeByte = header.data()[0];
uint8_t supByte = header.data()[1];
switch(primeByte)
{
// Unrelated case removed
case PACKETHEADER::UPDATE:
// Read the first 4 bytes as two 16-bit numbers representing the size of
// the update
boost::array<uint16_t, 2> buf;
printf("Attempting to read the first two Uint16's.\n");
boost::asio::read(mySocket, boost::asio::buffer(buf));
printf("The update has size %d x %d\n", buf.data()[0], buf.data()[1]);
break;
}
// Keep listening
boost::asio::async_read(mySocket, boost::asio::buffer(header),
boost::bind(readHeader, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
The code compiles, however it doesn't return 30 x 40 as I would expect. Instead it returns
188 x 40. If I stretch the second array out only the first byte is messed up. However, if I add a third array before sending (but still read the send amount), the values of the second array all get messed up. I'm guessing that this could be related to how I'm reading it (in chunks into one buffer rather than similar to how I'm writing it).
Ideally I'd like to avoid having to cast everything into bytes and read/write that way, since it's less clear and probably less portable, but I know that's an option. However, if there is a better way I'm fine rewriting what I have.
The first problem I see is a lifetime issue with the data you are sending. asio::buffers simply wrap a data buffer that you continue to own.
The UpdatePacket::buffer() method creates a boost::array which it wraps and then pushes back on the buffers std::vector. When the method exits the boost::array goes out of scope and the asio::buffer is now pointing to garbage.
There maybe other issues, but this is a good start. Mind the lifetimes of your data buffers in Asio.

Resources