<commit_before>using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using BerkeleyDB;
using Dccelerator.Reflection;


namespace Dccelerator.DataAccess.BerkeleyDb.Implementation {
    class BDbSchema : IBDbSchema {
        readonly string _environmentPath;
        readonly string _dbPath;
        string _password;
        //readonly ConcurrentDictionary<string, Database> _primaryReadOnlyDbs = new ConcurrentDictionary<string, Database>();
        readonly ConcurrentDictionary<string, SecondaryDatabase> _secondaryReadOnlyDbs = new ConcurrentDictionary<string, SecondaryDatabase>();

        readonly ConcurrentDictionary<string, Database> _primaryWritableDbs = new ConcurrentDictionary<string, Database>();
        readonly ConcurrentDictionary<string, SecondaryDatabase> _foreignKeyWritableDbs = new ConcurrentDictionary<string, SecondaryDatabase>();

        readonly HashSet<string> _transactionPreparedEntities = new HashSet<string>(); 



        public bool IsEncrypted { get; private set; }

        public bool IsFreeThreaded { get; private set; }

        public virtual DatabaseEnvironment Environment {
            get {
                if (_environment != null)
                    return _environment;

                _environment = OpenEnvironment(_environmentPath, _dbPath, _password);
                _password = <PASSWORD>;

                IsEncrypted = _environment.EncryptAlgorithm == EncryptionAlgorithm.AES;
                IsFreeThreaded = _environment.FreeThreaded;

                return _environment;
            }
        }

        DatabaseEnvironment _environment;

        public BDbSchema(string environmentPath, string dbPath) : this(environmentPath, dbPath, null) { }

        public BDbSchema(string environmentPath, string dbPath, string password) {
            _environmentPath = environmentPath;
            _dbPath = dbPath;
            _password = password;
        }



        public Database GetPrimaryDb(string dbName, bool readOnly) {
            Database database;
            if (_primaryWritableDbs.TryGetValue(dbName, out database))
                return database;

            database = OpenDatabase(dbName);
            if (_primaryWritableDbs.TryAdd(dbName, database))
                return database;

            database.Close();
            database = _primaryWritableDbs[dbName];
            return database;
        }


        public SecondaryDatabase GetReadOnlySecondaryDb(Database primaryDb, string indexSubName, DuplicatesPolicy duplicatesPolicy) {
            var dbName = SecondaryDbName(primaryDb, indexSubName);<commit_msg>BDbSchema: constructor now checks is dbPath are just file name, and is environmentPath exists, If not - it tries to create environmentPath.<commit_after>using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using BerkeleyDB;
using Dccelerator.Reflection;
using Dccelerator.DataAccess.Infrastructure;

namespace Dccelerator.DataAccess.BerkeleyDb.Implementation {
    class BDbSchema : IBDbSchema {
        readonly string _environmentPath;
        readonly string _dbPath;
        string _password;
        //readonly ConcurrentDictionary<string, Database> _primaryReadOnlyDbs = new ConcurrentDictionary<string, Database>();
        readonly ConcurrentDictionary<string, SecondaryDatabase> _secondaryReadOnlyDbs = new ConcurrentDictionary<string, SecondaryDatabase>();

        readonly ConcurrentDictionary<string, Database> _primaryWritableDbs = new ConcurrentDictionary<string, Database>();
        readonly ConcurrentDictionary<string, SecondaryDatabase> _foreignKeyWritableDbs = new ConcurrentDictionary<string, SecondaryDatabase>();

        readonly HashSet<string> _transactionPreparedEntities = new HashSet<string>(); 



        public bool IsEncrypted { get; private set; }

        public bool IsFreeThreaded { get; private set; }

        public virtual DatabaseEnvironment Environment {
            get {
                if (_environment != null)
                    return _environment;

                _environment = OpenEnvironment(_environmentPath, _dbPath, _password);
                _password = null;

                IsEncrypted = _environment.EncryptAlgorithm == EncryptionAlgorithm.AES;
                IsFreeThreaded = _environment.FreeThreaded;

                return _environment;
            }
        }

        DatabaseEnvironment _environment;

        public BDbSchema(string environmentPath, string dbPath) : this(environmentPath, dbPath, null) { }


        /// <exception cref="InvalidOperationException">Can't create environment directory.</exception>
        /// <exception cref="ArgumentException">BerkeleyDb file name is an absolute or relative path, but should be just file name (with or without extension).</exception>
        public BDbSchema(string environmentPath, string dbPath, string password) {
            _environmentPath = environmentPath;
            _dbPath = dbPath;
            _password = password;

            if (Path.GetFileName(_dbPath) != _dbPath) {
                var msg = $"BerkeleyDb file name '{dbPath}' is an absolute or relative path, but should be just file name (with or without extension)";
                Internal.TraceEvent(TraceEventType.Error, msg);
                throw new ArgumentException(msg, nameof(dbPath));
            }

            if (!Directory.Exists(_environmentPath)) {
                try {
                    Directory.CreateDirectory(_environmentPath);
                }
                catch (Exception e) {
                    var msg = $"Can't create environment directory {environmentPath}";
                    Internal.TraceEvent(TraceEventType.Error, msg);
                    throw new InvalidOperationException(msg, e);
                }
            }
        }



        public Database GetPrimaryDb(string dbName, bool readOnly) {
            Database database;
            if (_primaryWritableDbs.TryGetValue(dbName, out database))
                return database;

            database = OpenDatabase(dbName);
            if (_primaryWritableDbs.TryAdd(dbName, database))
                return database;

            database.Close();
            database = _primaryWritableDbs[dbName];
            return database;
        }


        public SecondaryDatabase GetReadOnlySecondaryDb(Database primaryDb, string indexSubName, DuplicatesPolicy duplicatesPolicy) {
            var dbName = SecondaryDbName(primaryDb, indexSubName);
{'fraction_non_alphanumeric': 0.07003950167122455, 'fraction_numerical': 0.0, 'mean_word_length': 2.706644144144144, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 28, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6442626', 'n_tokens_mistral': 1571, 'n_tokens_neox': 1478, 'n_words': 409}