From 060e1a8efb01b992b98ab6d6aa91f31553b636de Mon Sep 17 00:00:00 2001 From: Brett Date: Sun, 29 Jan 2023 17:10:36 -0500 Subject: [PATCH] Tables now have names --- include/blt/std/format.h | 7 ++- src/blt/nbt/nbt.cpp | 9 +-- src/blt/profiling/profiler.cpp | 4 +- src/blt/std/format.cpp | 31 ++++++++-- src/tests/nbt_tests.h | 101 ++++++++++++++++++++++++++------- 5 files changed, 118 insertions(+), 34 deletions(-) diff --git a/include/blt/std/format.h b/include/blt/std/format.h index 24b2e55..e154db5 100644 --- a/include/blt/std/format.h +++ b/include/blt/std/format.h @@ -174,12 +174,13 @@ namespace blt::string { class TableFormatter { private: + std::string m_tableName; int m_columnPadding; int m_maxColumnWidth; std::vector columns; std::vector rows; - static std::string generateTopSeparator(size_t size); + std::string generateTopSeparator(size_t size); std::string generateColumnHeader(); @@ -192,8 +193,8 @@ namespace blt::string { } public: - explicit TableFormatter(int columnPadding = 2, int maxColumnWidth = 500): - m_columnPadding(columnPadding), m_maxColumnWidth(maxColumnWidth) {} + explicit TableFormatter(std::string tableName = "", int columnPadding = 2, int maxColumnWidth = 500): + m_tableName(std::move(tableName)), m_columnPadding(columnPadding), m_maxColumnWidth(maxColumnWidth) {} inline void addColumn(const TableColumn& column) { columns.push_back(column); diff --git a/src/blt/nbt/nbt.cpp b/src/blt/nbt/nbt.cpp index fa727b8..7342778 100644 --- a/src/blt/nbt/nbt.cpp +++ b/src/blt/nbt/nbt.cpp @@ -33,15 +33,16 @@ namespace blt::nbt { if (readIndex == 0) m_stream.read(m_buffer, (long) m_bufferSize); if (readIndex + bytes >= m_bufferSize) { + // copy out all the data from the current buffer auto bytesLeft = m_bufferSize - readIndex; memcpy(buffer, m_buffer + readIndex, bytesLeft); readIndex = 0; bytes -= bytesLeft; - readBytes(buffer + bytesLeft, bytes); -// m_stream.read(m_buffer, (long) m_bufferSize); -// memcpy(buffer + bytesLeft, m_buffer, bytes); -// readIndex += bytes; + // now to prevent large scale reading in small blocks, we should just read the entire thing into the buffer. + m_stream.read(buffer + bytesLeft, (long) bytes); } else { + // but in the case that the size of the data read is small, we should read in blocks and copy from that buffer + // that should be quicker since file operations are slow. std::memcpy(buffer, m_buffer + readIndex, bytes); readIndex += bytes; } diff --git a/src/blt/profiling/profiler.cpp b/src/blt/profiling/profiler.cpp index ca5b039..cf220b9 100644 --- a/src/blt/profiling/profiler.cpp +++ b/src/blt/profiling/profiler.cpp @@ -58,7 +58,7 @@ namespace blt::profiling { } void printProfile(const std::string& profileName, int loggingLevel) { - string::TableFormatter formatter; + string::TableFormatter formatter {profileName}; formatter.addColumn({"Interval"}); formatter.addColumn({"Time (ns)"}); formatter.addColumn({"Time (ms)"}); @@ -105,7 +105,7 @@ namespace blt::profiling { std::sort(unorderedIntervalVector.begin(), unorderedIntervalVector.end(), timeCompare); - string::TableFormatter formatter; + string::TableFormatter formatter {profileName}; formatter.addColumn({"Order"}); formatter.addColumn({"Interval"}); formatter.addColumn({"Time (ns)"}); diff --git a/src/blt/std/format.cpp b/src/blt/std/format.cpp index ab19072..94d1c2b 100644 --- a/src/blt/std/format.cpp +++ b/src/blt/std/format.cpp @@ -68,10 +68,33 @@ std::string blt::string::TableFormatter::generateColumnHeader() { } std::string blt::string::TableFormatter::generateTopSeparator(size_t size) { - std::string wholeWidthSeparator; - for (int i = 0; i < size; i++) - wholeWidthSeparator += "-"; - return wholeWidthSeparator; + auto sizeOfName = m_tableName.empty() ? 0 : m_tableName.size() + 4; + auto sizeNameRemoved = size - sizeOfName; + + std::string halfWidthLeftSeparator; + std::string halfWidthRightSeparator; + + auto sizeNameFloor = (size_t) std::floor((double)sizeNameRemoved/2.0); + auto sizeNameCeil = (size_t) std::ceil((double)sizeNameRemoved/2.0); + + halfWidthLeftSeparator.reserve(sizeNameCeil); + halfWidthRightSeparator.reserve(sizeNameFloor); + + for (int i = 0; i < sizeNameFloor; i++) + halfWidthLeftSeparator += "-"; + + for (int i = 0; i < sizeNameCeil; i++) + halfWidthRightSeparator += "-"; + + std::string separator; + separator += halfWidthLeftSeparator; + if (sizeOfName != 0) { + separator += "{ "; + separator += m_tableName; + separator += " }"; + } + separator += halfWidthRightSeparator; + return separator; } std::string blt::string::TableFormatter::generateSeparator(size_t size) { diff --git a/src/tests/nbt_tests.h b/src/tests/nbt_tests.h index f8b0546..4d0daa8 100644 --- a/src/tests/nbt_tests.h +++ b/src/tests/nbt_tests.h @@ -12,6 +12,33 @@ #include #include +struct nbt_scoped_buffer { + char* buffer; + size_t bufferSize; + explicit nbt_scoped_buffer(size_t bufferSize): bufferSize(bufferSize) { + buffer = new char[bufferSize]; + } + ~nbt_scoped_buffer(){ + delete[] buffer; + } + inline char operator[](size_t index) const { + return buffer[index]; + } +}; + +inline bool readLargeBlockUsingNBTBufferedReader(const std::string& file, const nbt_scoped_buffer& bufferToCompare, size_t bufferSize) { + nbt_scoped_buffer read_buffer{bufferToCompare.bufferSize}; + std::fstream largeBlockInputLarge(file, std::ios::in | std::ios::binary); + blt::nbt::NBTByteFStreamReader byteLargeBlockInputLarge(largeBlockInputLarge, bufferSize); + byteLargeBlockInputLarge.readBytes(read_buffer.buffer, bufferToCompare.bufferSize); + for (int i = 0; i < bufferToCompare.bufferSize; i++) { + if (read_buffer[i] != bufferToCompare.buffer[i]) + return false; + } + largeBlockInputLarge.close(); + return true; +} + inline void nbt_tests(){ std::fstream testOutput("Hello.txt", std::ios::out | std::ios::binary); @@ -43,52 +70,84 @@ inline void nbt_tests(){ BLT_INFO("%d, %c, %d, %d, %d, %s", testByteIn[0], testByteIn[1], testByteIn[2], testShortIn, testIntIn, strIn.c_str()); - auto bufferSize = 1024 * 1024; - char* buffer = new char[bufferSize]; + constexpr auto bufferSize = 1024 * 128; + + nbt_scoped_buffer buffer{bufferSize}; + char* read_buffer = new char[bufferSize]; char* read_block_buffer = new char[bufferSize]; + bool fstream_indv_correct = true; + bool fstream_large_correct = true; + bool nbt_block_indv_correct = true; + for (int i = 0; i < bufferSize; i++) - buffer[i] = i+1; + buffer.buffer[i] = i+1; BLT_START_INTERVAL("nbt", "Raw Write"); std::fstream largeOutput("HeyThere.txt", std::ios::out | std::ios::binary); - largeOutput.write(buffer, bufferSize); + largeOutput.write(buffer.buffer, bufferSize); largeOutput.flush(); largeOutput.close(); BLT_END_INTERVAL("nbt", "Raw Write"); - BLT_START_INTERVAL("nbt", "Raw Read"); + BLT_START_INTERVAL("nbt", "Raw Read Individual"); std::fstream largeInput("HeyThere.txt", std::ios::in | std::ios::binary); - largeInput.read(read_buffer, bufferSize); + for (int i = 0; i < bufferSize; i++) { + char byte; + largeInput.read(&byte, 1); + if (byte != buffer[i]) { + fstream_indv_correct = false; + break; + } + } largeInput.close(); - BLT_END_INTERVAL("nbt", "Raw Read"); + BLT_END_INTERVAL("nbt", "Raw Read Individual"); - BLT_START_INTERVAL("nbt", "Block Read"); + BLT_START_INTERVAL("nbt", "Block Read Individual"); std::fstream largeBlockInput("HeyThere.txt", std::ios::in | std::ios::binary); - blt::nbt::NBTByteFStreamReader byteLargeBlockInput(largeBlockInput, 1024 * 128); - byteLargeBlockInput.readBytes(read_block_buffer, bufferSize); + blt::nbt::NBTByteFStreamReader byteLargeBlockInput(largeBlockInput, 1024 * 8); + for (int i = 0; i < bufferSize; i++) { + char byte; + byteLargeBlockInput.readBytes(&byte, 1); + if (byte != buffer[i]) { + nbt_block_indv_correct = false; + break; + } + } largeBlockInput.close(); - BLT_END_INTERVAL("nbt", "Block Read"); + BLT_END_INTERVAL("nbt", "Block Read Individual"); - bool fstream_in_correct = true; - bool nbt_block_in_correct = true; + BLT_START_INTERVAL("nbt", "Raw Read Large"); + std::fstream largeInputLarge("HeyThere.txt", std::ios::in | std::ios::binary); + largeInputLarge.read(read_buffer, bufferSize); for (int i = 0; i < bufferSize; i++) { if (read_buffer[i] != buffer[i]) - fstream_in_correct = false; - if (read_block_buffer[i] != buffer[i]) - nbt_block_in_correct = false; - if (!fstream_in_correct && !nbt_block_in_correct) - break; + fstream_large_correct = false; + } + largeInputLarge.close(); + BLT_END_INTERVAL("nbt", "Raw Read Large"); + + BLT_INFO("FStream Read Correctly? %s;", fstream_indv_correct ? "True" : "False"); + BLT_INFO("FStream Large Read Correctly? %s;", fstream_large_correct ? "True" : "False"); + BLT_INFO("NBT Block Stream Correctly? %s;\n", nbt_block_indv_correct ? "True" : "False"); + + for (int i = 0; i < 8; i++) { + auto size = (size_t) std::pow(2, 11 + i); + auto size_str = std::to_string(size); + auto profiler_string = "Block Read " + size_str; + bool nbt_block_large_correct = true; + BLT_START_INTERVAL("nbt", profiler_string); + nbt_block_large_correct = readLargeBlockUsingNBTBufferedReader("HeyThere.txt", buffer, size); + BLT_END_INTERVAL("nbt", profiler_string); + + BLT_INFO("NBT Block %s Stream Correctly? %s;\n", size_str.c_str(), nbt_block_large_correct ? "True" : "False"); } - BLT_INFO("FStream Read Correctly? %s;", fstream_in_correct ? "True" : "False"); - BLT_INFO("NBT Block Stream Correctly? %s;\n", nbt_block_in_correct ? "True" : "False"); BLT_PRINT_ORDERED("nbt"); delete[] read_buffer; delete[] read_block_buffer; - delete[] buffer; }