Skip to content

Commit

Permalink
Test for correct memory mapping of a file that is growing.
Browse files Browse the repository at this point in the history
When growing a store file, ensure that new regions at the end of the file are memory mapped, and there are no misses.
  • Loading branch information
apcj committed Sep 6, 2012
1 parent 1f21aa9 commit d73555a
Showing 1 changed file with 91 additions and 0 deletions.
@@ -0,0 +1,91 @@
/**
* Copyright (c) 2002-2012 "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 <http://www.gnu.org/licenses/>.
*/
package org.neo4j.kernel.impl.nioneo.store;

import static org.junit.Assert.assertEquals;
import static org.neo4j.graphdb.factory.GraphDatabaseSettings.nodestore_mapped_memory_size;
import static org.neo4j.helpers.collection.MapUtil.stringMap;

import java.io.File;

import org.junit.Test;
import org.neo4j.kernel.DefaultFileSystemAbstraction;
import org.neo4j.kernel.DefaultIdGeneratorFactory;
import org.neo4j.kernel.DefaultLastCommittedTxIdSetter;
import org.neo4j.kernel.DefaultTxHook;
import org.neo4j.kernel.configuration.Config;
import org.neo4j.kernel.configuration.ConfigurationDefaults;
import org.neo4j.kernel.impl.util.StringLogger;
import org.neo4j.test.TargetDirectory;

public class TestGrowingFileMemoryMapping
{
private static final int MEGA = 1024 * 1024;

@Test
public void shouldGrowAFileWhileContinuingToMemoryMapNewRegions() throws Exception
{
// given
int NUMBER_OF_RECORDS = 1000000;

File storeDir = TargetDirectory.forTest( getClass() ).graphDbDir( true );
Config config = new Config( new ConfigurationDefaults( NodeStore.Configuration.class ).apply( stringMap(
nodestore_mapped_memory_size.name(), mmapSize( NUMBER_OF_RECORDS, NodeStore.RECORD_SIZE ),
NodeStore.Configuration.use_memory_mapped_buffers.name(), "true",
NodeStore.Configuration.store_dir.name(), storeDir.getPath(),
NodeStore.Configuration.neo_store.name(), new File( storeDir, NeoStore.DEFAULT_NAME ).getPath()
) ) );
DefaultIdGeneratorFactory idGeneratorFactory = new DefaultIdGeneratorFactory();
StoreFactory storeFactory = new StoreFactory( config, idGeneratorFactory,
new DefaultFileSystemAbstraction(),
new DefaultLastCommittedTxIdSetter(), StringLogger.SYSTEM, new DefaultTxHook() );

String fileName = new File( storeDir, NeoStore.DEFAULT_NAME + ".nodestore.db" ).getPath();
storeFactory.createEmptyStore( fileName, storeFactory.buildTypeDescriptorAndVersion(
NodeStore.TYPE_DESCRIPTOR ) );

NodeStore nodeStore = new NodeStore( fileName, config, idGeneratorFactory,
new DefaultFileSystemAbstraction(), StringLogger.SYSTEM );

// when
for ( int i = 0; i < 2 * NUMBER_OF_RECORDS; i++ )
{
NodeRecord record = new NodeRecord( nodeStore.nextId(), 0, 0 );
record.setInUse( true );
nodeStore.updateRecord( record );
}

// then
WindowPoolStats stats = nodeStore.getWindowPoolStats();

nodeStore.close();

assertEquals( stats.toString(), 0, stats.getMissCount() );
}

private String mmapSize( int numberOfRecords, int recordSize )
{
int bytes = numberOfRecords * recordSize;
if (bytes < MEGA) {
throw new IllegalArgumentException( "too few records: " + numberOfRecords );
}
return bytes / MEGA + "M";
}
}

0 comments on commit d73555a

Please sign in to comment.