Skip to content

Commit

Permalink
Try speedup
Browse files Browse the repository at this point in the history
  • Loading branch information
bansan85 committed Nov 3, 2023
1 parent bf08f19 commit 661228b
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 27 deletions.
4 changes: 2 additions & 2 deletions NTFSLibTests/ntfsdump/ntfsdumpDlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ void CNtfsdumpDlg::OnOK()

const _TCHAR volname = m_filename.GetAt(0);

NtfsVolume<Strategy::FULL_CACHE> volume(volname);
NtfsVolume<Strategy::NO_CACHE> volume(volname);
if (!volume.IsVolumeOK())
{
MessageBox(_T("Not a valid NTFS volume or NTFS version < 3.0"));
Expand Down Expand Up @@ -325,7 +325,7 @@ void CNtfsdumpDlg::OnOK()
filebuf.resize(BUFFER_SIZE);

// only pick the unnamed stream (file data)
const AttrBase<Strategy::FULL_CACHE>* data = fr.FindStream({});
const AttrBase<Strategy::NO_CACHE>* data = fr.FindStream({});
if (data != nullptr)
{
// show only the first 16K
Expand Down
15 changes: 8 additions & 7 deletions NTFSLibTests/ntfsundel/ntfsundelDlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ void CNtfsundelDlg::OnSearch()
for (auto i = static_cast<ULONGLONG>(Enum::MftIdx::MFT);
i < volume.GetRecordsCount(); i++)
{
//if (i == 100000) break;
if (i == 500000) break;
if (stop)
{
break;
Expand Down Expand Up @@ -263,9 +263,15 @@ void CNtfsundelDlg::OnSearch()
},
nullptr);
}

files.insert(*fr.GetFileReference());
}

std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
long long duration =
std::chrono::duration_cast<std::chrono::microseconds>(end - begin)
.count();

for (auto fri : files)
{
fr.SetAttrMask(Mask::FILE_NAME);
Expand Down Expand Up @@ -321,7 +327,7 @@ void CNtfsundelDlg::OnSearch()

// Prevent showing too many entries, 50,000 maxiam
count++;
static constexpr DWORD MAX_NUMBER_FILES = 50000;
static constexpr DWORD MAX_NUMBER_FILES = 5000;
if (count >= MAX_NUMBER_FILES)
{
MessageBox(
Expand All @@ -331,11 +337,6 @@ void CNtfsundelDlg::OnSearch()
}
}

std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
long long duration =
std::chrono::duration_cast<std::chrono::microseconds>(end - begin)
.count();

CString totals;
totals.Format(_T("%lldus"), duration);
MessageBox(totals);
Expand Down
10 changes: 9 additions & 1 deletion include/ntfs-browser/file-reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <string_view>
#include <span>
#include <vector>
#include <unordered_map>

#include <ntfs-browser/strategy.h>

Expand Down Expand Up @@ -40,10 +41,17 @@ class FileReader
using HandlePtr =
std::unique_ptr<std::remove_pointer_t<HANDLE>, decltype(&::CloseHandle)>;

BYTE* NextMemory() const;

HandlePtr handle_;

// Use only for Strategy::NO_CACHE.
mutable std::vector<BYTE> buffer_;
mutable std::map<size_t, std::vector<BYTE>> map_buffer_;

// Strategy::FULL_CACHE
mutable std::unordered_map<size_t, BYTE*> map_buffer_;
mutable std::vector<std::unique_ptr<BYTE[]>> mem_alloc;
mutable size_t last_alloc = 0;
};

} // namespace NtfsBrowser
2 changes: 1 addition & 1 deletion include/ntfs-browser/file-record.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class FileRecord

virtual ~FileRecord();
friend class AttrBase<S>;
template <class TYPE_RESIDENT, Strategy S>
template <class TYPE_RESIDENT, Strategy>
friend class AttrList;

private:
Expand Down
40 changes: 27 additions & 13 deletions src/file-reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

#include "ntfs-common.h"

