|
| 1 | +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- |
| 2 | +//----------------------------------------------------------------------------- |
| 3 | +// Copyright 2000-2024 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 | +/* BasicGenericReader.cc (C) 2000-2024 */ |
| 9 | +/* */ |
| 10 | +/* Lecture simple pour les protections/reprises. */ |
| 11 | +/*---------------------------------------------------------------------------*/ |
| 12 | +/*---------------------------------------------------------------------------*/ |
| 13 | + |
| 14 | +#include "arcane/std/internal/BasicReader.h" |
| 15 | + |
| 16 | +#include "arcane/utils/FatalErrorException.h" |
| 17 | +#include "arcane/utils/StringBuilder.h" |
| 18 | +#include "arcane/utils/IDataCompressor.h" |
| 19 | +#include "arcane/utils/Ref.h" |
| 20 | + |
| 21 | +#include "arcane/core/IApplication.h" |
| 22 | +#include "arcane/core/IXmlDocumentHolder.h" |
| 23 | +#include "arcane/core/IIOMng.h" |
| 24 | +#include "arcane/core/IData.h" |
| 25 | +#include "arcane/core/ArcaneException.h" |
| 26 | +#include "arcane/core/ISerializedData.h" |
| 27 | +#include "arcane/core/XmlNodeList.h" |
| 28 | + |
| 29 | +#include "arcane/std/TextReader.h" |
| 30 | + |
| 31 | +/*---------------------------------------------------------------------------*/ |
| 32 | +/*---------------------------------------------------------------------------*/ |
| 33 | + |
| 34 | +namespace Arcane::impl |
| 35 | +{ |
| 36 | + |
| 37 | +/*---------------------------------------------------------------------------*/ |
| 38 | +/*---------------------------------------------------------------------------*/ |
| 39 | + |
| 40 | +BasicGenericReader:: |
| 41 | +BasicGenericReader(IApplication* app, Int32 version, Ref<KeyValueTextReader> text_reader) |
| 42 | +: TraceAccessor(app->traceMng()) |
| 43 | +, m_application(app) |
| 44 | +, m_text_reader(text_reader) |
| 45 | +, m_version(version) |
| 46 | +{ |
| 47 | +} |
| 48 | + |
| 49 | +/*---------------------------------------------------------------------------*/ |
| 50 | +/*---------------------------------------------------------------------------*/ |
| 51 | + |
| 52 | +void BasicGenericReader:: |
| 53 | +initialize(const String& path, Int32 rank) |
| 54 | +{ |
| 55 | + // Dans le cas de la version 1 ou 2, on ne peut pas créer le KeyValueTextReader |
| 56 | + // avant de lire les 'OwnMetaData' car ce sont ces dernières qui contiennent |
| 57 | + // le numéro de version. |
| 58 | + |
| 59 | + m_path = path; |
| 60 | + m_rank = rank; |
| 61 | + |
| 62 | + info(4) << "BasicGenericReader::initialize known_version=" << m_version; |
| 63 | + |
| 64 | + ScopedPtrT<IXmlDocumentHolder> xdoc; |
| 65 | + |
| 66 | + if (m_version >= 3) { |
| 67 | + if (!m_text_reader.get()) |
| 68 | + ARCANE_FATAL("Null text reader"); |
| 69 | + String dc_name; |
| 70 | + if (m_text_reader->dataCompressor().get()) |
| 71 | + dc_name = m_text_reader->dataCompressor()->name(); |
| 72 | + info(4) << "BasicGenericReader::initialize data_compressor=" << dc_name; |
| 73 | + |
| 74 | + // Si on connait déjà la version et qu'elle est supérieure ou égale à 3 |
| 75 | + // alors les informations sont dans la base de données. Dans ce cas on lit |
| 76 | + // directement les infos depuis cette base. |
| 77 | + String main_filename = BasicReaderWriterCommon::_getBasicVariableFile(m_version, m_path, rank); |
| 78 | + Int64 meta_data_size = 0; |
| 79 | + String key_name = "Global:OwnMetadata"; |
| 80 | + m_text_reader->getExtents(key_name, Int64ArrayView(1, &meta_data_size)); |
| 81 | + UniqueArray<std::byte> bytes(meta_data_size); |
| 82 | + m_text_reader->read(key_name, bytes); |
| 83 | + info(4) << "Reading own metadata rank=" << rank << " from database"; |
| 84 | + xdoc = IXmlDocumentHolder::loadFromBuffer(bytes, "OwnMetadata", traceMng()); |
| 85 | + } |
| 86 | + else { |
| 87 | + StringBuilder filename = BasicReaderWriterCommon::_getOwnMetatadaFile(m_path, m_rank); |
| 88 | + info(4) << "Reading own metadata rank=" << rank << " file=" << filename; |
| 89 | + IApplication* app = m_application; |
| 90 | + xdoc = app->ioMng()->parseXmlFile(filename); |
| 91 | + } |
| 92 | + XmlNode root = xdoc->documentNode().documentElement(); |
| 93 | + XmlNodeList variables_elem = root.children("variable-data"); |
| 94 | + String deflater_name = root.attrValue("deflater-service"); |
| 95 | + String hash_algorithm_name = root.attrValue("hash-algorithm-service"); |
| 96 | + String version_id = root.attrValue("version", false); |
| 97 | + info(4) << "Infos from metadata deflater-service=" << deflater_name |
| 98 | + << " hash-algorithm-service=" << hash_algorithm_name |
| 99 | + << " version=" << version_id; |
| 100 | + if (version_id.null() || version_id == "1") |
| 101 | + // Version 1: |
| 102 | + // - taille des dimensions sur 32 bits |
| 103 | + m_version = 1; |
| 104 | + else if (version_id == "2") |
| 105 | + // Version 2: |
| 106 | + // - taille des dimensions sur 64 bits |
| 107 | + m_version = 2; |
| 108 | + else if (version_id == "3") |
| 109 | + // Version 3: |
| 110 | + // - taille des dimensions sur 64 bits |
| 111 | + // - 1 seul fichier pour toutes les meta-données |
| 112 | + m_version = 3; |
| 113 | + else |
| 114 | + ARCANE_FATAL("Unsupported version '{0}' (max=3)", version_id); |
| 115 | + |
| 116 | + Ref<IDataCompressor> deflater; |
| 117 | + if (!deflater_name.null()) |
| 118 | + deflater = BasicReaderWriterCommon::_createDeflater(m_application, deflater_name); |
| 119 | + |
| 120 | + Ref<IHashAlgorithm> hash_algorithm; |
| 121 | + if (!hash_algorithm_name.null()) |
| 122 | + hash_algorithm = BasicReaderWriterCommon::_createHashAlgorithm(m_application, hash_algorithm_name); |
| 123 | + |
| 124 | + for (Integer i = 0, is = variables_elem.size(); i < is; ++i) { |
| 125 | + XmlNode n = variables_elem[i]; |
| 126 | + String var_full_name = n.attrValue("full-name"); |
| 127 | + Ref<VariableDataInfo> vdi = makeRef(new VariableDataInfo(var_full_name, n)); |
| 128 | + m_variables_data_info.insert(std::make_pair(var_full_name, vdi)); |
| 129 | + } |
| 130 | + |
| 131 | + if (!m_text_reader.get()) { |
| 132 | + String main_filename = BasicReaderWriterCommon::_getBasicVariableFile(m_version, m_path, rank); |
| 133 | + m_text_reader = makeRef(new KeyValueTextReader(traceMng(), main_filename, m_version)); |
| 134 | + } |
| 135 | + |
| 136 | + // Il est possible qu'il y ait déjà un algorithme de compression spécifié. |
| 137 | + // Il ne faut pas l'écraser si aucun n'est spécifié dans 'OwnMetadata'. |
| 138 | + // (Normalement cela ne devrait pas arriver sauf incohérence). |
| 139 | + if (deflater.get()) |
| 140 | + m_text_reader->setDataCompressor(deflater); |
| 141 | + if (hash_algorithm.get()) |
| 142 | + m_text_reader->setHashAlgorithm(hash_algorithm); |
| 143 | +} |
| 144 | + |
| 145 | +/*---------------------------------------------------------------------------*/ |
| 146 | +/*---------------------------------------------------------------------------*/ |
| 147 | + |
| 148 | +Ref<VariableDataInfo> BasicGenericReader:: |
| 149 | +_getVarInfo(const String& full_name) |
| 150 | +{ |
| 151 | + VariableDataInfoMap::const_iterator ivar = m_variables_data_info.find(full_name); |
| 152 | + if (ivar == m_variables_data_info.end()) |
| 153 | + ARCANE_THROW(ReaderWriterException, |
| 154 | + "Can not find own metadata infos for data var={0} rank={1}", full_name, m_rank); |
| 155 | + Ref<VariableDataInfo> vdi = ivar->second; |
| 156 | + return vdi; |
| 157 | +} |
| 158 | + |
| 159 | +/*---------------------------------------------------------------------------*/ |
| 160 | +/*---------------------------------------------------------------------------*/ |
| 161 | + |
| 162 | +void BasicGenericReader:: |
| 163 | +readData(const String& var_full_name, IData* data) |
| 164 | +{ |
| 165 | + KeyValueTextReader* reader = m_text_reader.get(); |
| 166 | + String vname = var_full_name; |
| 167 | + Ref<VariableDataInfo> vdi = _getVarInfo(vname); |
| 168 | + if (m_version < 3) |
| 169 | + reader->setFileOffset(vdi->fileOffset()); |
| 170 | + |
| 171 | + eDataType data_type = vdi->baseDataType(); |
| 172 | + Int64 memory_size = vdi->memorySize(); |
| 173 | + Integer dimension_array_size = vdi->dimensionArraySize(); |
| 174 | + Int64 nb_element = vdi->nbElement(); |
| 175 | + Integer nb_dimension = vdi->nbDimension(); |
| 176 | + Int64 nb_base_element = vdi->nbBaseElement(); |
| 177 | + bool is_multi_size = vdi->isMultiSize(); |
| 178 | + UniqueArray<Int64> extents(dimension_array_size); |
| 179 | + reader->getExtents(var_full_name, extents.view()); |
| 180 | + ArrayShape shape = vdi->shape(); |
| 181 | + |
| 182 | + Ref<ISerializedData> sd(arcaneCreateSerializedDataRef(data_type, memory_size, nb_dimension, nb_element, |
| 183 | + nb_base_element, is_multi_size, extents, shape)); |
| 184 | + |
| 185 | + Int64 storage_size = sd->memorySize(); |
| 186 | + info(4) << " READ DATA storage_size=" << storage_size << " DATA=" << data; |
| 187 | + |
| 188 | + data->allocateBufferForSerializedData(sd.get()); |
| 189 | + |
| 190 | + if (storage_size != 0) |
| 191 | + reader->read(var_full_name, asWritableBytes(sd->writableBytes())); |
| 192 | + |
| 193 | + data->assignSerializedData(sd.get()); |
| 194 | +} |
| 195 | + |
| 196 | +/*---------------------------------------------------------------------------*/ |
| 197 | +/*---------------------------------------------------------------------------*/ |
| 198 | + |
| 199 | +void BasicGenericReader:: |
| 200 | +readItemGroup(const String& group_full_name, Int64Array& written_unique_ids, |
| 201 | + Int64Array& wanted_unique_ids) |
| 202 | +{ |
| 203 | + if (m_version >= 3) { |
| 204 | + { |
| 205 | + String written_uid_name = String("GroupWrittenUid:") + group_full_name; |
| 206 | + Int64 nb_written_uid = 0; |
| 207 | + m_text_reader->getExtents(written_uid_name, Int64ArrayView(1, &nb_written_uid)); |
| 208 | + written_unique_ids.resize(nb_written_uid); |
| 209 | + m_text_reader->read(written_uid_name, asWritableBytes(written_unique_ids.span())); |
| 210 | + } |
| 211 | + { |
| 212 | + String wanted_uid_name = String("GroupWantedUid:") + group_full_name; |
| 213 | + Int64 nb_wanted_uid = 0; |
| 214 | + m_text_reader->getExtents(wanted_uid_name, Int64ArrayView(1, &nb_wanted_uid)); |
| 215 | + wanted_unique_ids.resize(nb_wanted_uid); |
| 216 | + m_text_reader->read(wanted_uid_name, asWritableBytes(wanted_unique_ids.span())); |
| 217 | + } |
| 218 | + return; |
| 219 | + } |
| 220 | + info(5) << "READ GROUP " << group_full_name; |
| 221 | + String filename = BasicReaderWriterCommon::_getBasicGroupFile(m_path, group_full_name, m_rank); |
| 222 | + TextReader reader(filename); |
| 223 | + |
| 224 | + { |
| 225 | + Integer nb_unique_id = 0; |
| 226 | + reader.readIntegers(IntegerArrayView(1, &nb_unique_id)); |
| 227 | + info(5) << "NB_WRITTEN_UNIQUE_ID = " << nb_unique_id; |
| 228 | + written_unique_ids.resize(nb_unique_id); |
| 229 | + reader.read(asWritableBytes(written_unique_ids.span())); |
| 230 | + } |
| 231 | + |
| 232 | + { |
| 233 | + Integer nb_unique_id = 0; |
| 234 | + reader.readIntegers(IntegerArrayView(1, &nb_unique_id)); |
| 235 | + info(5) << "NB_WANTED_UNIQUE_ID = " << nb_unique_id; |
| 236 | + wanted_unique_ids.resize(nb_unique_id); |
| 237 | + reader.read(asWritableBytes(wanted_unique_ids.span())); |
| 238 | + } |
| 239 | +} |
| 240 | + |
| 241 | +/*---------------------------------------------------------------------------*/ |
| 242 | +/*---------------------------------------------------------------------------*/ |
| 243 | + |
| 244 | +} // namespace Arcane::impl |
| 245 | + |
| 246 | +/*---------------------------------------------------------------------------*/ |
| 247 | +/*---------------------------------------------------------------------------*/ |
0 commit comments