@Override
  public StatementOperationParts newStatementOperations() {
    // Store stuff
    StatementOperationParts parts = delegate.newStatementOperations();

    // + Caching
    CachingStatementOperations cachingContext =
        new CachingStatementOperations(
            parts.entityReadOperations(),
            parts.schemaReadOperations(),
            persistenceCache,
            schemaCache);
    parts = parts.override(null, null, cachingContext, null, cachingContext, null, null);

    // + Transaction-local state awareness
    AuxiliaryStoreOperations auxStoreOperations = parts.resolve(AuxiliaryStoreOperations.class);
    auxStoreOperations =
        new LegacyAutoIndexAuxStoreOps(
            auxStoreOperations,
            propertyKeyTokenHolder,
            nodeManager.getNodePropertyTrackers(),
            nodeManager.getRelationshipPropertyTrackers(),
            nodeManager);

    StateHandlingStatementOperations stateHandlingContext =
        new StateHandlingStatementOperations(
            parts.entityReadOperations(),
            parts.schemaReadOperations(),
            auxStoreOperations,
            constraintIndexCreator);

    parts =
        parts.override(
            null,
            null,
            stateHandlingContext,
            stateHandlingContext,
            stateHandlingContext,
            stateHandlingContext,
            new SchemaStateConcern(schemaState));

    // done
    return parts;
  }
