<commit_before>/**
 * Copyright (c) 2002-2011 "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.storemigration;

import static org.neo4j.kernel.impl.storemigration.LegacyStore.longFromIntAndMod;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.text.MessageFormat;

import org.neo4j.kernel.impl.nioneo.store.Buffer;
import org.neo4j.kernel.impl.nioneo.store.CommonAbstractStore;
import org.neo4j.kernel.impl.nioneo.store.OperationType;
import org.neo4j.kernel.impl.nioneo.store.PersistenceWindow;
import org.neo4j.kernel.impl.nioneo.store.PersistenceWindowPool;
import org.neo4j.kernel.impl.nioneo.store.Record;

public class LegacyPropertyStoreReader
{
    public static final int RECORD_LENGTH = 25;
    private PersistenceWindowPool windowPool;

    public LegacyPropertyStoreReader( String fileName ) throws FileNotFoundException
    {
        FileChannel fileChannel = new RandomAccessFile( fileName, "r" ).getChannel();
        windowPool = new PersistenceWindowPool( fileName,
                RECORD_LENGTH, fileChannel, CommonAbstractStore.calculateMappedMemory( null, fileName ),
                true, true );
    }

    public LegacyPropertyRecord readPropertyRecord( long id ) throws IOException
    {
        PersistenceWindow persistenceWindow = windowPool.acquire( id, OperationType.READ );

        Buffer buffer = persistenceWindow.getOffsettedBuffer( id );

        // [    ,   x] in use
        // [xxxx,    ] high prev prop bits
        long inUseByte = buffer.get();

        boolean inUse = (inUseByte & 0x1) == Record.IN_USE.intValue();
        if ( !inUse )
        {
            throw new IllegalArgumentException( MessageFormat.format( "Record {0} not in use", id ) );
        }
        LegacyPropertyRecord record = new LegacyPropertyRecord( id );

        // [    ,    ][    ,    ][xxxx,xxxx][xxxx,xxxx] type
        // [    ,    ][    ,xxxx][    ,    ][    ,    ] high next prop bits
        long typeInt = buffer.getInt();

        record.setType( getEnumType( (int) typeInt & 0xFFFF ) );
        record.setInUse( true );
        record.setKeyIndexId( buffer.getInt() );
        record.setPropBlock( buffer.getLong() );

        long prevProp = buffer.getUnsignedInt();
        long prevModifier = (inUseByte & 0xF0L) << 28;
        long nextProp = buffer.getUnsignedInt();
        long nextModifier = (typeInt & 0xF0000L) << 16;

        record.setPrevProp( longFromIntAndMod( prevProp, prevModifier ) );
        record.setNextProp( longFromIntAndMod( nextProp, nextModifier ) );

        return record;
    }

    private LegacyPropertyType getEnumType( int type )
    {
        return LegacyPropertyType.getPropertyType( type, false );
    }

}<commit_msg>Releases the PersistenceWindow to the pool after getRecord to prevent memory leaks<commit_after>/**
 * Copyright (c) 2002-2011 "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.storemigration;

import static org.neo4j.kernel.impl.storemigration.LegacyStore.longFromIntAndMod;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.text.MessageFormat;

import org.neo4j.kernel.impl.nioneo.store.Buffer;
import org.neo4j.kernel.impl.nioneo.store.CommonAbstractStore;
import org.neo4j.kernel.impl.nioneo.store.OperationType;
import org.neo4j.kernel.impl.nioneo.store.PersistenceWindow;
import org.neo4j.kernel.impl.nioneo.store.PersistenceWindowPool;
import org.neo4j.kernel.impl.nioneo.store.Record;

public class LegacyPropertyStoreReader
{
    public static final int RECORD_LENGTH = 25;
    private PersistenceWindowPool windowPool;

    public LegacyPropertyStoreReader( String fileName ) throws FileNotFoundException
    {
        FileChannel fileChannel = new RandomAccessFile( fileName, "r" ).getChannel();
        windowPool = new PersistenceWindowPool( fileName,
                RECORD_LENGTH, fileChannel, CommonAbstractStore.calculateMappedMemory( null, fileName ),
                true, true );
    }

    public LegacyPropertyRecord readPropertyRecord( long id ) throws IOException
    {
        PersistenceWindow persistenceWindow = windowPool.acquire( id, OperationType.READ );
        try
        {
            Buffer buffer = persistenceWindow.getOffsettedBuffer( id );
    
            // [    ,   x] in use
            // [xxxx,    ] high prev prop bits
            long inUseByte = buffer.get();
    
            boolean inUse = (inUseByte & 0x1) == Record.IN_USE.intValue();
            if ( !inUse )
            {
                throw new IllegalArgumentException( MessageFormat.format( "Record {0} not in use", id ) );
            }
            LegacyPropertyRecord record = new LegacyPropertyRecord( id );
    
            // [    ,    ][    ,    ][xxxx,xxxx][xxxx,xxxx] type
            // [    ,    ][    ,xxxx][    ,    ][    ,    ] high next prop bits
            long typeInt = buffer.getInt();
    
            record.setType( getEnumType( (int) typeInt & 0xFFFF ) );
            record.setInUse( true );
            record.setKeyIndexId( buffer.getInt() );
            record.setPropBlock( buffer.getLong() );
    
            long prevProp = buffer.getUnsignedInt();
            long prevModifier = (inUseByte & 0xF0L) << 28;
            long nextProp = buffer.getUnsignedInt();
            long nextModifier = (typeInt & 0xF0000L) << 16;
    
            record.setPrevProp( longFromIntAndMod( prevProp, prevModifier ) );
            record.setNextProp( longFromIntAndMod( nextProp, nextModifier ) );
    
            return record;
        }
        finally
        {
            windowPool.release( persistenceWindow );
        }
    }

    private LegacyPropertyType getEnumType( int type )
    {
        return LegacyPropertyType.getPropertyType( type, false );
    }

}
{'fraction_non_alphanumeric': 0.09131553989974259, 'fraction_numerical': 0.009754775775640157, 'mean_word_length': 2.8387935517420697, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '3115385', 'n_tokens_mistral': 2121, 'n_tokens_neox': 2033, 'n_words': 587}