static constexpr LONGLONG BUFFER_SIZE = 32 * 1024;
static constexpr LONGLONG READ_BUFFER_SIZE = 64 * 1024;
static constexpr LONGLONG MEMORY_BUFFER_SIZE = 512 * READ_BUFFER_SIZE;

namespace NtfsBrowser
{
Expand Down Expand Up @@ -67,17 +68,18 @@ typename std::enable_if_t<
FileReader<T>::Read(LARGE_INTEGER& addr, DWORD length) const
{
// Not implemented. Really needed ?
assert(addr.QuadPart / BUFFER_SIZE ==
(addr.QuadPart + length - 1) / BUFFER_SIZE);
assert(addr.QuadPart / READ_BUFFER_SIZE ==
(addr.QuadPart + length - 1) / READ_BUFFER_SIZE);

size_t index = addr.QuadPart / BUFFER_SIZE;
size_t index = addr.QuadPart / READ_BUFFER_SIZE;
if (map_buffer_.contains(index))
{
return std::span<const BYTE>{
map_buffer_[index].data() + addr.QuadPart % BUFFER_SIZE, length};
&map_buffer_[index][0] + addr.QuadPart % READ_BUFFER_SIZE, length};
}

LARGE_INTEGER addr2{.QuadPart = addr.QuadPart - addr.QuadPart % BUFFER_SIZE};
LARGE_INTEGER addr2{.QuadPart =
addr.QuadPart - addr.QuadPart % READ_BUFFER_SIZE};
DWORD len = SetFilePointer(handle_.get(), static_cast<LONG>(addr2.LowPart),
&addr2.HighPart, FILE_BEGIN);

Expand All @@ -87,21 +89,33 @@ typename std::enable_if_t<
return {};
}

std::vector<BYTE> new_vector;
new_vector.reserve(BUFFER_SIZE);
BYTE* new_data = NextMemory();

if (ReadFile(handle_.get(), new_vector.data(), BUFFER_SIZE, &len, nullptr) ==
if (ReadFile(handle_.get(), &new_data[0], READ_BUFFER_SIZE, &len, nullptr) ==
FALSE ||
len != BUFFER_SIZE)
len != READ_BUFFER_SIZE)
{
NTFS_TRACE1("Cannot read file at adress %I64d\n", addr.QuadPart);
return {};
}

map_buffer_[index] = std::move(new_vector);
map_buffer_[index] = new_data;

return std::span<const BYTE>{
map_buffer_[index].data() + addr.QuadPart % BUFFER_SIZE, length};
return std::span<const BYTE>{new_data + addr.QuadPart % READ_BUFFER_SIZE,
length};
}

template <Strategy S>
BYTE* FileReader<S>::NextMemory() const
{
if (mem_alloc.empty() || last_alloc * READ_BUFFER_SIZE == MEMORY_BUFFER_SIZE)
{
last_alloc = 0;
mem_alloc.emplace_back(std::make_unique<BYTE[]>(MEMORY_BUFFER_SIZE));
}
BYTE* retval = &mem_alloc.back()[0] + last_alloc * READ_BUFFER_SIZE;
last_alloc++;
return retval;
}

template class FileReader<Strategy::NO_CACHE>;
Expand Down
5 changes: 2 additions & 3 deletions src/file-record.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,7 @@ std::optional<FileRecordHeaderImpl<S>>
return {};
}

FileRecordHeaderImpl<S> fr{buffer_file, volume_.GetSectorSize()};
return fr;
return {{buffer_file, volume_.GetSectorSize()}};
}

// Read File Record, verify and patch the US (update sequence)
Expand Down Expand Up @@ -433,7 +432,7 @@ template <Strategy S>
void FileRecord<S>::SetAttrMask(Mask mask) noexcept
{
// Standard Information and Attribute List is needed always
attr_mask_ = mask | Mask::STANDARD_INFORMATION | Mask::ATTRIBUTE_LIST;
attr_mask_ = mask;
}

// Traverse all Attribute and return CAttr_xxx classes to User Callback routine
Expand Down

0 comments on commit 661228b

Please sign in to comment.