nind 2.2.1__tar.gz → 2.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. {nind-2.2.1 → nind-2.3.0}/CLAUDE.md +13 -6
  2. {nind-2.2.1 → nind-2.3.0}/CMakeLists.txt +1 -1
  3. {nind-2.2.1 → nind-2.3.0}/PKG-INFO +1 -1
  4. {nind-2.2.1 → nind-2.3.0}/pyproject.toml +2 -2
  5. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindAmose/CMakeLists.txt +3 -0
  6. nind-2.3.0/src/cpp/NindAmose/NindAmoseMerge.cpp +77 -0
  7. nind-2.3.0/src/cpp/NindAmose/NindAmoseMerge.h +58 -0
  8. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindBasics/NindFile.cpp +15 -0
  9. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindBasics/NindFile.h +6 -0
  10. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindBasics/NindPadFile.cpp +15 -1
  11. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindBasics/NindPadFile.h +4 -0
  12. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/CMakeLists.txt +3 -1
  13. nind-2.3.0/src/cpp/NindIndex/NindIndexMerge.cpp +287 -0
  14. nind-2.3.0/src/cpp/NindIndex/NindIndexMerge.h +114 -0
  15. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/NindLexiconIndex.cpp +55 -0
  16. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/NindLexiconIndex.h +21 -0
  17. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/NindLocalIndex.cpp +15 -0
  18. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/NindLocalIndex.h +5 -0
  19. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/NindTermIndex.cpp +17 -0
  20. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/NindTermIndex.h +6 -0
  21. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindLexicon/NindLexiconFile.cpp +7 -1
  22. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindPy/CMakeLists.txt +1 -0
  23. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindPy/bindings.cpp +46 -0
  24. {nind-2.2.1 → nind-2.3.0}/src/py/nind/NindFile.py +1 -1
  25. {nind-2.2.1 → nind-2.3.0}/src/py/nind/NindIndex.py +1 -1
  26. {nind-2.2.1 → nind-2.3.0}/src/py/nind/NindLexiconindex.py +1 -1
  27. {nind-2.2.1 → nind-2.3.0}/src/py/nind/NindLocalindex.py +1 -1
  28. {nind-2.2.1 → nind-2.3.0}/src/py/nind/NindPadFile.py +1 -1
  29. {nind-2.2.1 → nind-2.3.0}/src/py/nind/NindRetrolexicon.py +1 -1
  30. {nind-2.2.1 → nind-2.3.0}/src/py/nind/NindTermindex.py +1 -1
  31. {nind-2.2.1 → nind-2.3.0}/src/py/nind/Nind_dumpDocument.py +1 -1
  32. {nind-2.2.1 → nind-2.3.0}/src/py/nind/Nind_search.py +1 -1
  33. {nind-2.2.1 → nind-2.3.0}/src/py/nind/Nind_trouveMotsSansOccurrence.py +1 -1
  34. {nind-2.2.1 → nind-2.3.0}/src/py/nind/Nind_trouveNombresPremiers.py +1 -1
  35. nind-2.3.0/src/py/nind/_index_store.py +281 -0
  36. {nind-2.2.1 → nind-2.3.0}/src/py/nind/amose/NindIdentifiantsClef.py +1 -1
  37. {nind-2.2.1 → nind-2.3.0}/src/py/nind/nind_engine.py +202 -87
  38. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindAmose/CMakeLists.txt +1 -0
  39. nind-2.3.0/tst/cpp/unit/NindAmose/NindAmoseMergeTest.cpp +128 -0
  40. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindIndex/CMakeLists.txt +1 -0
  41. nind-2.3.0/tst/cpp/unit/NindIndex/NindIndexMergeTest.cpp +379 -0
  42. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindIndex/NindIndexRobustnessTest.cpp +4 -0
  43. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindIndex/NindTermIndexTest.cpp +22 -0
  44. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindLexicon/NindLexiconFileTest.cpp +11 -0
  45. {nind-2.2.1 → nind-2.3.0}/tst/py/test_native.py +68 -0
  46. nind-2.3.0/tst/py/test_nind_engine.py +382 -0
  47. {nind-2.2.1 → nind-2.3.0}/tst/py/test_nindlexiconindex.py +2 -2
  48. {nind-2.2.1 → nind-2.3.0}/tst/py/test_nindlocalindex.py +1 -1
  49. {nind-2.2.1 → nind-2.3.0}/tst/py/test_nindtermindex.py +1 -1
  50. {nind-2.2.1 → nind-2.3.0}/uv.lock +1 -1
  51. nind-2.2.1/tst/py/test_nind_engine.py +0 -142
  52. {nind-2.2.1 → nind-2.3.0}/.github/workflows/build.yml +0 -0
  53. {nind-2.2.1 → nind-2.3.0}/.github/workflows/docs.yml +0 -0
  54. {nind-2.2.1 → nind-2.3.0}/.github/workflows/publish-pypi.yml +0 -0
  55. {nind-2.2.1 → nind-2.3.0}/.gitignore +0 -0
  56. {nind-2.2.1 → nind-2.3.0}/AGENTS.md +0 -0
  57. {nind-2.2.1 → nind-2.3.0}/Dockerfile-ubuntu24.04 +0 -0
  58. {nind-2.2.1 → nind-2.3.0}/LICENCE.md +0 -0
  59. {nind-2.2.1 → nind-2.3.0}/NindConfig-version-src.cmake +0 -0
  60. {nind-2.2.1 → nind-2.3.0}/NindConfig.cmake +0 -0
  61. {nind-2.2.1 → nind-2.3.0}/README.md +0 -0
  62. {nind-2.2.1 → nind-2.3.0}/SystemSpecificInformations.cmake +0 -0
  63. {nind-2.2.1 → nind-2.3.0}/bench/README.md +0 -0
  64. {nind-2.2.1 → nind-2.3.0}/bench/index_bulk.py +0 -0
  65. {nind-2.2.1 → nind-2.3.0}/bench/lookup_latency_bench.py +0 -0
  66. {nind-2.2.1 → nind-2.3.0}/bench/msmarco/convert_to_nind.py +0 -0
  67. {nind-2.2.1 → nind-2.3.0}/bench/run_bulk_indexing_benchmark.sh +0 -0
  68. {nind-2.2.1 → nind-2.3.0}/bench/run_indexing_benchmark.sh +0 -0
  69. {nind-2.2.1 → nind-2.3.0}/cicd/extract_package.sh +0 -0
  70. {nind-2.2.1 → nind-2.3.0}/docs/api/engine.md +0 -0
  71. {nind-2.2.1 → nind-2.3.0}/docs/api/index.md +0 -0
  72. {nind-2.2.1 → nind-2.3.0}/docs/api/readers.md +0 -0
  73. {nind-2.2.1 → nind-2.3.0}/docs/architecture.md +0 -0
  74. {nind-2.2.1 → nind-2.3.0}/docs/cli.md +0 -0
  75. {nind-2.2.1 → nind-2.3.0}/docs/conf.py +0 -0
  76. {nind-2.2.1 → nind-2.3.0}/docs/index.md +0 -0
  77. {nind-2.2.1 → nind-2.3.0}/docs/quickstart.md +0 -0
  78. {nind-2.2.1 → nind-2.3.0}/docs/requirements.txt +0 -0
  79. {nind-2.2.1 → nind-2.3.0}/gbuild.sh +0 -0
  80. {nind-2.2.1 → nind-2.3.0}/src/CMakeLists.txt +0 -0
  81. {nind-2.2.1 → nind-2.3.0}/src/cpp/CMakeLists.txt +0 -0
  82. {nind-2.2.1 → nind-2.3.0}/src/cpp/Doxyfile +0 -0
  83. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindAmose/NindLexiconAmose.cpp +0 -0
  84. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindAmose/NindLexiconAmose.h +0 -0
  85. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindAmose/NindLocalAmose.cpp +0 -0
  86. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindAmose/NindLocalAmose.h +0 -0
  87. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindAmose/NindTermAmose.cpp +0 -0
  88. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindAmose/NindTermAmose.h +0 -0
  89. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindBasics/CMakeLists.txt +0 -0
  90. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindBasics/NindSignalCatcher.cpp +0 -0
  91. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindBasics/NindSignalCatcher.h +0 -0
  92. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindCommonExport.h +0 -0
  93. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindExceptions.h +0 -0
  94. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/NindIndex.cpp +0 -0
  95. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/NindIndex.h +0 -0
  96. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/NindLexiconIndexK.cpp +0 -0
  97. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/NindLexiconIndexK.h +0 -0
  98. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindLexicon/CMakeLists.txt +0 -0
  99. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindLexicon/NindLexicon.cpp +0 -0
  100. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindLexicon/NindLexicon.h +0 -0
  101. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindLexicon/NindLexiconFile.h +0 -0
  102. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindRetrolexicon/CMakeLists.txt +0 -0
  103. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindRetrolexicon/NindRetrolexicon.cpp +0 -0
  104. {nind-2.2.1 → nind-2.3.0}/src/cpp/NindRetrolexicon/NindRetrolexicon.h +0 -0
  105. {nind-2.2.1 → nind-2.3.0}/src/py/CMakeLists.txt +0 -0
  106. {nind-2.2.1 → nind-2.3.0}/src/py/Nind_checkAndRepair.py +0 -0
  107. {nind-2.2.1 → nind-2.3.0}/src/py/Nind_checkDocument.py +0 -0
  108. {nind-2.2.1 → nind-2.3.0}/src/py/Nind_checkRejtroAndLexicon.py +0 -0
  109. {nind-2.2.1 → nind-2.3.0}/src/py/nind/__init__.py +0 -0
  110. {nind-2.2.1 → nind-2.3.0}/src/py/nind/amose/CMakeLists.txt +0 -0
  111. {nind-2.2.1 → nind-2.3.0}/src/py/nind/amose/LatXmlParser.py +0 -0
  112. {nind-2.2.1 → nind-2.3.0}/src/py/nind/amose/Nind_convertitLuceneDump.py +0 -0
  113. {nind-2.2.1 → nind-2.3.0}/src/py/nind/amose/Nind_convertitSampleDump.py +0 -0
  114. {nind-2.2.1 → nind-2.3.0}/src/py/nind/amose/Nind_convertitXmlClef.py +0 -0
  115. {nind-2.2.1 → nind-2.3.0}/tst/CMakeLists.txt +0 -0
  116. {nind-2.2.1 → nind-2.3.0}/tst/cpp/CMakeLists.txt +0 -0
  117. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindAmose/CMakeLists.txt +0 -0
  118. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindAmose/NindAmose_effaceDocument.cpp +0 -0
  119. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindAmose/NindAmose_indexeCorpus.cpp +0 -0
  120. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindAmose/NindAmose_litTexteAnalysej.cpp +0 -0
  121. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindAmose/NindAmose_litTexteAnalysej.h +0 -0
  122. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindAmose/NindAmose_testLecteur.cpp +0 -0
  123. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindAmose/NindAmose_testSynchro.cpp +0 -0
  124. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindAmose/Nind_indexeCorpus.cpp +0 -0
  125. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindBasics/CMakeLists.txt +0 -0
  126. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindBasics/NindBasics_testLecture.cpp +0 -0
  127. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/CMakeLists.txt +0 -0
  128. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindDate.cpp +0 -0
  129. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindDate.h +0 -0
  130. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindFichiers.cpp +0 -0
  131. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindFichiers.h +0 -0
  132. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindIndexTest.cpp +0 -0
  133. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindIndexTest.h +0 -0
  134. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindIndex_indexe.cpp +0 -0
  135. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindIndex_indexe.h +0 -0
  136. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindIndex_litDumpS2.cpp +0 -0
  137. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindIndex_litDumpS2.h +0 -0
  138. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindIndex_testEcrivain.cpp +0 -0
  139. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindIndex_testLecteur.cpp +0 -0
  140. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindIndex_testSynchro.cpp +0 -0
  141. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindLexiconIndex_testEcrivain.cpp +0 -0
  142. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindLexiconIndex_testLecteur.cpp +0 -0
  143. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindTermIndex_testEcrivain.cpp +0 -0
  144. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindTermIndex_testLecteur.cpp +0 -0
  145. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/Nind_testLateconNumber.cpp +0 -0
  146. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/Nind_testNumbersInLocalIndexes.cpp +0 -0
  147. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindLexicon/CMakeLists.txt +0 -0
  148. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindLexicon/NindLexicon_testEcrivain.cpp +0 -0
  149. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindLexicon/NindLexicon_testInter.cpp +0 -0
  150. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindLexicon/NindLexicon_testLecteur.cpp +0 -0
  151. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindLexicon/NindLexicon_testLimites.cpp +0 -0
  152. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindLexicon/NindLexicon_testLimitesB.cpp +0 -0
  153. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindLexicon/NindLexicon_testLimitesC.cpp +0 -0
  154. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindLexicon/NindLexicon_testMemoire.cpp +0 -0
  155. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindSearch/CMakeLists.txt +0 -0
  156. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindSearch/NindGetDocTerms.cpp +0 -0
  157. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindSearch/NindSearch.cpp +0 -0
  158. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindSearch/NindSearchAmose.cpp +0 -0
  159. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindTests/CMakeLists.txt +0 -0
  160. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindTests/NindTestControlC.cpp +0 -0
  161. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindTests/Nind_test1.cpp +0 -0
  162. {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindTests/Nind_testSynchro.cpp +0 -0
  163. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/CMakeLists.txt +0 -0
  164. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindAmose/NindLexiconAmoseTest.cpp +0 -0
  165. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindAmose/NindLocalAmoseTest.cpp +0 -0
  166. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindAmose/NindTermAmoseTest.cpp +0 -0
  167. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindBasics/CMakeLists.txt +0 -0
  168. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindBasics/NindBasicsRobustnessTest.cpp +0 -0
  169. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindBasics/NindFileTest.cpp +0 -0
  170. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindBasics/NindPadFileTest.cpp +0 -0
  171. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindIndex/NindLexiconIndexTest.cpp +0 -0
  172. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindIndex/NindLocalIndexTest.cpp +0 -0
  173. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindLexicon/CMakeLists.txt +0 -0
  174. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindLexicon/NindLexiconTest.cpp +0 -0
  175. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindRetrolexicon/CMakeLists.txt +0 -0
  176. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindRetrolexicon/NindRetrolexiconTest.cpp +0 -0
  177. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/TestFileBytes.h +0 -0
  178. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/TestTempDir.h +0 -0
  179. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/doctest.h +0 -0
  180. {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/doctest_main.cpp +0 -0
  181. {nind-2.2.1 → nind-2.3.0}/tst/py/test_nindfile.py +0 -0
  182. {nind-2.2.1 → nind-2.3.0}/tst/py/test_nindretrolexicon.py +0 -0
@@ -33,7 +33,7 @@ To run tests manually instead of via the full `gbuild.sh` cycle: `ctest --output
33
33
 
34
34
  C++ unit tests live in `tst/cpp/unit/<Module>/` (one executable per library, one ctest entry each) and use **doctest**, vendored as the single header `tst/cpp/unit/doctest.h` (v2.4.12) — no system package or download needed, so they are always built. Each executable accepts doctest options, e.g. `NindIndexUnitTests -tc='NindIndexRobustness*' -s`. Corrupt/hostile-input tests live in the `*RobustnessTest.cpp` files: they patch or byte-by-byte corrupt files produced by the writers and require every read to either succeed or throw a `FileException` — run them under `-a ON` so ASan/UBSan/LSan turn any memory error, UB or leak into a failure. (`-a ON` needs the GCC sanitizer runtimes — `libasan`, `libubsan`, `liblsan` packages on RHEL-like systems.)
35
35
 
36
- Memory-safety conventions in the C++ core (keep them when touching it): readers must never trust a length/offset/count read from a file — bound it against the buffer (`NindFile::get*` check before advancing) or the real file size (`NindFile::getCurrentFileSize()`); byte assembly is done in `uint32_t`/`uint64_t` (never `int`, which overflows); chains read from files (indirection blocks, compound words) must be provably finite; `NindFile`/`NindPadFile` are non-copyable; critical sections use the RAII `NindCriticalSection`, never raw `beginCriticalSection`/`endCriticalSection`.
36
+ Memory-safety conventions in the C++ core (keep them when touching it): readers must never trust a length/offset/count read from a file — bound it against the buffer (`NindFile::get*` check before advancing) or the real file size (`NindFile::getCurrentFileSize()`); byte assembly is done in `uint32_t`/`uint64_t` (never `int`, which overflows); chains read from files (indirection blocks, compound words) must be provably finite; `NindFile`/`NindPadFile` are non-copyable; critical sections use the RAII `NindCriticalSection`, never raw `beginCriticalSection`/`endCriticalSection`; a file has at most one writer — `NindPadFile`/`NindLexiconFile` writers take a non-blocking exclusive `flock` (`NindFile::lockExclusive`, no-op on Windows) and create files with `"w+bx"` (never truncating a file another writer just created), so a second writer, even in-process, gets an exception instead of corrupting the file (readers never lock).
37
37
 
38
38
  `-DDEBUG_NIND` is added automatically in `Debug` and `RelWithDebInfo` modes (and in `Release` if configured with `-DWITH_DEBUG_MESSAGES=ON`) to enable conditional debug output.
39
39
 
@@ -80,9 +80,11 @@ NindIndex (deps: NindBasics, NindRetrolexicon)
80
80
  — NindTermIndex: the inverted file itself, as an index file
81
81
  — NindLocalIndex: per-document local index file
82
82
  — NindIndex: ties the above into a full inverted/local index file
83
+ — NindIndexMerge: offline merge of index shards (disjoint documents) into one standard index
83
84
 
84
85
  NindAmose (deps: NindIndex, NindRetrolexicon)
85
86
  — adapts nind to Amose's richer term-type model (see internal doc refs "LAT2015.JYS.448")
87
+ — NindAmoseMerge: NindIndexMerge for Amose indexes (retro lexicon, recomputed term counters)
86
88
 
87
89
  NindPy (deps: NindBasics, NindRetrolexicon, NindLexicon, NindIndex sources, compiled in directly)
88
90
  — pybind11 bindings, built only through the Python wheel (scikit-build-core), not gbuild.sh
@@ -105,7 +107,8 @@ Parallels the C++ layering with lowercase-suffixed module names for the index cl
105
107
  - `NindFile.py` — low-level binary codec. Historically read-only-oriented (the `litXxx` getters have long existed for every format), but now has a full writer counterpart too: `ejcritNombre1/3/4/5`, `ejcritNombreULat`/`ejcritNombreSLat` (both varint encodings, full tier range matching the readers and the C++ implementation), `ejcritChaine`, `ejcritZejros`.
106
108
  - `NindPadFile.py` — the shared "pad file" envelope (header, indirection block(s), specifics, identification trailer); read-only, no writer (mirrors `NindBasics::NindPadFile`, but nothing in Python subclasses it as a writer the way `NindIndex`/`NindRetrolexicon` do in C++).
107
109
  - `NindRetrolexicon.py`, `NindLexiconindex.py`, `NindTermindex.py`, `NindLocalindex.py` — ergonomic read-only Python wrappers around the corresponding `NindIndex`-family C++ classes; their hot-path lookups delegate to `nind._native`, as does the shared structural-diagnostic base (`analyseFichierPadFile`/`analyseFichierIndex`, inherited from `NindPadFile.py`/`NindIndex.py`). The remaining, per-format diagnostic/analysis methods (`dumpeFichier`, `debogueIndex`, `donneCollisions`, `donneMax`, `donneClef`, `afficheTerme`, `afficheDocument`, and each class's own `analyseFichierXxx` beyond the shared base) remain hand-rolled pure-Python parsing, since `nind._native` doesn't expose that introspection surface yet (see "Planned follow-up work" below). `NindLexiconindex` is hash-bucketed (`clefB(word) % nombreIndirection`), the other two are directly indexed by id.
108
- - `nind_engine.py` — `NindIndexer` (writer) and `NindEngine` (BM25-style search) built on top of the above. `NindIndexer` is the *only* Python writer for the index-family formats (`.nindlexiconindex`/`.nindtermindex`/`.nindlocalindex`) — it builds them via `nind._native`'s `is_writer=True` constructors. It does not write `.nindretrolexicon` (not needed by `NindEngine`, which only supports simple, non-compound words). Indexing is parallel but every file keeps a single writer: files are tokenized in worker processes (`workers` argument of `index_files`; in-process below `PARALLEL_MIN_FILES` files), then the term and local index files are written concurrently from two threads through the flat-buffer bulk bindings `NindTermIndex.set_term_defs_arrays`/`NindLocalIndex.set_local_defs_arrays`, which take `array('I')` buffers (building `Document`/`Term`/`Localisation` objects in Python cost ~20× the write itself) and release the GIL. The `*_local_def*_arrays` writers split a term's positions into entries of ≤255 (`<nbreLocalisations>` is one byte).
110
+ - `nind_engine.py` — `NindIndexer` (writer) and `NindEngine` (BM25-style search) built on top of the above. `NindIndexer` is the *only* Python writer for the index-family formats (`.nindlexiconindex`/`.nindtermindex`/`.nindlocalindex`) — it builds them via `nind._native`'s `is_writer=True` constructors. It does not write `.nindretrolexicon` (not needed by `NindEngine`, which only supports simple, non-compound words). Indexing is parallel but every file keeps a single writer: files are tokenized in worker processes (`workers` argument of `index_files`; in-process below `PARALLEL_MIN_FILES` files), then the term and local index files are written concurrently from two threads through the flat-buffer bulk bindings `NindTermIndex.set_term_defs_arrays`/`NindLocalIndex.set_local_defs_arrays`, which take `array('I')` buffers (building `Document`/`Term`/`Localisation` objects in Python cost ~20× the write itself) and release the GIL. The `*_local_def*_arrays` writers split a term's positions into entries of ≤255 (`<nbreLocalisations>` is one byte). Every build goes into a new generation directory published atomically (see `_index_store.py` below), so rebuilding never disturbs readers. With `shards=N` it instead builds N independent indexes over contiguous parts of the files in worker processes (in a temporary directory inside the new generation), then merges them with `nind._native.merge_indexes`; opt-in because the merge costs about as much as writing the index again (see "Sharded indexing" below), so it only pays off when per-document work dominates.
111
+ - `_index_store.py` — the on-disk layout that makes every `NindIndexer`/`NindEngine` operation safe without the caller doing anything: each build writes a fresh, never-modified generation directory `<prefix>.gen-<n>-<hex>/`, flushed to disk (`fsync`) then published by atomically replacing the pointer file `<prefix>.CURRENT` (a pointer file rather than a symlink: atomic on Windows too). Readers open every file of the generation `CURRENT` names under a shared `flock` on its `generation.lock` (only while opening: open files stay readable after deletion on POSIX); `NindEngine` checks `CURRENT` (one `stat`) at the start of each public call and switches to a newly published build, each call answering from one snapshot (`_Snapshot`), calls serialized by an `RLock` (the native readers aren't thread-safe). Writers of one prefix are serialized by `<prefix>.lock`; after publishing, the writer deletes older generations nobody is opening, crashed builds' leftovers, and flat files of indexes written before generations existed (still readable: no `CURRENT` = flat layout). A failed build never touches `CURRENT`. Lock fds are closed in forked children (`os.register_at_fork`) — otherwise a worker outliving a killed writer would keep the index locked forever — and `NindIndexer`'s pool workers exit when their parent dies. Windows: `msvcrt` locks are exclusive only, so readers don't lock and rely on retrying; generations still open can't be deleted and are retried at the next build.
109
112
  - `Nind_*.py` at the package root — standalone CLI scripts (dump a document, convert corpora, search, diagnostics)
110
113
  - `amose/` — Amose-specific conversion/parsing scripts (Lucene dump, XML-CLEF, sample corpora)
111
114
 
@@ -124,7 +127,11 @@ Binary file formats are specified in EBNF grammar (see README). The Python packa
124
127
 
125
128
  Not part of this: `.nindretrolexicon` writing (`NindIndexer` still doesn't write this format — unrelated, no change planned).
126
129
 
127
- **Sharded indexing (planned next, after the in-process parallelism above).** Nind files are single-writer by design (no locking, readers resync lazily; see `NindPadFile::getEntryPos`), and every write rewrites the shared specifics/identification tail at EOF, so concurrent writers on one file would serialize anyway — sharing a file between writers is explicitly *not* the plan. Instead, scale writes across N independent shards (each its own lexicon + term + local files, one single-threaded writer each, over a partition of the documents), then either:
128
- - merge offline: union the lexicons into a new one, remap every shard's term ids, concatenate posting lists with doc ids kept in increasing order (the term index stores relative doc ids), and remap term ids inside each shard's local index; or
129
- - search across shards: `NindEngine` fans out per shard, but BM25 needs corpus-wide statistics (N, df, avgdl) summed over all shards, not per-shard values.
130
- Expected cost ~1–2 weeks including tests; zero overhead on the write path.
130
+ **Sharded indexing — offline merge implemented; follow-ups below.** Nind files are single-writer by design (no locking, readers resync lazily; see `NindPadFile::getEntryPos`), and every write rewrites the shared specifics/identification tail at EOF, so concurrent writers on one file would serialize anyway — sharing a file between writers is explicitly *not* the plan. Writes scale instead across N independent shards (each its own lexicon + term + local files, one single-threaded writer each, over a partition of the documents), merged offline into one standard index that every existing reader uses unchanged (search across shards was considered and rejected: every reader, Amose's included, would have to learn about shards, and BM25 would need corpus-wide statistics summed over them).
131
+
132
+ How the merge works (`NindIndexMerge`, `src/cpp/NindIndex/`): shard lexicons are enumerated with `NindLexiconIndex::getEntries` (walks the hash buckets; no retro lexicon needed) and unioned with words canonicalised as (union id of the prefix, last component) — which also gives the exact merged size, used as the lexicon's hash modulo; documents are listed with `NindLocalIndex::getDocIdents` and checked disjoint *before anything is written*; each merged term's postings are gathered from every shard (per term, so memory stays small) and each document is copied with its term ids remapped (local term order is kept, so Amose's per-occurrence reading order survives). A failed merge removes the target files. `NindAmoseMerge` (`src/cpp/NindAmose/`) forces a retro lexicon and recomputes the 8 term counters, a term's type being derived from its components as in `NindLexiconAmose::getWord` (unique-term counts aren't additive across shards); they're written once at the end with `NindTermIndex::setSpecificWords`. The plain merge refuses shards with term specifics.
133
+
134
+ Follow-ups:
135
+ - **Merge cost is I/O-syscall bound, and so are all writes.** Merging 10k documents / 58k terms from 4 shards makes ~2.3M `lseek`, ~1.5M `read`, ~280k `write` and ~250k `rt_sigaction` calls: `NindIndex::getDefinition` discards the stdio buffer (`flush`) then seeks+reads twice (indirection, then data) on every read, `NindFile::writeBuffer` flushes every write, and every critical section installs/restores a signal handler. A direct build pays the same per definition, so a merge costs about a full rewrite. Reading with `pread` (one syscall per read, no buffer discard) and a bulk mode for a writer creating a fresh file (no per-write flush, tail written once) would speed up merges, direct builds and search alike — mind the reader-resync semantics above when touching this.
136
+ - **CLI for Amose/LIMA** multi-process indexing: a small C++ program (like the legacy `tst/cpp/NindAmose/` tools) running `NindAmoseMerge` over shard prefixes. `NindAmoseMerge` isn't bound in `nind._native` (the wheel doesn't compile `NindAmose`).
137
+ - `NindLexiconAmose::getWord` dereferences past the end of the component list for the lexicon word `§` alone (the first prefix of every named entity): undefined behaviour, seen as a `bad_alloc`. Normal lookups never ask for that id; the merge doesn't call `getWord`.
@@ -113,7 +113,7 @@ endif ()
113
113
 
114
114
  ########### setting project verion number ###############
115
115
 
116
- set(NIND_VERSION "2.2.1")
116
+ set(NIND_VERSION "2.3.0")
117
117
 
118
118
  string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+$" "\\1" NIND_VERSION_MAJOR "${NIND_VERSION}")
119
119
  string(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]+$" "\\1" NIND_VERSION_MINOR "${NIND_VERSION}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: nind
3
- Version: 2.2.1
3
+ Version: 2.3.0
4
4
  Summary: Python frontend for the Nind Indexing Module, with its native C++ index stack built in
5
5
  Requires-Python: >=3.8
6
6
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "nind"
3
- version = "2.2.1"
3
+ version = "2.3.0"
4
4
  description = "Python frontend for the Nind Indexing Module, with its native C++ index stack built in"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.8"
@@ -25,7 +25,7 @@ testpaths = ["tst/py"]
25
25
  pythonpath = ["src/py"]
26
26
 
27
27
  [tool.bumpver]
28
- current_version = "v2.2.1"
28
+ current_version = "v2.3.0"
29
29
  version_pattern = "vMAJOR.MINOR.PATCH"
30
30
  commit_message = "Bump version {old_version} -> {new_version}"
31
31
  commit = true
@@ -8,6 +8,8 @@ SET(NindAmose_LIB_SRCS
8
8
  NindTermAmose.cpp
9
9
  NindLocalAmose.h
10
10
  NindLocalAmose.cpp
11
+ NindAmoseMerge.h
12
+ NindAmoseMerge.cpp
11
13
  )
12
14
 
13
15
  add_library(NindAmose SHARED ${NindAmose_LIB_SRCS})
@@ -22,4 +24,5 @@ install(FILES
22
24
  NindTermAmose.h
23
25
  NindLocalAmose.h
24
26
  NindLexiconAmose.h
27
+ NindAmoseMerge.h
25
28
  DESTINATION include/NindAmose)
@@ -0,0 +1,77 @@
1
+ //
2
+ // C++ Implementation: NindAmoseMerge
3
+ //
4
+ // Description: Fusion hors ligne d'index Amose, voir NindAmoseMerge.h
5
+ //
6
+ // Author: Claude <noreply@anthropic.com>
7
+ //
8
+ // Copyright: 2014-2017 LATEJCON. See LICENCE.md file that comes with this distribution
9
+ // This file is part of NIND (as "nouvelle indexation").
10
+ // NIND is free software: you can redistribute it and/or modify it under the terms of the
11
+ // GNU Less General Public License (LGPL) as published by the Free Software Foundation,
12
+ // (see <http://www.gnu.org/licenses/>), either version 3 of the License, or any later version.
13
+ // NIND is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
14
+ // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ // GNU Less General Public License for more details.
16
+ ////////////////////////////////////////////////////////////
17
+ #include "NindAmoseMerge.h"
18
+ using namespace latecon::nindex;
19
+ using namespace std;
20
+ ////////////////////////////////////////////////////////////
21
+ //mesme nombre et mesme ordre que NindTermAmose
22
+ #define NOMBRE_COMPTEURS 8
23
+ ////////////////////////////////////////////////////////////
24
+ static NindIndexMerge::Options forceRetrolexicon(const NindIndexMerge::Options &options)
25
+ {
26
+ NindIndexMerge::Options result = options;
27
+ result.withRetrolexicon = true; //NindLexiconAmose a toujours un retro lexique
28
+ return result;
29
+ }
30
+ ////////////////////////////////////////////////////////////
31
+ //brief Prepare the merge of the specified shards
32
+ //param shardNames absolute path file names without extension of the shards
33
+ //param options indirection block sizes of the merged files (withRetrolexicon is forced) */
34
+ NindAmoseMerge::NindAmoseMerge(const vector<string> &shardNames,
35
+ const Options &options):
36
+ NindIndexMerge(shardNames, forceRetrolexicon(options)),
37
+ m_uniqueTermCount(4, 0),
38
+ m_termOccurrences(4, 0)
39
+ {
40
+ }
41
+ ////////////////////////////////////////////////////////////
42
+ NindAmoseMerge::~NindAmoseMerge()
43
+ {
44
+ }
45
+ ////////////////////////////////////////////////////////////
46
+ unsigned int NindAmoseMerge::getTermSpecificsNumber() const
47
+ {
48
+ return NOMBRE_COMPTEURS;
49
+ }
50
+ ////////////////////////////////////////////////////////////
51
+ //compte le terme selon son type, dejduit de ses composants comme NindLexiconAmose::getWord
52
+ void NindAmoseMerge::countTerm(const list<string> &components,
53
+ const list<NindTermIndex::TermCG> &termDef)
54
+ {
55
+ AmoseTypes type = (components.size() == 1) ? SIMPLE_TERM : MULTI_TERM;
56
+ if (!components.empty() && components.front() == "§") type = NAMED_ENTITY;
57
+ unsigned int occurrences = 0;
58
+ for (list<NindTermIndex::TermCG>::const_iterator it = termDef.begin(); it != termDef.end(); it++)
59
+ occurrences += (*it).frequency;
60
+ m_uniqueTermCount[type] += 1;
61
+ m_uniqueTermCount[ALL] += 1;
62
+ m_termOccurrences[type] += occurrences;
63
+ m_termOccurrences[ALL] += occurrences;
64
+ }
65
+ ////////////////////////////////////////////////////////////
66
+ //mesme ordre que NindTermAmose::setCountsAsList
67
+ list<unsigned int> NindAmoseMerge::getTermSpecifics() const
68
+ {
69
+ list<unsigned int> result;
70
+ const AmoseTypes types[] = {ALL, SIMPLE_TERM, MULTI_TERM, NAMED_ENTITY};
71
+ for (unsigned int i = 0; i < 4; i++) {
72
+ result.push_back(m_uniqueTermCount[types[i]]);
73
+ result.push_back(m_termOccurrences[types[i]]);
74
+ }
75
+ return result;
76
+ }
77
+ ////////////////////////////////////////////////////////////
@@ -0,0 +1,58 @@
1
+ //
2
+ // C++ Interface: NindAmoseMerge
3
+ //
4
+ // Description: Fusion hors ligne d'index Amose (voir NindIndexMerge) : le lexique fusionnej a
5
+ // toujours un retro lexique, et les compteurs du fichier inverse (termes uniques et occurrences
6
+ // par type) sont recalculejs sur l'index fusionnej, le type d'un terme ejtant dejduit de ses
7
+ // composants comme le fait NindLexiconAmose::getWord.
8
+ //
9
+ // Author: Claude <noreply@anthropic.com>
10
+ //
11
+ // Copyright: 2014-2017 LATEJCON. See LICENCE.md file that comes with this distribution
12
+ // This file is part of NIND (as "nouvelle indexation").
13
+ // NIND is free software: you can redistribute it and/or modify it under the terms of the
14
+ // GNU Less General Public License (LGPL) as published by the Free Software Foundation,
15
+ // (see <http://www.gnu.org/licenses/>), either version 3 of the License, or any later version.
16
+ // NIND is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
17
+ // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ // GNU Less General Public License for more details.
19
+ ////////////////////////////////////////////////////////////
20
+ #ifndef NindAmoseMerge_H
21
+ #define NindAmoseMerge_H
22
+ ////////////////////////////////////////////////////////////
23
+ #include "NindIndex/NindIndexMerge.h"
24
+ #include "NindLexiconAmose.h"
25
+ #include "NindCommonExport.h"
26
+ #include <string>
27
+ #include <list>
28
+ #include <vector>
29
+ ////////////////////////////////////////////////////////////
30
+ namespace latecon {
31
+ namespace nindex {
32
+ ////////////////////////////////////////////////////////////
33
+ /**\brief Merges several Amose indexes (shards over disjoint sets of documents) into one */
34
+ class DLLExportLexicon NindAmoseMerge : public NindIndexMerge {
35
+ public:
36
+ /**\brief Prepare the merge of the specified shards
37
+ *\param shardNames absolute path file names without extension of the shards
38
+ *\param options indirection block sizes of the merged files (withRetrolexicon is forced) */
39
+ NindAmoseMerge(const std::vector<std::string> &shardNames,
40
+ const Options &options = Options());
41
+
42
+ virtual ~NindAmoseMerge();
43
+
44
+ protected:
45
+ virtual unsigned int getTermSpecificsNumber() const;
46
+ virtual void countTerm(const std::list<std::string> &components,
47
+ const std::list<NindTermIndex::TermCG> &termDef);
48
+ virtual std::list<unsigned int> getTermSpecifics() const;
49
+
50
+ private:
51
+ std::vector<unsigned int> m_uniqueTermCount; //par AmoseTypes
52
+ std::vector<unsigned int> m_termOccurrences; //par AmoseTypes
53
+ };
54
+ ////////////////////////////////////////////////////////////
55
+ } // end namespace
56
+ } // end namespace
57
+ #endif
58
+ ////////////////////////////////////////////////////////////
@@ -18,6 +18,9 @@
18
18
  #include "NindFile.h"
19
19
  #include <string.h>
20
20
  #include <sys/stat.h>
21
+ #ifndef _WIN32
22
+ #include <sys/file.h>
23
+ #endif
21
24
  //#include <iostream>
22
25
  using namespace latecon::nindex;
23
26
  using namespace std;
@@ -124,6 +127,18 @@ bool NindFile::open(const string &accessMode)
124
127
  return true;
125
128
  }
126
129
  ////////////////////////////////////////////////////////////
130
+ //brief Take an advisory exclusive lock on the open file, without waiting
131
+ //return true if the lock was taken, false if another open of the file holds it */
132
+ bool NindFile::lockExclusive()
133
+ {
134
+ #ifdef _WIN32
135
+ return true;
136
+ #else
137
+ //flock est par description de fichier ouvert : refuse aussi un 2e ejcrivain du mesme processus
138
+ return flock(fileno(m_file), LOCK_EX | LOCK_NB) == 0;
139
+ #endif
140
+ }
141
+ ////////////////////////////////////////////////////////////
127
142
  //brief Close file associated with. Success in any case. */
128
143
  void NindFile::close()
129
144
  {
@@ -46,6 +46,12 @@ public:
46
46
  *\return true if success, false otherwise */
47
47
  bool open(const std::string &accessMode);
48
48
 
49
+ /**\brief Take an advisory exclusive lock on the open file, without waiting: a second
50
+ * writer on the same file (in any process) is refused instead of silently corrupting it.
51
+ * The lock is released when the file is closed. No-op (always true) on Windows.
52
+ *\return true if the lock was taken, false if another open of the file holds it */
53
+ bool lockExclusive();
54
+
49
55
  /**\brief Close file associated with. Success in any case. */
50
56
  void close();
51
57
 
@@ -84,6 +84,9 @@ NindPadFile::NindPadFile(const string &fileName,
84
84
  if (m_isWriter) {
85
85
  //si fichier ejcrivain, ouvre en ecriture + lecture
86
86
  bool isOpened = m_file.open("r+b");
87
+ //un seul ejcrivain par fichier : un 2e (de ce processus ou d'un autre) est refusej
88
+ if (isOpened && !m_file.lockExclusive())
89
+ throw NindPadFileException("NindPadFile::NindPadFile already opened by another writer " + m_fileName);
87
90
  if (isOpened) {
88
91
  //si le fichier existe, l'analyse pour trouver le mapping des blocs et l'identification
89
92
  //lit la taille d'une donneje indexeje at la taille des spejcifiques
@@ -112,8 +115,12 @@ NindPadFile::NindPadFile(const string &fileName,
112
115
  //la taille du bloc de dejfinitions doit estre spejcifieje diffejrente de 0
113
116
  if (dataEntriesBlocSize == 0)
114
117
  throw NindPadFileException("NindPadFile::NindPadFile null dataEntriesBlocSize " + m_fileName);
115
- isOpened = m_file.open("w+b");
118
+ //crejation exclusive ("x") : un autre ejcrivain qui crejerait le mesme fichier au mesme
119
+ //moment n'est pas tronquej, c'est cette ouverture-ci qui ejchoue
120
+ isOpened = m_file.open("w+bx");
116
121
  if (!isOpened) throw OpenFileException("NindPadFile::NindPadFile open error " + m_fileName);
122
+ if (!m_file.lockExclusive())
123
+ throw NindPadFileException("NindPadFile::NindPadFile already opened by another writer " + m_fileName);
117
124
  //taille d'une donneje indexeje et taille des spejcifiques en teste de fichier
118
125
  m_file.createBuffer(TAILLE_ENTETE_FIXE);
119
126
  m_file.putInt1(m_dataEntrySize);
@@ -267,6 +274,13 @@ string NindPadFile::getFileName()
267
274
  return m_fileName;
268
275
  }
269
276
  ////////////////////////////////////////////////////////////
277
+ //brief get size of specific datas, as read from the file (or given to a neo writer)
278
+ //return size in bytes of specific datas */
279
+ unsigned int NindPadFile::getSpecificsSize() const
280
+ {
281
+ return m_specificsSize;
282
+ }
283
+ ////////////////////////////////////////////////////////////
270
284
  //brief write specifics header into write buffer */
271
285
  void NindPadFile::writeSpecificsHeader()
272
286
  {
@@ -169,6 +169,10 @@ public:
169
169
  /**\brief get file name
170
170
  * \return file name */
171
171
  std::string getFileName();
172
+
173
+ /**\brief get size of specific datas, as read from the file (or given to a neo writer)
174
+ * \return size in bytes of specific datas */
175
+ unsigned int getSpecificsSize() const;
172
176
  NindFile m_file; //pour l'ecrivain ou le lecteur
173
177
 
174
178
  protected:
@@ -11,6 +11,8 @@ SET(NindIndex_LIB_SRCS
11
11
  NindTermIndex.cpp
12
12
  NindLocalIndex.h
13
13
  NindLocalIndex.cpp
14
+ NindIndexMerge.h
15
+ NindIndexMerge.cpp
14
16
  )
15
17
 
16
18
  add_library(NindIndex SHARED ${NindIndex_LIB_SRCS})
@@ -21,4 +23,4 @@ set_target_properties(NindIndex PROPERTIES VERSION ${NIND_LIB_VERSION} SOVERSION
21
23
  install(TARGETS NindIndex DESTINATION lib)
22
24
 
23
25
  ########### install files ###############
24
- install(FILES NindIndex.h NindLexiconIndex.h NindTermIndex.h NindLocalIndex.h DESTINATION include/NindIndex)
26
+ install(FILES NindIndex.h NindLexiconIndex.h NindTermIndex.h NindLocalIndex.h NindIndexMerge.h DESTINATION include/NindIndex)