Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
FileHashDatabase.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* FileHashDatabase.cc (C) 2000-2025 */
9/* */
10/* Hash database managed by the file system. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/std/internal/IHashDatabase.h"
15
16#include "arcane/utils/PlatformUtils.h"
17#include "arcane/utils/StringBuilder.h"
18#include "arcane/utils/String.h"
19#include "arcane/utils/FatalErrorException.h"
20#include "arcane/utils/TraceAccessor.h"
21
22#include <fstream>
23
24/*---------------------------------------------------------------------------*/
25/*---------------------------------------------------------------------------*/
26
27namespace Arcane
28{
29// TODO: add version information.
30// TODO: add lock for directory creation
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
51class FileHashDatabase
52: public TraceAccessor
53, public IHashDatabase
54{
55 public:
56
59 {
60 String directory;
61 String filename;
62 String full_filename;
63 };
64
65 public:
66
67 FileHashDatabase(ITraceMng* tm, const String& directory)
68 : TraceAccessor(tm)
69 , m_directory(directory)
70 {
71 }
73 {
74 info() << "FileHashDatabase: nb_write_cache=" << m_nb_write_cache
75 << " nb_write=" << m_nb_write << " nb_read=" << m_nb_read;
76 }
77
78 public:
79
80 void writeValues(const HashDatabaseWriteArgs& args, HashDatabaseWriteResult& xresult) override
81 {
82 Span<const std::byte> bytes = args.values();
83 String hash_value = args.hashValue();
84 xresult.setHashValueAsString(hash_value);
85 DirFileInfo dirfile_info = _getDirFileInfo(hash_value);
86 String base_name = dirfile_info.directory;
87 String full_filename = dirfile_info.full_filename;
88 // TODO: save the created directories in a database so as not to do it every time.
89 // TODO: use locks when creating subdirectories to prevent
90 // two processes from doing it at the same time
92 // If the hash is already saved, do nothing
93 {
94 // TODO: we should reread the value to verify that everything is OK in the database
95 // and also retrieve the file size to guarantee consistency.
96 std::ifstream ifile(full_filename.localstr(), ios::binary);
97 if (ifile.good()) {
98 ++m_nb_write_cache;
99 //std::cout << "FILE_FOUND hash=" << hash_value << " name=" << key << "\n";
100 return;
101 }
102 }
103 // TODO: Add lock for writing if multiple processes write at the same time
104 {
105 String full_filename = dirfile_info.full_filename;
106 ofstream ofile(full_filename.localstr(), ios::binary);
107 //info() << "WRITE_HASH hash=" << hash_value << " size=" << bytes.size() << " file=" << full_filename;
108 binaryWrite(ofile, bytes);
109 ++m_nb_write;
110 if (!ofile)
111 ARCANE_FATAL("Can not write hash for filename '{0}'", full_filename);
112 }
113 }
114
115 void readValues(const HashDatabaseReadArgs& args) override
116 {
117 const String& hash_value = args.hashValueAsString();
118 Span<std::byte> bytes = args.values();
119 DirFileInfo dirfile_info = _getDirFileInfo(hash_value);
120 {
121 String full_filename = dirfile_info.full_filename;
122 //info() << "READ_VALUE hash_value=" << hash_value << " name=" << args.key() << " file=" << full_filename;
123 std::ifstream ifile(full_filename.localstr(), ios::binary);
124 if (!ifile.good())
125 ARCANE_FATAL("Can not open file '{0}'", full_filename);
126 binaryRead(ifile, bytes);
127 ++m_nb_read;
128 if (!ifile.good())
129 ARCANE_FATAL("Can not read file '{0}'", full_filename);
130 }
131 }
132
133 private:
134
135 DirFileInfo _getDirFileInfo(const String& hash_value)
136 {
137 char name1 = hash_value.bytes()[0];
138 char name2 = hash_value.bytes()[1];
139 char name3 = hash_value.bytes()[2];
140 StringBuilder base_name_builder = m_directory;
141 base_name_builder += '/';
142 base_name_builder += name1;
143 base_name_builder += '/';
144 base_name_builder += name2;
145 base_name_builder += name3;
146 String base_name = base_name_builder.toString();
147 String full_filename = String::format("{0}/{1}", base_name, hash_value);
148 return DirFileInfo{ base_name, hash_value, full_filename };
149 }
150
151 private:
152
153 String m_directory;
154 Int64 m_nb_write_cache = 0;
155 Int64 m_nb_write = 0;
156 Int64 m_nb_read = 0;
157};
158
159/*---------------------------------------------------------------------------*/
160/*---------------------------------------------------------------------------*/
161
162extern "C++" Ref<IHashDatabase>
163createFileHashDatabase(ITraceMng* tm, const String& directory)
164{
165 return makeRef<IHashDatabase>(new FileHashDatabase(tm, directory));
166}
167
168/*---------------------------------------------------------------------------*/
169/*---------------------------------------------------------------------------*/
170
171} // namespace Arcane
172
173/*---------------------------------------------------------------------------*/
174/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Hash database implemented as a file system.
Reference to an instance.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage info() const
Flow for an information message.
bool recursiveCreateDirectory(const String &dir_name)
Create a directory.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::int64_t Int64
Signed integer type of 64 bits.
void binaryRead(std::istream &istr, const Span< std::byte > &bytes)
Reads the content of bytes from the stream istr in binary format.
Definition ArrayView.cc:102
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
void binaryWrite(std::ostream &ostr, const Span< const std::byte > &bytes)
Writes the content of bytes to the stream ostr in binary format.
Definition ArrayView.cc:93
Name of the directory and file containing the hash.