Skip to content

Commit

Permalink
Cleaning up checkpoint
Browse files Browse the repository at this point in the history
 - Cleaning up code
 - Fixing test/unit/util/checkpoint.cpp
 - Adding documentation for stream operators and access iterators
  • Loading branch information
aserio committed Sep 28, 2017
1 parent 18dbe31 commit 3aeb079
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 15 deletions.
46 changes: 46 additions & 0 deletions docs/manual/utilities.qbk
Expand Up @@ -75,6 +75,52 @@ below:

[check_test_2]

[h2 Writing to a File]

The core utility of [^checkpoint] is in its ability to make certain
data persistent. Often this means that the data is needed to be
stored in an object, such as a file, for later use.
For these cases we have provided two solutions: stream
operator overloads and access iterators.

We have created the two stream overleads
[^operator<<] and [^operator>>] to stream data
out of and into [^checkpoint]. You can see an
example of the overloads in use below:

[check_test_3]

This is the primary way to move data into and out of [^checkpoint]s
which expose stream operators. It is important to note, however,
a feature of these functions. Both [^operator<<] and [^operator>>]
rely on a [^.write()] and a [^.read()] funtion respectively.
In order to know how much data to read from the [^std::istream],
the [^operator<<] will write the size of the [^checkpoint] before writing
the [^checkpoint] data. Correspondingly, the [^operator>>] will
read the size of the stored data before reading
the data into new instance of [^checkpoint]. As long as the
user employs the [^operator<<] and [^operator>>]
to stream the data this detail can be ignored.
If the user tries to use another method to read or write
data to the checkpoint with either of the
overloads she should be aware of this hazardous attribute!

[important Be careful when mixing [^operator<<] and [^operator>>]
with other facilities to read and write to a [^checkpoint].
[^operator<<] writes and extra variable and
[^operator>>] reads this variable back separatly.
Used together the user will not see this and therefore can ignore
this detail. However if the user tries to read or write
using another method and then tries to stream that data
back he must take this into account!]


Users may also move the data into and out of a [^checkpoint]
using the exposed [^.begin()] and [^.end()] iterators.
An example of this usecase is illustrated below.

[check_test_4]

[endsect]

[endsect]
55 changes: 41 additions & 14 deletions hpx/util/checkpoint.hpp
Expand Up @@ -125,20 +125,6 @@ struct save_funct_obj;
{
return data.end();
}
/*
void load(std::string file_name)
{
std::ifstream ifs(file_name);
if(ifs) //Check fstream is open
{
ifs.seekg(0, ifs.end);
int length = ifs.tellg(); //Get length of file
ifs.seekg(0, ifs.beg);
data.resize(length);
ifs.read(data.data(), length);
}
}
*/
size_t size() const
{
return data.size();
Expand All @@ -147,6 +133,25 @@ struct save_funct_obj;
};

//Stream Overloads
///////////////////////////////////
/// Operator<< Overload
///
/// \param ost Output stream to write to.
///
/// \param ckp Checkpoint to copy from.
///
/// This overload is the main way to write data from a
/// checkpoint to an object such as a file. Inside
/// the function, the size of the checkpoint will
/// be written to the stream before the checkpoint's
/// data. The operator>> overload uses this to read
/// the correct number of bytes. Be mindful of this
/// additional write and read when you use different
/// facitlites to write out or read in data to a
/// checkpoint!
///
/// \returns Operator<< returns the ostream object.
///
std::ostream& operator<<(std::ostream& ost, checkpoint const& ckp)
{
// Write the size of the checkpoint to the file
Expand All @@ -156,6 +161,28 @@ struct save_funct_obj;
ost.write(ckp.data.data(), ckp.size());
return ost;
}
///////////////////////////////////
/// Operator>> Overload
///
/// \param ist Input stream to write from.
///
/// \param ckp Checkpoint to write to.
///
/// This overload is the main way to read in data from a
/// object such as a file to a checkpoint.
/// It is important to note that inside
/// the function, the first variable to be read is
/// the size of the checkpoint.
/// This size variable is written to
/// to the stream before the checkpoint's
/// data in the operator<< overload.
/// Be mindful of this
/// additional read and write when you use different
/// facitlites to read in or write out data from a
/// checkpoint!
///
/// \returns Operator>> returns the ostream object.
///
std::istream& operator>>(std::istream& ist, checkpoint& ckp)
{
// Read in the size of the next checkpoint
Expand Down
27 changes: 26 additions & 1 deletion tests/unit/util/checkpoint.cpp
Expand Up @@ -123,7 +123,8 @@ int main()

//Test 7
// test writing to a file
// test .load()
// test .begin() and .end() iterators
//[check_test_4
std::ofstream test_file_7("checkpoint_test_file.txt");
std::vector<float> vec7{1.02, 1.03, 1.04, 1.05};
hpx::future<checkpoint> fut_7=save_checkpoint(vec7);
Expand All @@ -147,6 +148,7 @@ int main()
}
checkpoint archive7_1(char_vec.data(),char_vec.size());
restore_checkpoint(archive7_1, vec7_1);
//]

HPX_TEST(vec7==vec7_1);

Expand All @@ -167,6 +169,29 @@ int main()
//Cleanup
std::remove("checkpoint_test_file.txt");

//Test 9
// test operator<< and operator>> overloads
//[check_test_3
double a9=1.0, b9=1.1, c9=1.2;
std::ofstream test_file_9("test_file_9.txt");
hpx::future<checkpoint>f_9=save_checkpoint(a9, b9, c9);
test_file_9<<f_9.get();
test_file_9.close();

double a9_1, b9_1, c9_1;
std::ifstream test_file_9_1("test_file_9.txt");
checkpoint archive9;
test_file_9_1>>archive9;
restore_checkpoint(archive9, a9_1, b9_1, c9_1);
//]

HPX_TEST(a9==a9_1);
HPX_TEST(b9==b9_1);
HPX_TEST(c9==c9_1);

//Cleanup
std::remove("test_file_9.txt");

return 0;
}

0 comments on commit 3aeb079

Please sign in to comment.