diff --git a/src/main/java/it/cavallium/dbengine/client/DatabaseOptions.java b/src/main/java/it/cavallium/dbengine/client/DatabaseOptions.java index d97c072..bdc2657 100644 --- a/src/main/java/it/cavallium/dbengine/client/DatabaseOptions.java +++ b/src/main/java/it/cavallium/dbengine/client/DatabaseOptions.java @@ -9,4 +9,5 @@ import org.jetbrains.annotations.Nullable; public record DatabaseOptions(List volumes, Map extraFlags, boolean absoluteConsistency, boolean lowMemory, boolean inMemory, boolean useDirectIO, boolean allowMemoryMapping, boolean allowNettyDirect, boolean optimistic, int maxOpenFiles, - @Nullable Long memtableMemoryBudgetBytes) {} + @Nullable Number memtableMemoryBudgetBytes, @Nullable Number blockCache, + @Nullable Boolean setCacheIndexAndFilterBlocks) {} diff --git a/src/main/java/it/cavallium/dbengine/database/disk/LLLocalKeyValueDatabase.java b/src/main/java/it/cavallium/dbengine/database/disk/LLLocalKeyValueDatabase.java index 6f9e72e..2692369 100644 --- a/src/main/java/it/cavallium/dbengine/database/disk/LLLocalKeyValueDatabase.java +++ b/src/main/java/it/cavallium/dbengine/database/disk/LLLocalKeyValueDatabase.java @@ -2,6 +2,7 @@ package it.cavallium.dbengine.database.disk; import static io.net5.buffer.api.StandardAllocationTypes.OFF_HEAP; import static it.cavallium.dbengine.database.LLUtils.MARKER_ROCKSDB; +import static java.util.Objects.requireNonNullElse; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Timer; @@ -39,12 +40,14 @@ import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.Nullable; import org.rocksdb.BlockBasedTableConfig; import org.rocksdb.BloomFilter; +import org.rocksdb.Cache; import org.rocksdb.ClockCache; import org.rocksdb.ColumnFamilyDescriptor; import org.rocksdb.ColumnFamilyHandle; import org.rocksdb.CompactRangeOptions; import org.rocksdb.CompactionPriority; import org.rocksdb.CompactionStyle; +import org.rocksdb.CompressionOptions; import org.rocksdb.CompressionType; import org.rocksdb.DBOptions; import org.rocksdb.DbPath; @@ -60,6 +63,7 @@ import org.rocksdb.TransactionDBOptions; import org.rocksdb.TxnDBWritePolicy; import org.rocksdb.WALRecoveryMode; import org.rocksdb.WriteBufferManager; +import org.rocksdb.util.SizeUnit; import reactor.core.publisher.Mono; import reactor.core.scheduler.Scheduler; import reactor.core.scheduler.Schedulers; @@ -319,16 +323,8 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase { options.setCreateIfMissing(true); options.setCreateMissingColumnFamilies(true); options.setCompactionStyle(CompactionStyle.LEVEL); - options.setTargetFileSizeBase(64 * 1024 * 1024); // 64MiB sst file options.setTargetFileSizeMultiplier(2); // Each level is 2 times the previous level - if (!databaseOptions.volumes().isEmpty()) { - options.setCompressionPerLevel(databaseOptions.volumes().stream().map(v -> v.compression().getType()).toList()); - } else { - options.setCompressionType(CompressionType.LZ4_COMPRESSION); - options.setBottommostCompressionType(CompressionType.LZ4HC_COMPRESSION); - } - options.setManualWalFlush(false); - options.setMinWriteBufferNumberToMerge(3); + options.setMinWriteBufferNumberToMerge(2); options.setMaxWriteBufferNumber(4); options.setAvoidFlushDuringShutdown(false); // Flush all WALs during shutdown options.setAvoidFlushDuringRecovery(false); // Flush all WALs during startup @@ -336,10 +332,7 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase { ? WALRecoveryMode.AbsoluteConsistency : WALRecoveryMode.PointInTimeRecovery); // Crash if the WALs are corrupted.Default: TolerateCorruptedTailRecords options.setDeleteObsoleteFilesPeriodMicros(20 * 1000000); // 20 seconds - options.setPreserveDeletes(false); options.setKeepLogFileNum(10); - options.setAllowFAllocate(true); - options.setIncreaseParallelism(Runtime.getRuntime().availableProcessors()); Objects.requireNonNull(databasesDirPath); Objects.requireNonNull(path.getFileName()); @@ -347,30 +340,28 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase { options.setDbPaths(paths); options.setMaxOpenFiles(databaseOptions.maxOpenFiles()); final BlockBasedTableConfig tableOptions = new BlockBasedTableConfig(); + Cache blockCache; if (databaseOptions.lowMemory()) { // LOW MEMORY options - .setLevelCompactionDynamicLevelBytes(false) .setBytesPerSync(0) // default .setWalBytesPerSync(0) // default .setIncreaseParallelism(1) - .optimizeLevelStyleCompaction(1024 * 1024) // 1MiB of ram will be used for level style compaction - .setWriteBufferSize(1024 * 1024) // 1MB + .setWriteBufferSize(8 * SizeUnit.MB) .setWalTtlSeconds(0) .setWalSizeLimitMB(0) // 16MB .setMaxTotalWalSize(0) // automatic ; + blockCache = new ClockCache(requireNonNullElse(databaseOptions.blockCache(), 8L * SizeUnit.MB).longValue(), -1, true); tableOptions .setIndexType(IndexType.kTwoLevelIndexSearch) .setPartitionFilters(true) - .setMetadataBlockSize(4096) - .setBlockCache(new ClockCache(8L * 1024L * 1024L)) // 8MiB - // Disable to reduce IOWAIT and make the read/writes faster, enable to reduce ram usage and startup time - .setCacheIndexAndFilterBlocks(true) + .setBlockCache(blockCache) + .setCacheIndexAndFilterBlocks(requireNonNullElse(databaseOptions.setCacheIndexAndFilterBlocks(), true)) .setCacheIndexAndFilterBlocksWithHighPriority(true) + .setPinTopLevelIndexAndFilter(true) .setPinL0FilterAndIndexBlocksInCache(true) ; - options.setWriteBufferManager(new WriteBufferManager(8L * 1024L * 1024L, new ClockCache(8L * 1024L * 1024L))); // 8MiB if (databaseOptions.useDirectIO()) { options @@ -384,31 +375,27 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase { } else { // HIGH MEMORY options - .setLevelCompactionDynamicLevelBytes(true) - .setAllowConcurrentMemtableWrite(true) - .setEnableWriteThreadAdaptiveYield(true) .setIncreaseParallelism(Runtime.getRuntime().availableProcessors()) - .setBytesPerSync(64 * 1024 * 1024) // 1MiB - .setWalBytesPerSync(128 * 1024 * 1024) - .optimizeLevelStyleCompaction(2048L * 1024L * 1024L) // 2GiB of ram will be used for level style compaction - .setWriteBufferSize(64 * 1024 * 1024) // 64MB + .setBytesPerSync(8 * SizeUnit.KB) + .setWalBytesPerSync(8 * SizeUnit.KB) + .setWalTtlSeconds(30) // flush wal after 30 seconds .setWalSizeLimitMB(1024) // 1024MB - .setMaxTotalWalSize(2L * 1024L * 1024L * 1024L) // 2GiB max wal directory size + .setMaxTotalWalSize(2L * SizeUnit.GB) // 2GiB max wal directory size ; + blockCache = new ClockCache(requireNonNullElse(databaseOptions.blockCache(), 512 * SizeUnit.MB).longValue(), -1, true); tableOptions .setIndexType(IndexType.kTwoLevelIndexSearch) .setPartitionFilters(true) - .setMetadataBlockSize(4096) - .setBlockCache(new ClockCache(1024L * 1024L * 1024L)) // 1GiB - // Disable to reduce IOWAIT and make the read/writes faster, enable to reduce ram usage and startup time - .setCacheIndexAndFilterBlocks(true) + .setBlockCache(blockCache) + .setCacheIndexAndFilterBlocks(requireNonNullElse(databaseOptions.setCacheIndexAndFilterBlocks(), true)) .setCacheIndexAndFilterBlocksWithHighPriority(true) + .setPinTopLevelIndexAndFilter(true) .setPinL0FilterAndIndexBlocksInCache(true) ; - final BloomFilter bloomFilter = new BloomFilter(10, false); + final BloomFilter bloomFilter = new BloomFilter(3, false); tableOptions.setFilterPolicy(bloomFilter); - options.setWriteBufferManager(new WriteBufferManager(256L * 1024L * 1024L, new ClockCache(128L * 1024L * 1024L))); // 128MiB + tableOptions.setOptimizeFiltersForMemory(true); if (databaseOptions.useDirectIO()) { options @@ -421,8 +408,23 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase { } } + options.setWriteBufferManager(new WriteBufferManager(256L * 1024L * 1024L, blockCache)); + if (databaseOptions.memtableMemoryBudgetBytes() != null) { - options.optimizeLevelStyleCompaction(databaseOptions.memtableMemoryBudgetBytes()); + // 16MiB/256MiB of ram will be used for level style compaction + options.optimizeLevelStyleCompaction(requireNonNullElse(databaseOptions.memtableMemoryBudgetBytes(), + databaseOptions.lowMemory() ? 16L * SizeUnit.MB : 128L * SizeUnit.MB).longValue()); + } + + if (!databaseOptions.volumes().isEmpty()) { + options.setCompressionPerLevel(databaseOptions.volumes().stream().map(v -> v.compression().getType()).toList()); + options.setCompressionOptions(new CompressionOptions().setMaxDictBytes((int) (512L * SizeUnit.MB))); + options.setBottommostCompressionType(CompressionType.DISABLE_COMPRESSION_OPTION); + } else { + options.setCompressionType(CompressionType.LZ4_COMPRESSION); + options.setCompressionOptions(new CompressionOptions().setMaxDictBytes((int) (512L * SizeUnit.MB))); + options.setBottommostCompressionType(CompressionType.LZ4HC_COMPRESSION); + options.setBottommostCompressionOptions(new CompressionOptions().setMaxDictBytes((int) (512L * SizeUnit.MB))); } if (databaseOptions.useDirectIO()) { @@ -441,7 +443,7 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase { options.setUseDirectIoForFlushAndCompaction(true); } - tableOptions.setBlockSize(16 * 1024); // 16MiB + tableOptions.setBlockSize(16 * 1024); // 16KiB options.setTableFormatConfig(tableOptions); options.setCompactionPriority(CompactionPriority.MinOverlappingRatio); diff --git a/src/main/java/it/cavallium/dbengine/lucene/LuceneUtils.java b/src/main/java/it/cavallium/dbengine/lucene/LuceneUtils.java index 1232eae..e4bf6a1 100644 --- a/src/main/java/it/cavallium/dbengine/lucene/LuceneUtils.java +++ b/src/main/java/it/cavallium/dbengine/lucene/LuceneUtils.java @@ -14,6 +14,7 @@ import it.cavallium.dbengine.database.collections.DatabaseMapDictionary; import it.cavallium.dbengine.database.collections.DatabaseMapDictionaryDeep; import it.cavallium.dbengine.database.collections.ValueGetter; import it.cavallium.dbengine.database.disk.LLIndexSearchers; +import it.cavallium.dbengine.lucene.analyzer.LegacyWordAnalyzer; import it.cavallium.dbengine.lucene.analyzer.NCharGramAnalyzer; import it.cavallium.dbengine.lucene.analyzer.NCharGramEdgeAnalyzer; import it.cavallium.dbengine.lucene.analyzer.TextFieldsAnalyzer; @@ -89,6 +90,8 @@ public class LuceneUtils { private static final Analyzer luceneEdge3To5GramAnalyzerEdgeInstance = new NCharGramEdgeAnalyzer(3, 5); private static final Analyzer lucene3To5GramAnalyzerInstance = new NCharGramAnalyzer(3, 5); private static final Analyzer luceneStandardAnalyzerInstance = new StandardAnalyzer(); + private static final Analyzer luceneWordAnalyzerLegacy1Instance = new LegacyWordAnalyzer(false, true, true); + private static final Analyzer luceneWordAnalyzerLegacy2Instance = new LegacyWordAnalyzer(false, false, true); private static final Analyzer luceneWordAnalyzerStemInstance = new WordAnalyzer(false,true); private static final Analyzer luceneWordAnalyzerSimpleInstance = new WordAnalyzer(false, false); private static final Analyzer luceneICUCollationKeyInstance = new WordAnalyzer(true, true); @@ -131,6 +134,8 @@ public class LuceneUtils { case N3To5GramEdge -> luceneEdge3To5GramAnalyzerEdgeInstance; case Standard -> luceneStandardAnalyzerInstance; case StandardMultilanguage -> luceneWordAnalyzerStemInstance; + case LegacyFullText -> luceneWordAnalyzerLegacy1Instance; + case LegacyWordWithStemming -> luceneWordAnalyzerLegacy2Instance; case StandardSimple -> luceneWordAnalyzerSimpleInstance; case ICUCollationKey -> luceneICUCollationKeyInstance; //noinspection UnnecessaryDefault diff --git a/src/main/java/it/cavallium/dbengine/lucene/analyzer/LegacyWordAnalyzer.java b/src/main/java/it/cavallium/dbengine/lucene/analyzer/LegacyWordAnalyzer.java new file mode 100644 index 0000000..ca49069 --- /dev/null +++ b/src/main/java/it/cavallium/dbengine/lucene/analyzer/LegacyWordAnalyzer.java @@ -0,0 +1,1097 @@ +package it.cavallium.dbengine.lucene.analyzer; + +import com.ibm.icu.text.Collator; +import com.ibm.icu.util.ULocale; +import it.cavallium.dbengine.lucene.LuceneUtils; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.CharArraySet; +import org.apache.lucene.analysis.LowerCaseFilter; +import org.apache.lucene.analysis.StopFilter; +import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.analysis.Tokenizer; +import org.apache.lucene.analysis.en.EnglishPossessiveFilter; +import org.apache.lucene.analysis.en.KStemFilter; +import org.apache.lucene.analysis.icu.ICUCollationAttributeFactory; +import org.apache.lucene.analysis.icu.ICUCollationKeyAnalyzer; +import org.apache.lucene.analysis.miscellaneous.ASCIIFoldingFilter; +import org.apache.lucene.analysis.miscellaneous.LengthFilter; +import org.apache.lucene.analysis.standard.StandardTokenizer; + +public class LegacyWordAnalyzer extends Analyzer { + + private final boolean icu; + private final boolean removeStopWords; + private final boolean stem; + + public LegacyWordAnalyzer(boolean icu, boolean removeStopWords, boolean stem) { + this.icu = icu; + this.removeStopWords = removeStopWords; + this.stem = stem; + } + + @Override + protected TokenStreamComponents createComponents(final String fieldName) { + Tokenizer tokenizer; + if (icu) { + tokenizer = new StandardTokenizer(new ICUCollationAttributeFactory(Collator.getInstance(ULocale.ROOT))); + } else { + tokenizer = new StandardTokenizer(); + } + TokenStream tokenStream = tokenizer; + if (stem) { + tokenStream = new LengthFilter(tokenStream, 1, 120); + } + if (!icu) { + tokenStream = newCommonFilter(tokenStream, stem); + } + if (removeStopWords) { + tokenStream = new EnglishItalianStopFilter(tokenStream); + } + + return new TokenStreamComponents(tokenizer, tokenStream); + } + + @Override + protected TokenStream normalize(String fieldName, TokenStream in) { + TokenStream tokenStream = in; + tokenStream = newCommonNormalizer(tokenStream); + return tokenStream; + } + + /** + * + * @param stem Enable stem filters on words. + * Pass false if it will be used with a n-gram filter + */ + public static TokenStream newCommonFilter(TokenStream tokenStream, boolean stem) { + tokenStream = newCommonNormalizer(tokenStream); + if (stem) { + tokenStream = new KStemFilter(tokenStream); + tokenStream = new EnglishPossessiveFilter(tokenStream); + } + return tokenStream; + } + + public static TokenStream newCommonNormalizer(TokenStream tokenStream) { + tokenStream = new ASCIIFoldingFilter(tokenStream); + tokenStream = new LowerCaseFilter(tokenStream); + return tokenStream; + } + + public class EnglishItalianStopFilter extends StopFilter { + + private static final CharArraySet stopWords; + + private static final Set stopWordsString; + + /** + * Constructs a filter which removes words from the input TokenStream that are named in the Set. + * + * @param in Input stream + * @see #makeStopSet(String...) + */ + public EnglishItalianStopFilter(TokenStream in) { + super(in, stopWords); + } + + static { + var englishStopWords = Set.of("a", + "an", + "and", + "are", + "as", + "at", + "be", + "but", + "by", + "for", + "if", + "in", + "into", + "is", + "it", + "no", + "not", + "of", + "on", + "or", + "such", + "that", + "the", + "their", + "then", + "there", + "these", + "they", + "this", + "to", + "was", + "will", + "with" + ); + var oldItalianStopWords = Set.of("a", + "abbastanza", + "abbia", + "abbiamo", + "abbiano", + "abbiate", + "accidenti", + "ad", + "adesso", + "affinché", + "agl", + "agli", + "ahime", + "ahimè", + "ai", + "al", + "alcuna", + "alcuni", + "alcuno", + "all", + "alla", + "alle", + "allo", + "allora", + "altre", + "altri", + "altrimenti", + "altro", + "altrove", + "altrui", + "anche", + "ancora", + "anni", + "anno", + "ansa", + "anticipo", + "assai", + "attesa", + "attraverso", + "avanti", + "avemmo", + "avendo", + "avente", + "aver", + "avere", + "averlo", + "avesse", + "avessero", + "avessi", + "avessimo", + "aveste", + "avesti", + "avete", + "aveva", + "avevamo", + "avevano", + "avevate", + "avevi", + "avevo", + "avrai", + "avranno", + "avrebbe", + "avrebbero", + "avrei", + "avremmo", + "avremo", + "avreste", + "avresti", + "avrete", + "avrà", + "avrò", + "avuta", + "avute", + "avuti", + "avuto", + "basta", + "ben", + "bene", + "benissimo", + "brava", + "bravo", + "buono", + "c", + "caso", + "cento", + "certa", + "certe", + "certi", + "certo", + "che", + "chi", + "chicchessia", + "chiunque", + "ci", + "ciascuna", + "ciascuno", + "cima", + "cinque", + "cio", + "cioe", + "cioè", + "circa", + "citta", + "città", + "ciò", + "co", + "codesta", + "codesti", + "codesto", + "cogli", + "coi", + "col", + "colei", + "coll", + "coloro", + "colui", + "come", + "cominci", + "comprare", + "comunque", + "con", + "concernente", + "conclusione", + "consecutivi", + "consecutivo", + "consiglio", + "contro", + "cortesia", + "cos", + "cosa", + "cosi", + "così", + "cui", + "d", + "da", + "dagl", + "dagli", + "dai", + "dal", + "dall", + "dalla", + "dalle", + "dallo", + "dappertutto", + "davanti", + "degl", + "degli", + "dei", + "del", + "dell", + "della", + "delle", + "dello", + "dentro", + "detto", + "deve", + "devo", + "di", + "dice", + "dietro", + "dire", + "dirimpetto", + "diventa", + "diventare", + "diventato", + "dopo", + "doppio", + "dov", + "dove", + "dovra", + "dovrà", + "dovunque", + "due", + "dunque", + "durante", + "e", + "ebbe", + "ebbero", + "ebbi", + "ecc", + "ecco", + "ed", + "effettivamente", + "egli", + "ella", + "entrambi", + "eppure", + "era", + "erano", + "eravamo", + "eravate", + "eri", + "ero", + "esempio", + "esse", + "essendo", + "esser", + "essere", + "essi", + "ex", + "fa", + "faccia", + "facciamo", + "facciano", + "facciate", + "faccio", + "facemmo", + "facendo", + "facesse", + "facessero", + "facessi", + "facessimo", + "faceste", + "facesti", + "faceva", + "facevamo", + "facevano", + "facevate", + "facevi", + "facevo", + "fai", + "fanno", + "farai", + "faranno", + "fare", + "farebbe", + "farebbero", + "farei", + "faremmo", + "faremo", + "fareste", + "faresti", + "farete", + "farà", + "farò", + "fatto", + "favore", + "fece", + "fecero", + "feci", + "fin", + "finalmente", + "finche", + "fine", + "fino", + "forse", + "forza", + "fosse", + "fossero", + "fossi", + "fossimo", + "foste", + "fosti", + "fra", + "frattempo", + "fu", + "fui", + "fummo", + "fuori", + "furono", + "futuro", + "generale", + "gente", + "gia", + "giacche", + "giorni", + "giorno", + "giu", + "già", + "gli", + "gliela", + "gliele", + "glieli", + "glielo", + "gliene", + "grande", + "grazie", + "gruppo", + "ha", + "haha", + "hai", + "hanno", + "ho", + "i", + "ie", + "ieri", + "il", + "improvviso", + "in", + "inc", + "indietro", + "infatti", + "inoltre", + "insieme", + "intanto", + "intorno", + "invece", + "io", + "l", + "la", + "lasciato", + "lato", + "le", + "lei", + "li", + "lo", + "lontano", + "loro", + "lui", + "lungo", + "luogo", + "là", + "ma", + "macche", + "magari", + "maggior", + "mai", + "male", + "malgrado", + "malissimo", + "me", + "medesimo", + "mediante", + "meglio", + "meno", + "mentre", + "mesi", + "mezzo", + "mi", + "mia", + "mie", + "miei", + "mila", + "miliardi", + "milioni", + "minimi", + "mio", + "modo", + "molta", + "molti", + "moltissimo", + "molto", + "momento", + "mondo", + "ne", + "negl", + "negli", + "nei", + "nel", + "nell", + "nella", + "nelle", + "nello", + "nemmeno", + "neppure", + "nessun", + "nessuna", + "nessuno", + "niente", + "no", + "noi", + "nome", + "non", + "nondimeno", + "nonostante", + "nonsia", + "nostra", + "nostre", + "nostri", + "nostro", + "novanta", + "nove", + "nulla", + "nuovi", + "nuovo", + "o", + "od", + "oggi", + "ogni", + "ognuna", + "ognuno", + "oltre", + "oppure", + "ora", + "ore", + "osi", + "ossia", + "ottanta", + "otto", + "paese", + "parecchi", + "parecchie", + "parecchio", + "parte", + "partendo", + "peccato", + "peggio", + "per", + "perche", + "perchè", + "perché", + "percio", + "perciò", + "perfino", + "pero", + "persino", + "persone", + "però", + "piedi", + "pieno", + "piglia", + "piu", + "piuttosto", + "più", + "po", + "pochissimo", + "poco", + "poi", + "poiche", + "possa", + "possedere", + "posteriore", + "posto", + "potrebbe", + "preferibilmente", + "presa", + "press", + "prima", + "primo", + "principalmente", + "probabilmente", + "promesso", + "proprio", + "puo", + "pure", + "purtroppo", + "può", + "qua", + "qualche", + "qualcosa", + "qualcuna", + "qualcuno", + "quale", + "quali", + "qualunque", + "quando", + "quanta", + "quante", + "quanti", + "quanto", + "quantunque", + "quarto", + "quasi", + "quattro", + "quel", + "quella", + "quelle", + "quelli", + "quello", + "quest", + "questa", + "queste", + "questi", + "questo", + "qui", + "quindi", + "quinto", + "realmente", + "recente", + "recentemente", + "registrazione", + "relativo", + "riecco", + "rispetto", + "salvo", + "sara", + "sarai", + "saranno", + "sarebbe", + "sarebbero", + "sarei", + "saremmo", + "saremo", + "sareste", + "saresti", + "sarete", + "sarà", + "sarò", + "scola", + "scopo", + "scorso", + "se", + "secondo", + "seguente", + "seguito", + "sei", + "sembra", + "sembrare", + "sembrato", + "sembrava", + "sembri", + "sempre", + "senza", + "sette", + "si", + "sia", + "siamo", + "siano", + "siate", + "siete", + "sig", + "solito", + "solo", + "soltanto", + "sono", + "sopra", + "soprattutto", + "sotto", + "spesso", + "sta", + "stai", + "stando", + "stanno", + "starai", + "staranno", + "starebbe", + "starebbero", + "starei", + "staremmo", + "staremo", + "stareste", + "staresti", + "starete", + "starà", + "starò", + "stata", + "state", + "stati", + "stato", + "stava", + "stavamo", + "stavano", + "stavate", + "stavi", + "stavo", + "stemmo", + "stessa", + "stesse", + "stessero", + "stessi", + "stessimo", + "stesso", + "steste", + "stesti", + "stette", + "stettero", + "stetti", + "stia", + "stiamo", + "stiano", + "stiate", + "sto", + "su", + "sua", + "subito", + "successivamente", + "successivo", + "sue", + "sugl", + "sugli", + "sui", + "sul", + "sull", + "sulla", + "sulle", + "sullo", + "suo", + "suoi", + "tale", + "tali", + "talvolta", + "tanto", + "te", + "tempo", + "terzo", + "th", + "ti", + "titolo", + "tra", + "tranne", + "tre", + "trenta", + "triplo", + "troppo", + "trovato", + "tu", + "tua", + "tue", + "tuo", + "tuoi", + "tutta", + "tuttavia", + "tutte", + "tutti", + "tutto", + "uguali", + "ulteriore", + "ultimo", + "un", + "una", + "uno", + "uomo", + "va", + "vai", + "vale", + "vari", + "varia", + "varie", + "vario", + "verso", + "vi", + "vicino", + "visto", + "vita", + "voi", + "volta", + "volte", + "vostra", + "vostre", + "vostri", + "vostro", + "è"); + var italianStopWords = Set.of("a", + "abbia", + "abbiamo", + "abbiano", + "abbiate", + "ad", + "adesso", + "agl", + "agli", + "ai", + "al", + "all", + "alla", + "alle", + "allo", + "allora", + "altre", + "altri", + "altro", + "anche", + "ancora", + "avemmo", + "avendo", + "avere", + "avesse", + "avessero", + "avessi", + "avessimo", + "aveste", + "avesti", + "avete", + "aveva", + "avevamo", + "avevano", + "avevate", + "avevi", + "avevo", + "avrai", + "avranno", + "avrebbe", + "avrebbero", + "avrei", + "avremmo", + "avremo", + "avreste", + "avresti", + "avrete", + "avrà", + "avrò", + "avuta", + "avute", + "avuti", + "avuto", + "c", + "che", + "chi", + "ci", + "coi", + "col", + "come", + "con", + "contro", + "cui", + "da", + "dagl", + "dagli", + "dai", + "dal", + "dall", + "dalla", + "dalle", + "dallo", + "degl", + "degli", + "dei", + "del", + "dell", + "della", + "delle", + "dello", + "dentro", + "di", + "dov", + "dove", + "e", + "ebbe", + "ebbero", + "ebbi", + "ecco", + "ed", + "era", + "erano", + "eravamo", + "eravate", + "eri", + "ero", + "essendo", + "faccia", + "facciamo", + "facciano", + "facciate", + "faccio", + "facemmo", + "facendo", + "facesse", + "facessero", + "facessi", + "facessimo", + "faceste", + "facesti", + "faceva", + "facevamo", + "facevano", + "facevate", + "facevi", + "facevo", + "fai", + "fanno", + "farai", + "faranno", + "fare", + "farebbe", + "farebbero", + "farei", + "faremmo", + "faremo", + "fareste", + "faresti", + "farete", + "farà", + "farò", + "fece", + "fecero", + "feci", + "fino", + "fosse", + "fossero", + "fossi", + "fossimo", + "foste", + "fosti", + "fra", + "fu", + "fui", + "fummo", + "furono", + "giù", + "gli", + "ha", + "hai", + "hanno", + "ho", + "i", + "il", + "in", + "io", + "l", + "la", + "le", + "lei", + "li", + "lo", + "loro", + "lui", + "ma", + "me", + "mi", + "mia", + "mie", + "miei", + "mio", + "ne", + "negl", + "negli", + "nei", + "nel", + "nell", + "nella", + "nelle", + "nello", + "no", + "noi", + "non", + "nostra", + "nostre", + "nostri", + "nostro", + "o", + "per", + "perché", + "però", + "più", + "pochi", + "poco", + "qua", + "quale", + "quanta", + "quante", + "quanti", + "quanto", + "quasi", + "quella", + "quelle", + "quelli", + "quello", + "questa", + "queste", + "questi", + "questo", + "qui", + "quindi", + "sarai", + "saranno", + "sarebbe", + "sarebbero", + "sarei", + "saremmo", + "saremo", + "sareste", + "saresti", + "sarete", + "sarà", + "sarò", + "se", + "sei", + "senza", + "si", + "sia", + "siamo", + "siano", + "siate", + "siete", + "sono", + "sopra", + "sotto", + "sta", + "stai", + "stando", + "stanno", + "starai", + "staranno", + "stare", + "starebbe", + "starebbero", + "starei", + "staremmo", + "staremo", + "stareste", + "staresti", + "starete", + "starà", + "starò", + "stava", + "stavamo", + "stavano", + "stavate", + "stavi", + "stavo", + "stemmo", + "stesse", + "stessero", + "stessi", + "stessimo", + "stesso", + "steste", + "stesti", + "stette", + "stettero", + "stetti", + "stia", + "stiamo", + "stiano", + "stiate", + "sto", + "su", + "sua", + "sue", + "sugl", + "sugli", + "sui", + "sul", + "sull", + "sulla", + "sulle", + "sullo", + "suo", + "suoi", + "te", + "ti", + "tra", + "tu", + "tua", + "tue", + "tuo", + "tuoi", + "tutti", + "tutto", + "un", + "una", + "uno", + "vai", + "vi", + "voi", + "vostra", + "vostre", + "vostri", + "vostro", + "è" + ); + var stopWordsString2 = new HashSet<>(englishStopWords); + stopWordsString2.addAll(italianStopWords); + stopWordsString = Collections.unmodifiableSet(stopWordsString2); + stopWords = CharArraySet.copy(Stream + .concat(englishStopWords.stream(), oldItalianStopWords.stream()) + .map(String::toCharArray) + .collect(Collectors.toSet())); + } + + @SuppressWarnings("unused") + public static CharArraySet getStopWords() { + return stopWords; + } + + public static Set getStopWordsString() { + return stopWordsString; + } + } + +} diff --git a/src/main/java/it/cavallium/dbengine/lucene/analyzer/TextFieldsAnalyzer.java b/src/main/java/it/cavallium/dbengine/lucene/analyzer/TextFieldsAnalyzer.java index 94b8836..0339dc1 100644 --- a/src/main/java/it/cavallium/dbengine/lucene/analyzer/TextFieldsAnalyzer.java +++ b/src/main/java/it/cavallium/dbengine/lucene/analyzer/TextFieldsAnalyzer.java @@ -8,5 +8,7 @@ public enum TextFieldsAnalyzer { Standard, StandardSimple, ICUCollationKey, - StandardMultilanguage + StandardMultilanguage, + LegacyFullText, + LegacyWordWithStemming } diff --git a/src/test/java/it/cavallium/dbengine/LocalTemporaryDbGenerator.java b/src/test/java/it/cavallium/dbengine/LocalTemporaryDbGenerator.java index 198af54..300451e 100644 --- a/src/test/java/it/cavallium/dbengine/LocalTemporaryDbGenerator.java +++ b/src/test/java/it/cavallium/dbengine/LocalTemporaryDbGenerator.java @@ -77,8 +77,20 @@ public class LocalTemporaryDbGenerator implements TemporaryDbGenerator { return Mono.zip( conn.getDatabase("testdb", List.of(Column.dictionary("testmap"), Column.special("ints"), Column.special("longs")), - new DatabaseOptions(List.of(), Map.of(), true, false, true, false, - true, canUseNettyDirect, false, -1, null) + new DatabaseOptions(List.of(), + Map.of(), + true, + false, + true, + false, + true, + canUseNettyDirect, + false, + -1, + null, + null, + null + ) ), conn.getLuceneIndex(null, "testluceneindex1", diff --git a/src/test/java/it/cavallium/dbengine/MemoryTemporaryDbGenerator.java b/src/test/java/it/cavallium/dbengine/MemoryTemporaryDbGenerator.java index dff3a20..d3e43a1 100644 --- a/src/test/java/it/cavallium/dbengine/MemoryTemporaryDbGenerator.java +++ b/src/test/java/it/cavallium/dbengine/MemoryTemporaryDbGenerator.java @@ -49,7 +49,20 @@ public class MemoryTemporaryDbGenerator implements TemporaryDbGenerator { .zip( conn.getDatabase("testdb", List.of(Column.dictionary("testmap"), Column.special("ints"), Column.special("longs")), - new DatabaseOptions(List.of(), Map.of(), true, false, true, false, true, canUseNettyDirect, true, -1, null) + new DatabaseOptions(List.of(), + Map.of(), + true, + false, + true, + false, + true, + canUseNettyDirect, + true, + -1, + null, + null, + null + ) ), conn.getLuceneIndex(null, "testluceneindex1",