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.
- {nind-2.2.1 → nind-2.3.0}/CLAUDE.md +13 -6
- {nind-2.2.1 → nind-2.3.0}/CMakeLists.txt +1 -1
- {nind-2.2.1 → nind-2.3.0}/PKG-INFO +1 -1
- {nind-2.2.1 → nind-2.3.0}/pyproject.toml +2 -2
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindAmose/CMakeLists.txt +3 -0
- nind-2.3.0/src/cpp/NindAmose/NindAmoseMerge.cpp +77 -0
- nind-2.3.0/src/cpp/NindAmose/NindAmoseMerge.h +58 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindBasics/NindFile.cpp +15 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindBasics/NindFile.h +6 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindBasics/NindPadFile.cpp +15 -1
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindBasics/NindPadFile.h +4 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/CMakeLists.txt +3 -1
- nind-2.3.0/src/cpp/NindIndex/NindIndexMerge.cpp +287 -0
- nind-2.3.0/src/cpp/NindIndex/NindIndexMerge.h +114 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/NindLexiconIndex.cpp +55 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/NindLexiconIndex.h +21 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/NindLocalIndex.cpp +15 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/NindLocalIndex.h +5 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/NindTermIndex.cpp +17 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/NindTermIndex.h +6 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindLexicon/NindLexiconFile.cpp +7 -1
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindPy/CMakeLists.txt +1 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindPy/bindings.cpp +46 -0
- {nind-2.2.1 → nind-2.3.0}/src/py/nind/NindFile.py +1 -1
- {nind-2.2.1 → nind-2.3.0}/src/py/nind/NindIndex.py +1 -1
- {nind-2.2.1 → nind-2.3.0}/src/py/nind/NindLexiconindex.py +1 -1
- {nind-2.2.1 → nind-2.3.0}/src/py/nind/NindLocalindex.py +1 -1
- {nind-2.2.1 → nind-2.3.0}/src/py/nind/NindPadFile.py +1 -1
- {nind-2.2.1 → nind-2.3.0}/src/py/nind/NindRetrolexicon.py +1 -1
- {nind-2.2.1 → nind-2.3.0}/src/py/nind/NindTermindex.py +1 -1
- {nind-2.2.1 → nind-2.3.0}/src/py/nind/Nind_dumpDocument.py +1 -1
- {nind-2.2.1 → nind-2.3.0}/src/py/nind/Nind_search.py +1 -1
- {nind-2.2.1 → nind-2.3.0}/src/py/nind/Nind_trouveMotsSansOccurrence.py +1 -1
- {nind-2.2.1 → nind-2.3.0}/src/py/nind/Nind_trouveNombresPremiers.py +1 -1
- nind-2.3.0/src/py/nind/_index_store.py +281 -0
- {nind-2.2.1 → nind-2.3.0}/src/py/nind/amose/NindIdentifiantsClef.py +1 -1
- {nind-2.2.1 → nind-2.3.0}/src/py/nind/nind_engine.py +202 -87
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindAmose/CMakeLists.txt +1 -0
- nind-2.3.0/tst/cpp/unit/NindAmose/NindAmoseMergeTest.cpp +128 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindIndex/CMakeLists.txt +1 -0
- nind-2.3.0/tst/cpp/unit/NindIndex/NindIndexMergeTest.cpp +379 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindIndex/NindIndexRobustnessTest.cpp +4 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindIndex/NindTermIndexTest.cpp +22 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindLexicon/NindLexiconFileTest.cpp +11 -0
- {nind-2.2.1 → nind-2.3.0}/tst/py/test_native.py +68 -0
- nind-2.3.0/tst/py/test_nind_engine.py +382 -0
- {nind-2.2.1 → nind-2.3.0}/tst/py/test_nindlexiconindex.py +2 -2
- {nind-2.2.1 → nind-2.3.0}/tst/py/test_nindlocalindex.py +1 -1
- {nind-2.2.1 → nind-2.3.0}/tst/py/test_nindtermindex.py +1 -1
- {nind-2.2.1 → nind-2.3.0}/uv.lock +1 -1
- nind-2.2.1/tst/py/test_nind_engine.py +0 -142
- {nind-2.2.1 → nind-2.3.0}/.github/workflows/build.yml +0 -0
- {nind-2.2.1 → nind-2.3.0}/.github/workflows/docs.yml +0 -0
- {nind-2.2.1 → nind-2.3.0}/.github/workflows/publish-pypi.yml +0 -0
- {nind-2.2.1 → nind-2.3.0}/.gitignore +0 -0
- {nind-2.2.1 → nind-2.3.0}/AGENTS.md +0 -0
- {nind-2.2.1 → nind-2.3.0}/Dockerfile-ubuntu24.04 +0 -0
- {nind-2.2.1 → nind-2.3.0}/LICENCE.md +0 -0
- {nind-2.2.1 → nind-2.3.0}/NindConfig-version-src.cmake +0 -0
- {nind-2.2.1 → nind-2.3.0}/NindConfig.cmake +0 -0
- {nind-2.2.1 → nind-2.3.0}/README.md +0 -0
- {nind-2.2.1 → nind-2.3.0}/SystemSpecificInformations.cmake +0 -0
- {nind-2.2.1 → nind-2.3.0}/bench/README.md +0 -0
- {nind-2.2.1 → nind-2.3.0}/bench/index_bulk.py +0 -0
- {nind-2.2.1 → nind-2.3.0}/bench/lookup_latency_bench.py +0 -0
- {nind-2.2.1 → nind-2.3.0}/bench/msmarco/convert_to_nind.py +0 -0
- {nind-2.2.1 → nind-2.3.0}/bench/run_bulk_indexing_benchmark.sh +0 -0
- {nind-2.2.1 → nind-2.3.0}/bench/run_indexing_benchmark.sh +0 -0
- {nind-2.2.1 → nind-2.3.0}/cicd/extract_package.sh +0 -0
- {nind-2.2.1 → nind-2.3.0}/docs/api/engine.md +0 -0
- {nind-2.2.1 → nind-2.3.0}/docs/api/index.md +0 -0
- {nind-2.2.1 → nind-2.3.0}/docs/api/readers.md +0 -0
- {nind-2.2.1 → nind-2.3.0}/docs/architecture.md +0 -0
- {nind-2.2.1 → nind-2.3.0}/docs/cli.md +0 -0
- {nind-2.2.1 → nind-2.3.0}/docs/conf.py +0 -0
- {nind-2.2.1 → nind-2.3.0}/docs/index.md +0 -0
- {nind-2.2.1 → nind-2.3.0}/docs/quickstart.md +0 -0
- {nind-2.2.1 → nind-2.3.0}/docs/requirements.txt +0 -0
- {nind-2.2.1 → nind-2.3.0}/gbuild.sh +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/CMakeLists.txt +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/CMakeLists.txt +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/Doxyfile +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindAmose/NindLexiconAmose.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindAmose/NindLexiconAmose.h +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindAmose/NindLocalAmose.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindAmose/NindLocalAmose.h +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindAmose/NindTermAmose.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindAmose/NindTermAmose.h +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindBasics/CMakeLists.txt +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindBasics/NindSignalCatcher.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindBasics/NindSignalCatcher.h +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindCommonExport.h +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindExceptions.h +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/NindIndex.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/NindIndex.h +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/NindLexiconIndexK.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindIndex/NindLexiconIndexK.h +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindLexicon/CMakeLists.txt +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindLexicon/NindLexicon.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindLexicon/NindLexicon.h +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindLexicon/NindLexiconFile.h +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindRetrolexicon/CMakeLists.txt +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindRetrolexicon/NindRetrolexicon.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/cpp/NindRetrolexicon/NindRetrolexicon.h +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/py/CMakeLists.txt +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/py/Nind_checkAndRepair.py +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/py/Nind_checkDocument.py +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/py/Nind_checkRejtroAndLexicon.py +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/py/nind/__init__.py +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/py/nind/amose/CMakeLists.txt +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/py/nind/amose/LatXmlParser.py +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/py/nind/amose/Nind_convertitLuceneDump.py +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/py/nind/amose/Nind_convertitSampleDump.py +0 -0
- {nind-2.2.1 → nind-2.3.0}/src/py/nind/amose/Nind_convertitXmlClef.py +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/CMakeLists.txt +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/CMakeLists.txt +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindAmose/CMakeLists.txt +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindAmose/NindAmose_effaceDocument.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindAmose/NindAmose_indexeCorpus.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindAmose/NindAmose_litTexteAnalysej.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindAmose/NindAmose_litTexteAnalysej.h +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindAmose/NindAmose_testLecteur.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindAmose/NindAmose_testSynchro.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindAmose/Nind_indexeCorpus.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindBasics/CMakeLists.txt +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindBasics/NindBasics_testLecture.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/CMakeLists.txt +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindDate.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindDate.h +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindFichiers.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindFichiers.h +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindIndexTest.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindIndexTest.h +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindIndex_indexe.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindIndex_indexe.h +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindIndex_litDumpS2.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindIndex_litDumpS2.h +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindIndex_testEcrivain.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindIndex_testLecteur.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindIndex_testSynchro.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindLexiconIndex_testEcrivain.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindLexiconIndex_testLecteur.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindTermIndex_testEcrivain.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/NindTermIndex_testLecteur.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/Nind_testLateconNumber.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindIndex/Nind_testNumbersInLocalIndexes.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindLexicon/CMakeLists.txt +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindLexicon/NindLexicon_testEcrivain.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindLexicon/NindLexicon_testInter.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindLexicon/NindLexicon_testLecteur.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindLexicon/NindLexicon_testLimites.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindLexicon/NindLexicon_testLimitesB.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindLexicon/NindLexicon_testLimitesC.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindLexicon/NindLexicon_testMemoire.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindSearch/CMakeLists.txt +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindSearch/NindGetDocTerms.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindSearch/NindSearch.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindSearch/NindSearchAmose.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindTests/CMakeLists.txt +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindTests/NindTestControlC.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindTests/Nind_test1.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/NindTests/Nind_testSynchro.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/CMakeLists.txt +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindAmose/NindLexiconAmoseTest.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindAmose/NindLocalAmoseTest.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindAmose/NindTermAmoseTest.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindBasics/CMakeLists.txt +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindBasics/NindBasicsRobustnessTest.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindBasics/NindFileTest.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindBasics/NindPadFileTest.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindIndex/NindLexiconIndexTest.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindIndex/NindLocalIndexTest.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindLexicon/CMakeLists.txt +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindLexicon/NindLexiconTest.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindRetrolexicon/CMakeLists.txt +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/NindRetrolexicon/NindRetrolexiconTest.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/TestFileBytes.h +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/TestTempDir.h +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/doctest.h +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/cpp/unit/doctest_main.cpp +0 -0
- {nind-2.2.1 → nind-2.3.0}/tst/py/test_nindfile.py +0 -0
- {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
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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.
|
|
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
|
[project]
|
|
2
2
|
name = "nind"
|
|
3
|
-
version = "2.
|
|
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.
|
|
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
|
-
|
|
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)
|