Beispiel #2
0
  private KernelModule buildKernel(
      IntegrityValidator integrityValidator,
      LogicalTransactionStore logicalTransactionStore,
      NeoStore neoStore,
      TransactionRepresentationStoreApplier storeApplier,
      IndexingService indexingService,
      StoreReadLayer storeLayer,
      UpdateableSchemaState updateableSchemaState,
      LabelScanStore labelScanStore,
      PersistenceCache persistenceCache,
      SchemaIndexProviderMap schemaIndexProviderMap) {
    final TransactionCommitProcess transactionCommitProcess =
        commitProcessFactory.create(
            logicalTransactionStore,
            kernelHealth,
            neoStore,
            storeApplier,
            new NeoStoreInjectedTransactionValidator(integrityValidator),
            TransactionApplicationMode.INTERNAL,
            config);

    /*
     * This is used by legacy indexes and constraint indexes whenever a transaction is to be spawned
     * from within an existing transaction. It smells, and we should look over alternatives when time permits.
     */
    Provider<KernelAPI> kernelProvider =
        new Provider<KernelAPI>() {
          @Override
          public KernelAPI instance() {
            return kernelModule.kernelAPI();
          }
        };

    ConstraintIndexCreator constraintIndexCreator =
        new ConstraintIndexCreator(kernelProvider, indexingService);

    LegacyIndexStore legacyIndexStore =
        new LegacyIndexStore(config, indexConfigStore, kernelProvider, legacyIndexProviderLookup);

    LegacyPropertyTrackers legacyPropertyTrackers =
        new LegacyPropertyTrackers(
            propertyKeyTokenHolder,
            nodeManager.getNodePropertyTrackers(),
            nodeManager.getRelationshipPropertyTrackers(),
            nodeManager);
    final NeoStoreTransactionContextSupplier neoStoreTransactionContextSupplier =
        new NeoStoreTransactionContextSupplier(neoStore);

    StatementOperationParts statementOperations =
        buildStatementOperations(
            storeLayer,
            legacyPropertyTrackers,
            constraintIndexCreator,
            updateableSchemaState,
            guard,
            legacyIndexStore);

    final TransactionHooks hooks = new TransactionHooks();
    final KernelTransactions kernelTransactions =
        life.add(
            new KernelTransactions(
                neoStoreTransactionContextSupplier,
                neoStore,
                locks,
                integrityValidator,
                constraintIndexCreator,
                indexingService,
                labelScanStore,
                statementOperations,
                updateableSchemaState,
                schemaWriteGuard,
                schemaIndexProviderMap,
                transactionHeaderInformationFactory,
                persistenceCache,
                storeLayer,
                transactionCommitProcess,
                indexConfigStore,
                legacyIndexProviderLookup,
                hooks,
                transactionMonitor,
                life));

    final Kernel kernel = new Kernel(kernelTransactions, hooks, kernelHealth, transactionMonitor);

    kernel.registerTransactionHook(transactionEventHandlers);

    final NeoStoreFileListing fileListing =
        new NeoStoreFileListing(
            storeDir, labelScanStore, indexingService, legacyIndexProviderLookup);

    return new KernelModule() {
      @Override
      public TransactionCommitProcess transactionCommitProcess() {
        return transactionCommitProcess;
      }

      @Override
      public KernelAPI kernelAPI() {
        return kernel;
      }

      @Override
      public KernelTransactions kernelTransactions() {
        return kernelTransactions;
      }

      @Override
      public NeoStoreFileListing fileListing() {
        return fileListing;
      }
    };
  }
  @Override
  public void start() throws IOException {
    life = new LifeSupport();
    readOnly = config.get(Configuration.read_only);
    storeDir = config.get(Configuration.store_dir);
    File store = config.get(Configuration.neo_store);
    if (!storeFactory.storeExists()) {
      storeFactory.createNeoStore().close();
    }
    indexProvider =
        dependencyResolver.resolveDependency(
            SchemaIndexProvider.class, SchemaIndexProvider.HIGHEST_PRIORITIZED_OR_NONE);
    storeMigrationProcess.addParticipant(indexProvider.storeMigrationParticipant());
    // TODO: Build a real provider map
    final DefaultSchemaIndexProviderMap providerMap =
        new DefaultSchemaIndexProviderMap(indexProvider);
    storeMigrationProcess.migrateIfNeeded(store.getParentFile());
    neoStore = dependencies.satisfyDependency(storeFactory.newNeoStore(false));
    dependencies.satisfyDependency(TransactionIdStore.class, neoStore);

    schemaCache = new SchemaCache(Collections.<SchemaRule>emptyList());

    nodeCache = new AutoLoadingCache<>(cacheProvider.node(), nodeLoader(neoStore.getNodeStore()));
    relationshipCache =
        new AutoLoadingCache<>(
            cacheProvider.relationship(), relationshipLoader(neoStore.getRelationshipStore()));
    RelationshipLoader relationshipLoader =
        new RelationshipLoader(relationshipCache, new RelationshipChainLoader(neoStore));
    PersistenceCache persistenceCache =
        new PersistenceCache(
            nodeCache,
            relationshipCache,
            nodeManager,
            relationshipLoader,
            propertyKeyTokenHolder,
            relationshipTypeTokens,
            labelTokens);
    CacheAccessBackDoor cacheAccess =
        new BridgingCacheAccess(schemaCache, updateableSchemaState, persistenceCache);
    try {
      indexingService =
          new IndexingService(
              scheduler,
              providerMap,
              new NeoStoreIndexStoreView(lockService, neoStore),
              tokenNameLookup,
              updateableSchemaState,
              indexRuleLoader(),
              logging,
              indexingServiceMonitor); // TODO 2.2-future What index rules should be
      final IntegrityValidator integrityValidator =
          new IntegrityValidator(neoStore, indexingService);
      labelScanStore =
          dependencyResolver
              .resolveDependency(
                  LabelScanStoreProvider.class, LabelScanStoreProvider.HIGHEST_PRIORITIZED)
              .getLabelScanStore();
      fileListing =
          new NeoStoreFileListing(
              storeDir, labelScanStore, indexingService, legacyIndexProviderLookup);
      Provider<NeoStore> neoStoreProvider =
          new Provider<NeoStore>() {
            @Override
            public NeoStore instance() {
              return getNeoStore();
            }
          };

      if (config.get(GraphDatabaseSettings.cache_type).equals(CacheLayer.EXPERIMENTAL_OFF)) {
        storeLayer =
            new DiskLayer(
                propertyKeyTokenHolder,
                labelTokens,
                relationshipTypeTokens,
                new SchemaStorage(neoStore.getSchemaStore()),
                neoStoreProvider,
                indexingService);
      } else {
        storeLayer =
            new CacheLayer(
                new DiskLayer(
                    propertyKeyTokenHolder,
                    labelTokens,
                    relationshipTypeTokens,
                    new SchemaStorage(neoStore.getSchemaStore()),
                    neoStoreProvider,
                    indexingService),
                persistenceCache,
                indexingService,
                schemaCache);
      }

      LegacyPropertyTrackers legacyPropertyTrackers =
          new LegacyPropertyTrackers(
              propertyKeyTokenHolder,
              nodeManager.getNodePropertyTrackers(),
              nodeManager.getRelationshipPropertyTrackers(),
              nodeManager);
      StatisticsService statisticsService =
          new StatisticsServiceRepository(fs, config, storeLayer, scheduler).loadStatistics();
      final NeoStoreTransactionContextSupplier neoStoreTransactionContextSupplier =
          new NeoStoreTransactionContextSupplier(neoStore);

      final TransactionHooks hooks = new TransactionHooks();
      File directory = config.get(GraphDatabaseSettings.store_dir);
      TransactionMetadataCache transactionMetadataCache =
          new TransactionMetadataCache(1000, 100_000);
      PhysicalLogFiles logFiles = new PhysicalLogFiles(directory, PhysicalLogFile.DEFAULT_NAME, fs);

      LogFileInformation logFileInformation =
          dependencies.satisfyDependency(
              LogFileInformation.class,
              new PhysicalLogFileInformation(
                  logFiles,
                  transactionMetadataCache,
                  neoStore,
                  new PhysicalLogFileInformation.SPI() {
                    @Override
                    public long getTimestampForVersion(long version) throws IOException {
                      LogPosition position = new LogPosition(version, LOG_HEADER_SIZE);
                      try (ReadableLogChannel channel = logFile.getReader(position)) {
                        LogEntryReader<ReadableLogChannel> reader =
                            new VersionAwareLogEntryReader();
                        LogEntry entry;
                        while ((entry = reader.readLogEntry(channel)) != null) {
                          if (entry instanceof LogEntryStart) {
                            return ((LogEntryStart) entry).getTimeWritten();
                          }
                        }
                      }
                      return -1;
                    }
                  }));

      LogPruneStrategy logPruneStrategy =
          LogPruneStrategyFactory.fromConfigValue(
              fs,
              logFileInformation,
              logFiles,
              neoStore,
              config.get(GraphDatabaseSettings.keep_logical_logs));

      final TransactionRepresentationStoreApplier storeApplier =
          dependencies.satisfyDependency(
              new TransactionRepresentationStoreApplier(
                  indexingService,
                  labelScanStore,
                  neoStore,
                  cacheAccess,
                  lockService,
                  legacyIndexProviderLookup,
                  indexConfigStore,
                  DEFAULT_HIGH_ID_TRACKING));

      LoggingLogFileMonitor logMonitor =
          new LoggingLogFileMonitor(logging.getMessagesLog(getClass()));
      RecoveryVisitor recoveryVisitor =
          new RecoveryVisitor(neoStore, storeApplier, recoveredCount, logMonitor);
      Visitor<ReadableLogChannel, IOException> logFileRecoverer =
          new LogFileRecoverer(new VersionAwareLogEntryReader(), recoveryVisitor);
      logFile =
          dependencies.satisfyDependency(
              new PhysicalLogFile(
                  fs,
                  logFiles,
                  config.get(GraphDatabaseSettings.logical_log_rotation_threshold),
                  logPruneStrategy,
                  neoStore,
                  neoStore,
                  logMonitor,
                  this,
                  transactionMetadataCache,
                  logFileRecoverer));

      final LogicalTransactionStore logicalTransactionStore =
          dependencies.satisfyDependency(
              LogicalTransactionStore.class,
              new PhysicalLogicalTransactionStore(
                  logFile,
                  txIdGenerator,
                  transactionMetadataCache,
                  neoStore,
                  config.get(GraphDatabaseSettings.batched_writes)));

      TransactionCommitProcess transactionCommitProcess =
          dependencies.satisfyDependency(
              TransactionCommitProcess.class,
              commitProcessFactory.create(
                  logicalTransactionStore,
                  kernelHealth,
                  neoStore,
                  storeApplier,
                  new NeoStoreInjectedTransactionValidator(integrityValidator),
                  false));

      /*
       * This is used by legacy indexes and constraint indexes whenever a transaction is to be spawned
       * from within an existing transaction. It smells, and we should look over alternatives when time permits.
       */
      Provider<KernelAPI> kernelProvider =
          new Provider<KernelAPI>() {
            @Override
            public KernelAPI instance() {
              return kernel;
            }
          };

      ConstraintIndexCreator constraintIndexCreator =
          new ConstraintIndexCreator(kernelProvider, indexingService);

      LegacyIndexStore legacyIndexStore =
          new LegacyIndexStore(config, indexConfigStore, kernelProvider, legacyIndexProviderLookup);

      StatementOperationParts statementOperations =
          buildStatementOperations(
              storeLayer,
              legacyPropertyTrackers,
              constraintIndexCreator,
              updateableSchemaState,
              guard,
              legacyIndexStore);

      kernelTransactions =
          life.add(
              new KernelTransactions(
                  neoStoreTransactionContextSupplier,
                  neoStore,
                  locks,
                  integrityValidator,
                  constraintIndexCreator,
                  indexingService,
                  labelScanStore,
                  statementOperations,
                  updateableSchemaState,
                  schemaWriteGuard,
                  providerMap,
                  transactionHeaderInformationFactory,
                  persistenceCache,
                  storeLayer,
                  transactionCommitProcess,
                  indexConfigStore,
                  legacyIndexProviderLookup,
                  hooks,
                  transactionMonitor,
                  life,
                  readOnly));

      kernel =
          new Kernel(
              statisticsService, kernelTransactions, hooks, kernelHealth, transactionMonitor);

      life.add(logFile);
      life.add(logicalTransactionStore);
      life.add(
          new LifecycleAdapter() {
            @Override
            public void start() throws Throwable {
              startupStatistics.setNumberOfRecoveredTransactions(recoveredCount.get());
              recoveredCount.set(0);
              loadSchemaCache();
            }
          });
      life.add(statisticsService);
      life.add(
          new LifecycleAdapter() {
            @Override
            public void start() {
              neoStore.makeStoreOk();
            }
          });
      life.add(indexingService);
      life.add(labelScanStore);

      kernel.registerTransactionHook(transactionEventHandlers);
      neoStore.setRecoveredStatus(true);
      try {
        life.start();
      } finally {
        neoStore.setRecoveredStatus(false);
      }

      propertyKeyTokenHolder.addTokens(
          neoStore.getPropertyKeyTokenStore().getTokens(Integer.MAX_VALUE));
      relationshipTypeTokens.addTokens(
          neoStore.getRelationshipTypeTokenStore().getTokens(Integer.MAX_VALUE));
      labelTokens.addTokens(neoStore.getLabelTokenStore().getTokens(Integer.MAX_VALUE));
    } catch (Throwable e) { // Something unexpected happened during startup
      try { // Close the neostore, so that locks are released properly
        neoStore.close();
      } catch (Exception closeException) {
        msgLog.logMessage("Couldn't close neostore after startup failure");
      }
      throw Exceptions.launderedException(e);
    }
  }