diff --git a/community/jmx/src/main/java/org/neo4j/jmx/StoreFile.java b/community/jmx/src/main/java/org/neo4j/jmx/StoreFile.java
index bd96e09db8629..ec46776102834 100644
--- a/community/jmx/src/main/java/org/neo4j/jmx/StoreFile.java
+++ b/community/jmx/src/main/java/org/neo4j/jmx/StoreFile.java
@@ -20,7 +20,9 @@
package org.neo4j.jmx;
@ManagementInterface( name = StoreFile.NAME )
-@Description( "Information about the sizes of the different parts of the Neo4j graph store" )
+@Description( "This bean is deprecated, use StoreSize bean instead; " +
+ "Information about the sizes of the different parts of the Neo4j graph store" )
+@Deprecated
public interface StoreFile
{
String NAME = "Store file sizes";
@@ -37,8 +39,8 @@ public interface StoreFile
@Description( "The amount of disk space used to store relationships, in bytes." )
long getRelationshipStoreSize();
- @Description( "The amount of disk space used to store properties "
- + "(excluding string values and array values), in bytes." )
+ @Description( "The amount of disk space used to store properties " +
+ "(excluding string values and array values), in bytes." )
long getPropertyStoreSize();
@Description( "The amount of disk space used to store string properties, in bytes." )
@@ -46,10 +48,4 @@ public interface StoreFile
@Description( "The amount of disk space used to store array properties, in bytes." )
long getArrayStoreSize();
-
- @Description( "The amount of disk space used by all logical logs, in bytes." )
- long getAllLogicalLogsSize();
-
- @Description( "The amount of disk space used by all indices, in bytes" )
- long getIndexStoreSize();
}
diff --git a/community/jmx/src/main/java/org/neo4j/jmx/StoreSize.java b/community/jmx/src/main/java/org/neo4j/jmx/StoreSize.java
new file mode 100644
index 0000000000000..dec38e28ff6d9
--- /dev/null
+++ b/community/jmx/src/main/java/org/neo4j/jmx/StoreSize.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2002-2017 "Neo Technology,"
+ * Network Engine for Objects in Lund AB [http://neotechnology.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.neo4j.jmx;
+
+@ManagementInterface( name = StoreSize.NAME )
+@Description( "Information about the disk space used by different parts of the Neo4j graph store" )
+public interface StoreSize
+{
+ String NAME = "Store sizes";
+
+ @Description( "Disk space used by the transaction logs, in bytes." )
+ long getTransactionLogsSize();
+
+ @Description( "Disk space used to store nodes, in bytes." )
+ long getNodeStoreSize();
+
+ @Description( "Disk space used to store relationships, in bytes." )
+ long getRelationshipStoreSize();
+
+ @Description( "Disk space used to store properties (excluding string values and array values), in bytes." )
+ long getPropertyStoreSize();
+
+ @Description( "Disk space used to store string properties, in bytes." )
+ long getStringStoreSize();
+
+ @Description( "Disk space used to store array properties, in bytes." )
+ long getArrayStoreSize();
+
+ @Description( "Disk space used to store labels, in bytes" )
+ long getLabelStoreSize();
+
+ @Description( "Disk space used to store counters, in bytes" )
+ long getCountStoreSize();
+
+ @Description( "Disk space used to store schemas (index and constrain declarations), in bytes" )
+ long getSchemaStoreSize();
+
+ @Description( "Disk space used to store all indices, in bytes" )
+ long getIndexStoreSize();
+
+ @Description( "Disk space used by whole store, in bytes." )
+ long getTotalStoreSize();
+}
diff --git a/community/jmx/src/main/java/org/neo4j/jmx/impl/StoreFileBean.java b/community/jmx/src/main/java/org/neo4j/jmx/impl/StoreFileBean.java
index c685f0e445df2..13519f2ceb70e 100644
--- a/community/jmx/src/main/java/org/neo4j/jmx/impl/StoreFileBean.java
+++ b/community/jmx/src/main/java/org/neo4j/jmx/impl/StoreFileBean.java
@@ -28,14 +28,9 @@
import org.neo4j.io.fs.FileUtils;
import org.neo4j.jmx.StoreFile;
import org.neo4j.kernel.NeoStoreDataSource;
-import org.neo4j.kernel.api.index.SchemaIndexProvider;
-import org.neo4j.kernel.api.labelscan.LabelScanStore;
-import org.neo4j.kernel.impl.api.LegacyIndexProviderLookup;
import org.neo4j.kernel.impl.store.MetaDataStore;
import org.neo4j.kernel.impl.transaction.log.LogFile;
-import org.neo4j.kernel.impl.transaction.log.PhysicalLogFiles;
import org.neo4j.kernel.impl.transaction.state.DataSourceManager;
-import org.neo4j.kernel.spi.legacyindex.IndexImplementation;
import static org.neo4j.kernel.impl.store.StoreFactory.NODE_STORE_NAME;
import static org.neo4j.kernel.impl.store.StoreFactory.PROPERTY_ARRAYS_STORE_NAME;
@@ -67,11 +62,7 @@ static class StoreFileImpl extends Neo4jMBean implements StoreFile
private File storePath;
private LogFile logFile;
- private PhysicalLogFiles physicalLogFiles;
private FileSystemAbstraction fs;
- private LegacyIndexProviderLookup legacyIndexProviderLookup;
- private SchemaIndexProvider schemaIndexProvider;
- private LabelScanStore labelScanStore;
StoreFileImpl( ManagementData management ) throws NotCompliantMBeanException
{
@@ -86,11 +77,6 @@ static class StoreFileImpl extends Neo4jMBean implements StoreFile
public void registered( NeoStoreDataSource ds )
{
logFile = resolveDependency( ds, LogFile.class );
- physicalLogFiles = resolveDependency( ds, PhysicalLogFiles.class );
- legacyIndexProviderLookup = resolveDependency( ds, LegacyIndexProviderLookup.class );
- schemaIndexProvider = resolveDependency( ds, SchemaIndexProvider.class );
- labelScanStore = resolveDependency( ds, LabelScanStore.class );
-
storePath = resolvePath( ds );
}
@@ -103,7 +89,6 @@ private T resolveDependency( NeoStoreDataSource ds, Class clazz )
public void unregistered( NeoStoreDataSource ds )
{
logFile = null;
- physicalLogFiles = null;
storePath = null;
}
@@ -133,47 +118,12 @@ public long getLogicalLogSize()
return logFile == null ? 0 : FileUtils.size( fs, logFile.currentLogFile() );
}
- private long sizeOf( String name )
- {
- return storePath == null ? 0 : FileUtils.size( fs, new File( storePath, name ) );
- }
-
@Override
public long getArrayStoreSize()
{
return sizeOf( ARRAY_STORE );
}
- @Override
- public long getAllLogicalLogsSize()
- {
- TotalSizeVersionVisitor logVersionVisitor = new TotalSizeVersionVisitor( fs );
-
- physicalLogFiles.accept( logVersionVisitor );
-
- return logVersionVisitor.getTotalSize();
- }
-
- @Override
- public long getIndexStoreSize()
- {
- long size = 0L;
-
- // Add legacy indices
- for ( IndexImplementation index : legacyIndexProviderLookup.all() )
- {
- size += FileUtils.size( fs, index.getIndexImplementationDirectory( storePath ) );
- }
-
- // Add schema index
- size += FileUtils.size( fs, schemaIndexProvider.getSchemaIndexStoreDirectory( storePath ) );
-
- // Add label index
- size += FileUtils.size( fs, labelScanStore.getLabelScanStoreFile() );
-
- return size;
- }
-
@Override
public long getNodeStoreSize()
{
@@ -198,26 +148,9 @@ public long getStringStoreSize()
return sizeOf( STRING_STORE );
}
- private static class TotalSizeVersionVisitor implements PhysicalLogFiles.LogVersionVisitor
+ private long sizeOf( String name )
{
- private final FileSystemAbstraction fs;
- private long totalSize;
-
- TotalSizeVersionVisitor( FileSystemAbstraction fs )
- {
- this.fs = fs;
- }
-
- long getTotalSize()
- {
- return totalSize;
- }
-
- @Override
- public void visit( File file, long logVersion )
- {
- totalSize += FileUtils.size( fs, file );
- }
+ return storePath == null ? 0 : FileUtils.size( fs, new File( storePath, name ) );
}
}
}
diff --git a/community/jmx/src/main/java/org/neo4j/jmx/impl/StoreSizeBean.java b/community/jmx/src/main/java/org/neo4j/jmx/impl/StoreSizeBean.java
new file mode 100644
index 0000000000000..bbb41394392bc
--- /dev/null
+++ b/community/jmx/src/main/java/org/neo4j/jmx/impl/StoreSizeBean.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2002-2017 "Neo Technology,"
+ * Network Engine for Objects in Lund AB [http://neotechnology.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.neo4j.jmx.impl;
+
+import java.io.File;
+import java.io.IOException;
+import javax.management.NotCompliantMBeanException;
+
+import org.neo4j.helpers.Service;
+import org.neo4j.io.fs.FileSystemAbstraction;
+import org.neo4j.io.fs.FileUtils;
+import org.neo4j.jmx.StoreSize;
+import org.neo4j.kernel.NeoStoreDataSource;
+import org.neo4j.kernel.api.index.SchemaIndexProvider;
+import org.neo4j.kernel.api.labelscan.LabelScanStore;
+import org.neo4j.kernel.impl.api.LegacyIndexProviderLookup;
+import org.neo4j.kernel.impl.store.StoreFile;
+import org.neo4j.kernel.impl.storemigration.StoreFileType;
+import org.neo4j.kernel.impl.transaction.log.PhysicalLogFiles;
+import org.neo4j.kernel.impl.transaction.state.DataSourceManager;
+import org.neo4j.kernel.spi.legacyindex.IndexImplementation;
+
+import static org.neo4j.kernel.impl.store.StoreFile.COUNTS_STORE_LEFT;
+import static org.neo4j.kernel.impl.store.StoreFile.COUNTS_STORE_RIGHT;
+import static org.neo4j.kernel.impl.store.StoreFile.LABEL_TOKEN_NAMES_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.LABEL_TOKEN_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.NODE_LABEL_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.NODE_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.PROPERTY_ARRAY_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.PROPERTY_KEY_TOKEN_NAMES_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.PROPERTY_KEY_TOKEN_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.PROPERTY_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.PROPERTY_STRING_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.RELATIONSHIP_GROUP_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.RELATIONSHIP_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.RELATIONSHIP_TYPE_TOKEN_NAMES_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.RELATIONSHIP_TYPE_TOKEN_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.SCHEMA_STORE;
+
+@Service.Implementation( ManagementBeanProvider.class )
+public final class StoreSizeBean extends ManagementBeanProvider
+{
+ StoreSizeBean()
+ {
+ super( StoreSize.class );
+ }
+
+ @Override
+ protected Neo4jMBean createMBean( ManagementData management ) throws NotCompliantMBeanException
+ {
+ return new StoreSizeImpl( management, false );
+ }
+
+ @Override
+ protected Neo4jMBean createMXBean( ManagementData management ) throws NotCompliantMBeanException
+ {
+ return new StoreSizeImpl( management, true );
+ }
+
+ static class StoreSizeImpl extends Neo4jMBean implements StoreSize
+ {
+ private final FileSystemAbstraction fs;
+ private final File storePath;
+
+ private PhysicalLogFiles physicalLogFiles;
+ private LegacyIndexProviderLookup legacyIndexProviderLookup;
+ private SchemaIndexProvider schemaIndexProvider;
+ private LabelScanStore labelScanStore;
+
+ StoreSizeImpl( ManagementData management, boolean isMXBean ) throws NotCompliantMBeanException
+ {
+ super( management, isMXBean );
+
+ fs = management.getKernelData().getFilesystemAbstraction();
+ storePath = resolveStorePath( management );
+
+ DataSourceManager dataSourceManager = management.resolveDependency( DataSourceManager.class );
+ dataSourceManager.addListener( new DataSourceManager.Listener()
+ {
+ @Override
+ public void registered( NeoStoreDataSource ds )
+ {
+ physicalLogFiles = resolveDependency( ds, PhysicalLogFiles.class );
+ legacyIndexProviderLookup = resolveDependency( ds, LegacyIndexProviderLookup.class );
+ schemaIndexProvider = resolveDependency( ds, SchemaIndexProvider.class );
+ labelScanStore = resolveDependency( ds, LabelScanStore.class );
+ }
+
+ private T resolveDependency( NeoStoreDataSource ds, Class clazz )
+ {
+ return ds.getDependencyResolver().resolveDependency( clazz );
+ }
+
+ @Override
+ public void unregistered( NeoStoreDataSource ds )
+ {
+ physicalLogFiles = null;
+ legacyIndexProviderLookup = null;
+ schemaIndexProvider = null;
+ labelScanStore = null;
+ }
+ } );
+ }
+
+ @Override
+ public long getTransactionLogsSize()
+ {
+ TotalSizeVersionVisitor logVersionVisitor = new TotalSizeVersionVisitor( fs );
+
+ physicalLogFiles.accept( logVersionVisitor );
+
+ return logVersionVisitor.getTotalSize();
+ }
+
+ @Override
+ public long getNodeStoreSize()
+ {
+ return sizeOfStoreFiles( NODE_STORE, NODE_LABEL_STORE );
+ }
+
+ @Override
+ public long getRelationshipStoreSize()
+ {
+ return sizeOfStoreFiles( RELATIONSHIP_STORE, RELATIONSHIP_GROUP_STORE, RELATIONSHIP_TYPE_TOKEN_STORE,
+ RELATIONSHIP_TYPE_TOKEN_NAMES_STORE );
+ }
+
+ @Override
+ public long getPropertyStoreSize()
+ {
+ return sizeOfStoreFiles( PROPERTY_STORE, PROPERTY_KEY_TOKEN_STORE, PROPERTY_KEY_TOKEN_NAMES_STORE );
+ }
+
+ @Override
+ public long getStringStoreSize()
+ {
+ return sizeOfStoreFiles( PROPERTY_STRING_STORE );
+ }
+
+ @Override
+ public long getArrayStoreSize()
+ {
+ return sizeOfStoreFiles( PROPERTY_ARRAY_STORE );
+ }
+
+ @Override
+ public long getLabelStoreSize()
+ {
+ return sizeOfStoreFiles( LABEL_TOKEN_STORE, LABEL_TOKEN_NAMES_STORE );
+ }
+
+ @Override
+ public long getCountStoreSize()
+ {
+ return sizeOfStoreFiles( COUNTS_STORE_LEFT, COUNTS_STORE_RIGHT );
+ }
+
+ @Override
+ public long getSchemaStoreSize()
+ {
+ return sizeOfStoreFiles( SCHEMA_STORE );
+ }
+
+ @Override
+ public long getIndexStoreSize()
+ {
+ long size = 0L;
+
+ // Add legacy indices
+ for ( IndexImplementation index : legacyIndexProviderLookup.all() )
+ {
+ size += FileUtils.size( fs, index.getIndexImplementationDirectory( storePath ) );
+ }
+
+ // Add schema index
+ size += FileUtils.size( fs, schemaIndexProvider.getSchemaIndexStoreDirectory( storePath ) );
+
+ // Add label index
+ size += FileUtils.size( fs, labelScanStore.getLabelScanStoreFile() );
+
+ return size;
+ }
+
+ @Override
+ public long getTotalStoreSize()
+ {
+ return storePath == null ? 0L : FileUtils.size( fs, storePath );
+ }
+
+ private long sizeOf( String name )
+ {
+ return storePath == null ? 0L : FileUtils.size( fs, new File( storePath, name ) );
+ }
+
+ private static class TotalSizeVersionVisitor implements PhysicalLogFiles.LogVersionVisitor
+ {
+ private final FileSystemAbstraction fs;
+ private long totalSize;
+
+ TotalSizeVersionVisitor( FileSystemAbstraction fs )
+ {
+ this.fs = fs;
+ }
+
+ long getTotalSize()
+ {
+ return totalSize;
+ }
+
+ @Override
+ public void visit( File file, long logVersion )
+ {
+ totalSize += FileUtils.size( fs, file );
+ }
+ }
+
+ /**
+ * Count the total file size, including id files, of {@link StoreFile}s.
+ * Missing files will be counted as 0 bytes.
+ *
+ * @param files the file types to count
+ * @return the total size in bytes of the files
+ */
+ private long sizeOfStoreFiles( StoreFile... files )
+ {
+ long size = 0L;
+ for ( StoreFile file : files )
+ {
+ // Get size of both store and id file
+ size += sizeOf( file.fileName( StoreFileType.STORE ) );
+ if ( file.isRecordStore() )
+ {
+ size += sizeOf( file.fileName( StoreFileType.ID ) );
+ }
+ }
+ return size;
+ }
+
+ private File resolveStorePath( ManagementData management )
+ {
+ File storeDir = management.getKernelData().getStoreDir();
+ try
+ {
+ return storeDir.getCanonicalFile().getAbsoluteFile();
+ }
+ catch ( IOException e )
+ {
+ return storeDir.getAbsoluteFile();
+ }
+ }
+ }
+}
diff --git a/community/jmx/src/main/resources/META-INF/services/org.neo4j.jmx.impl.ManagementBeanProvider b/community/jmx/src/main/resources/META-INF/services/org.neo4j.jmx.impl.ManagementBeanProvider
index 7a18f779a4848..469504e82ed6a 100644
--- a/community/jmx/src/main/resources/META-INF/services/org.neo4j.jmx.impl.ManagementBeanProvider
+++ b/community/jmx/src/main/resources/META-INF/services/org.neo4j.jmx.impl.ManagementBeanProvider
@@ -1,2 +1,3 @@
org.neo4j.jmx.impl.PrimitivesBean
org.neo4j.jmx.impl.StoreFileBean
+org.neo4j.jmx.impl.StoreSizeBean
diff --git a/community/jmx/src/test/java/org/neo4j/jmx/impl/StoreFileBeanTest.java b/community/jmx/src/test/java/org/neo4j/jmx/impl/StoreFileBeanTest.java
deleted file mode 100644
index eadd7c87c2c9f..0000000000000
--- a/community/jmx/src/test/java/org/neo4j/jmx/impl/StoreFileBeanTest.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 2002-2017 "Neo Technology,"
- * Network Engine for Objects in Lund AB [http://neotechnology.com]
- *
- * This file is part of Neo4j.
- *
- * Neo4j is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package org.neo4j.jmx.impl;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-import org.neo4j.graphdb.mockfs.EphemeralFileSystemAbstraction;
-import org.neo4j.io.fs.FileSystemAbstraction;
-import org.neo4j.io.fs.StoreChannel;
-import org.neo4j.io.pagecache.PageCache;
-import org.neo4j.jmx.StoreFile;
-import org.neo4j.kernel.NeoStoreDataSource;
-import org.neo4j.kernel.api.index.SchemaIndexProvider;
-import org.neo4j.kernel.api.labelscan.LabelScanStore;
-import org.neo4j.kernel.configuration.Config;
-import org.neo4j.kernel.impl.api.LegacyIndexProviderLookup;
-import org.neo4j.kernel.impl.transaction.log.LogFile;
-import org.neo4j.kernel.impl.transaction.log.PhysicalLogFiles;
-import org.neo4j.kernel.impl.transaction.state.DataSourceManager;
-import org.neo4j.kernel.impl.util.Dependencies;
-import org.neo4j.kernel.internal.DefaultKernelData;
-import org.neo4j.kernel.internal.GraphDatabaseAPI;
-import org.neo4j.kernel.internal.KernelData;
-import org.neo4j.kernel.spi.legacyindex.IndexImplementation;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import static org.neo4j.helpers.collection.Iterables.iterable;
-
-public class StoreFileBeanTest
-{
- private FileSystemAbstraction fs = new EphemeralFileSystemAbstraction();
- private File storeDir = new File( "" );
- private PhysicalLogFiles physicalLogFiles = new PhysicalLogFiles( storeDir, fs );
- private LegacyIndexProviderLookup legacyIndexProviderLookup = mock( LegacyIndexProviderLookup.class );
- private SchemaIndexProvider schemaIndexProvider = mock( SchemaIndexProvider.class );
- private LabelScanStore labelScanStore = mock( LabelScanStore.class );
- private StoreFile storeFileBean;
-
- @Before
- public void setUp() throws Throwable
- {
- LogFile logFile = mock( LogFile.class );
- DataSourceManager dataSourceManager = new DataSourceManager();
- GraphDatabaseAPI db = mock( GraphDatabaseAPI.class );
- NeoStoreDataSource dataSource = mock( NeoStoreDataSource.class );
-
- // Setup all dependencies
- Dependencies dependencies = new Dependencies();
- dependencies.satisfyDependency( fs );
- dependencies.satisfyDependencies( dataSourceManager );
- dependencies.satisfyDependency( logFile );
- dependencies.satisfyDependency( physicalLogFiles );
- dependencies.satisfyDependency( legacyIndexProviderLookup );
- dependencies.satisfyDependency( schemaIndexProvider );
- dependencies.satisfyDependency( labelScanStore );
- when( db.getDependencyResolver() ).thenReturn( dependencies );
- when( dataSource.getDependencyResolver() ).thenReturn( dependencies );
-
- // Start DataSourceManager
- when( dataSource.getStoreDir() ).thenReturn( storeDir );
- dataSourceManager.register( dataSource );
- dataSourceManager.start();
-
- // Create bean
- KernelData kernelData = new DefaultKernelData( fs, mock( PageCache.class ), storeDir, Config.defaults(), db );
- ManagementData data = new ManagementData( new StoreFileBean(), kernelData, ManagementSupport.load() );
- storeFileBean = (StoreFile) new StoreFileBean().createMBean( data );
- }
-
- @Test
- public void shouldCountAllLogFiles() throws Throwable
- {
- createFileOfSize( physicalLogFiles.getLogFileForVersion( 0 ), 10 );
- createFileOfSize( physicalLogFiles.getLogFileForVersion( 1 ), 20 );
-
- assertEquals( 30, storeFileBean.getAllLogicalLogsSize() );
- }
-
- @Test
- public void shouldCountAllIndexFiles() throws Exception
- {
- // Legacy index file
- File legacyIndex = new File( storeDir, "legacyIndex" );
- createFileOfSize( legacyIndex, 10 );
-
- IndexImplementation indexImplementation = mock( IndexImplementation.class );
- when( indexImplementation.getIndexImplementationDirectory( Mockito.any() ) ).thenReturn( legacyIndex );
- when( legacyIndexProviderLookup.all() ).thenReturn( iterable( indexImplementation ) );
-
- // Legacy index file
- File schemaIndex = new File( storeDir, "schemaIndex" );
- createFileOfSize( schemaIndex, 5 );
- when( schemaIndexProvider.getSchemaIndexStoreDirectory( Mockito.any() ) ).thenReturn( schemaIndex );
-
- // Label scan store
- File labelScan = new File( storeDir, "labelScanStore" );
- createFileOfSize( labelScan, 20 );
- when( labelScanStore.getLabelScanStoreFile() ).thenReturn( labelScan );
-
- // Count all files
- assertEquals( 35, storeFileBean.getIndexStoreSize() );
- }
-
- private void createFileOfSize( File file, int size ) throws IOException
- {
- try ( StoreChannel storeChannel = fs.create( file ) )
- {
- byte[] bytes = new byte[size];
- ByteBuffer buffer = ByteBuffer.wrap( bytes );
- storeChannel.writeAll( buffer );
- }
- }
-}
diff --git a/community/jmx/src/test/java/org/neo4j/jmx/impl/StoreSizeBeanTest.java b/community/jmx/src/test/java/org/neo4j/jmx/impl/StoreSizeBeanTest.java
new file mode 100644
index 0000000000000..13473768057df
--- /dev/null
+++ b/community/jmx/src/test/java/org/neo4j/jmx/impl/StoreSizeBeanTest.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2002-2017 "Neo Technology,"
+ * Network Engine for Objects in Lund AB [http://neotechnology.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.neo4j.jmx.impl;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.neo4j.graphdb.mockfs.EphemeralFileSystemAbstraction;
+import org.neo4j.io.fs.FileSystemAbstraction;
+import org.neo4j.io.fs.StoreChannel;
+import org.neo4j.io.pagecache.PageCache;
+import org.neo4j.jmx.StoreSize;
+import org.neo4j.kernel.NeoStoreDataSource;
+import org.neo4j.kernel.api.index.SchemaIndexProvider;
+import org.neo4j.kernel.api.labelscan.LabelScanStore;
+import org.neo4j.kernel.configuration.Config;
+import org.neo4j.kernel.impl.api.LegacyIndexProviderLookup;
+import org.neo4j.kernel.impl.transaction.log.PhysicalLogFiles;
+import org.neo4j.kernel.impl.transaction.state.DataSourceManager;
+import org.neo4j.kernel.impl.util.Dependencies;
+import org.neo4j.kernel.internal.DefaultKernelData;
+import org.neo4j.kernel.internal.GraphDatabaseAPI;
+import org.neo4j.kernel.internal.KernelData;
+import org.neo4j.kernel.spi.legacyindex.IndexImplementation;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.neo4j.helpers.collection.Iterables.iterable;
+import static org.neo4j.kernel.impl.store.StoreFile.COUNTS_STORE_LEFT;
+import static org.neo4j.kernel.impl.store.StoreFile.COUNTS_STORE_RIGHT;
+import static org.neo4j.kernel.impl.store.StoreFile.LABEL_TOKEN_NAMES_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.LABEL_TOKEN_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.NODE_LABEL_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.NODE_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.PROPERTY_ARRAY_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.PROPERTY_KEY_TOKEN_NAMES_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.PROPERTY_KEY_TOKEN_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.PROPERTY_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.PROPERTY_STRING_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.RELATIONSHIP_GROUP_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.RELATIONSHIP_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.RELATIONSHIP_TYPE_TOKEN_NAMES_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.RELATIONSHIP_TYPE_TOKEN_STORE;
+import static org.neo4j.kernel.impl.store.StoreFile.SCHEMA_STORE;
+import static org.neo4j.kernel.impl.storemigration.StoreFileType.ID;
+import static org.neo4j.kernel.impl.storemigration.StoreFileType.STORE;
+
+public class StoreSizeBeanTest
+{
+ private FileSystemAbstraction fs = new EphemeralFileSystemAbstraction();
+ private File storeDir = new File( "" );
+ private PhysicalLogFiles physicalLogFiles = new PhysicalLogFiles( storeDir, fs );
+ private LegacyIndexProviderLookup legacyIndexProviderLookup = mock( LegacyIndexProviderLookup.class );
+ private SchemaIndexProvider schemaIndexProvider = mock( SchemaIndexProvider.class );
+ private LabelScanStore labelScanStore = mock( LabelScanStore.class );
+ private StoreSize storeSizeBean;
+
+ @Before
+ public void setUp() throws Throwable
+ {
+ DataSourceManager dataSourceManager = new DataSourceManager();
+ GraphDatabaseAPI db = mock( GraphDatabaseAPI.class );
+ NeoStoreDataSource dataSource = mock( NeoStoreDataSource.class );
+
+ // Setup all dependencies
+ Dependencies dependencies = new Dependencies();
+ dependencies.satisfyDependency( fs );
+ dependencies.satisfyDependencies( dataSourceManager );
+ dependencies.satisfyDependency( physicalLogFiles );
+ dependencies.satisfyDependency( legacyIndexProviderLookup );
+ dependencies.satisfyDependency( schemaIndexProvider );
+ dependencies.satisfyDependency( labelScanStore );
+ when( db.getDependencyResolver() ).thenReturn( dependencies );
+ when( dataSource.getDependencyResolver() ).thenReturn( dependencies );
+
+ // Start DataSourceManager
+ dataSourceManager.register( dataSource );
+ dataSourceManager.start();
+
+ // Create bean
+ KernelData kernelData = new DefaultKernelData( fs, mock( PageCache.class ), storeDir, Config.empty(), db );
+ ManagementData data = new ManagementData( new StoreSizeBean(), kernelData, ManagementSupport.load() );
+ storeSizeBean = (StoreSize) new StoreSizeBean().createMBean( data );
+
+ // Create a simulated file structure of the store
+ Map dummyStore = new HashMap<>();
+ dummyStore.put( NODE_STORE.fileName( STORE ), 1 );
+ dummyStore.put( NODE_STORE.fileName( ID ), 2 );
+ dummyStore.put( NODE_LABEL_STORE.fileName( STORE ), 3 );
+ dummyStore.put( NODE_LABEL_STORE.fileName( ID ), 4 );
+ dummyStore.put( PROPERTY_STORE.fileName( STORE ), 5 );
+ dummyStore.put( PROPERTY_STORE.fileName( ID ), 6 );
+ dummyStore.put( PROPERTY_KEY_TOKEN_STORE.fileName( STORE ), 7 );
+ dummyStore.put( PROPERTY_KEY_TOKEN_STORE.fileName( ID ), 8 );
+ dummyStore.put( PROPERTY_KEY_TOKEN_NAMES_STORE.fileName( STORE ), 9 );
+ dummyStore.put( PROPERTY_KEY_TOKEN_NAMES_STORE.fileName( ID ), 10 );
+ dummyStore.put( PROPERTY_STRING_STORE.fileName( STORE ), 11 );
+ dummyStore.put( PROPERTY_STRING_STORE.fileName( ID ), 12 );
+ dummyStore.put( PROPERTY_ARRAY_STORE.fileName( STORE ), 13 );
+ dummyStore.put( PROPERTY_ARRAY_STORE.fileName( ID ), 14 );
+ dummyStore.put( RELATIONSHIP_STORE.fileName( STORE ), 15 );
+ dummyStore.put( RELATIONSHIP_STORE.fileName( ID ), 16 );
+ dummyStore.put( RELATIONSHIP_GROUP_STORE.fileName( STORE ), 17 );
+ dummyStore.put( RELATIONSHIP_GROUP_STORE.fileName( ID ), 18 );
+ dummyStore.put( RELATIONSHIP_TYPE_TOKEN_STORE.fileName( STORE ), 19 );
+ dummyStore.put( RELATIONSHIP_TYPE_TOKEN_STORE.fileName( ID ), 20 );
+ dummyStore.put( RELATIONSHIP_TYPE_TOKEN_NAMES_STORE.fileName( STORE ), 21 );
+ dummyStore.put( RELATIONSHIP_TYPE_TOKEN_NAMES_STORE.fileName( ID ), 22 );
+ dummyStore.put( LABEL_TOKEN_STORE.fileName( STORE ), 23 );
+ dummyStore.put( LABEL_TOKEN_STORE.fileName( ID ), 24 );
+ dummyStore.put( LABEL_TOKEN_NAMES_STORE.fileName( STORE ), 25 );
+ dummyStore.put( LABEL_TOKEN_NAMES_STORE.fileName( ID ), 26 );
+ dummyStore.put( SCHEMA_STORE.fileName( STORE ), 27 );
+ dummyStore.put( SCHEMA_STORE.fileName( ID ), 28 );
+ dummyStore.put( COUNTS_STORE_LEFT.fileName( STORE ), 29 );
+ // COUNTS_STORE_RIGHT is created in the test
+
+ File storeDirAbsolute = storeDir.getCanonicalFile().getAbsoluteFile();
+ for ( Map.Entry dummyFile : dummyStore.entrySet() )
+ {
+ createFileOfSize( new File( storeDirAbsolute, dummyFile.getKey() ), dummyFile.getValue() );
+ }
+ }
+
+ @Test
+ public void sumAllNodeRelatedFiles() throws Exception
+ {
+ assertEquals( getExpected(1, 4 ), storeSizeBean.getNodeStoreSize() );
+ }
+
+ @Test
+ public void sumAllPropertyRelatedFiles() throws Exception
+ {
+ assertEquals( getExpected( 5, 10 ), storeSizeBean.getPropertyStoreSize() );
+ }
+
+ @Test
+ public void sumAllStringRelatedFiles() throws Exception
+ {
+ assertEquals( getExpected(11, 12 ), storeSizeBean.getStringStoreSize() );
+ }
+
+ @Test
+ public void sumAllArrayRelatedFiles() throws Exception
+ {
+ assertEquals( getExpected(13, 14 ), storeSizeBean.getArrayStoreSize() );
+ }
+
+ @Test
+ public void sumAllRelationshipRelatedFiles() throws Exception
+ {
+ assertEquals( getExpected( 15, 22 ), storeSizeBean.getRelationshipStoreSize() );
+ }
+
+ @Test
+ public void sumAllLabelRelatedFiles() throws Exception
+ {
+ assertEquals( getExpected( 23, 26 ), storeSizeBean.getLabelStoreSize() );
+ }
+
+ @Test
+ public void sumAllCountStoreRelatedFiles() throws Exception
+ {
+ assertEquals( getExpected( 29, 29), storeSizeBean.getCountStoreSize() );
+ createFileOfSize( new File( storeDir.getCanonicalFile().getAbsoluteFile(), COUNTS_STORE_RIGHT.fileName( STORE ) ), 30 );
+ assertEquals( getExpected( 29, 30), storeSizeBean.getCountStoreSize() );
+ }
+
+ @Test
+ public void sumAllSchemaRelatedFiles() throws Exception
+ {
+ assertEquals( getExpected( 27, 28 ), storeSizeBean.getSchemaStoreSize() );
+ }
+
+ @Test
+ public void sumAllFiles() throws Exception
+ {
+ assertEquals( getExpected( 0, 29 ), storeSizeBean.getTotalStoreSize() );
+ }
+
+ @Test
+ public void shouldCountAllLogFiles() throws Throwable
+ {
+ createFileOfSize( physicalLogFiles.getLogFileForVersion( 0 ), 1 );
+ createFileOfSize( physicalLogFiles.getLogFileForVersion( 1 ), 2 );
+
+ assertEquals( 3L, storeSizeBean.getTransactionLogsSize() );
+ }
+
+ @Test
+ public void shouldCountAllIndexFiles() throws Exception
+ {
+ // Legacy index file
+ File legacyIndex = new File( storeDir, "legacyIndex" );
+ createFileOfSize( legacyIndex, 1 );
+
+ IndexImplementation indexImplementation = mock( IndexImplementation.class );
+ when( indexImplementation.getIndexImplementationDirectory( any() ) ).thenReturn( legacyIndex );
+ when( legacyIndexProviderLookup.all() ).thenReturn( iterable( indexImplementation ) );
+
+ // Legacy index file
+ File schemaIndex = new File( storeDir, "schemaIndex" );
+ createFileOfSize( schemaIndex, 2 );
+ when( schemaIndexProvider.getSchemaIndexStoreDirectory( any() ) ).thenReturn( schemaIndex );
+
+ // Label scan store
+ File labelScan = new File( storeDir, "labelScanStore" );
+ createFileOfSize( labelScan, 4 );
+ when( labelScanStore.getLabelScanStoreFile() ).thenReturn( labelScan );
+
+ // Count all files
+ assertEquals( 7, storeSizeBean.getIndexStoreSize() );
+ }
+
+ private void createFileOfSize( File file, int size ) throws IOException
+ {
+ try ( StoreChannel storeChannel = fs.create( file ) )
+ {
+ byte[] bytes = new byte[size];
+ ByteBuffer buffer = ByteBuffer.wrap( bytes );
+ storeChannel.writeAll( buffer );
+ }
+ }
+
+ private long getExpected( int lower, int upper )
+ {
+ long expected = 0;
+ for ( int i = lower; i <= upper; i++ )
+ {
+ expected += i;
+ }
+ return expected;
+ }
+}