/**
* Copyright (c) 2002-2013 "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 java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* PropertyRecord is a container for PropertyBlocks. PropertyRecords form
* a double linked list and each one holds one or more PropertyBlocks that
* are the actual property key/value pairs. Because PropertyBlocks are of
* variable length, a full PropertyRecord can be holding just one
* PropertyBlock.
*/
public class PropertyRecord extends Abstract64BitRecord
{
private long nextProp = Record.NO_NEXT_PROPERTY.intValue();
private long prevProp = Record.NO_PREVIOUS_PROPERTY.intValue();
private final List<PropertyBlock> blockRecords = new ArrayList<PropertyBlock>(
4 );
private long entityId = -1;
private boolean nodeIdSet;
private boolean isChanged;
private final List<DynamicRecord> deletedRecords = new LinkedList<DynamicRecord>();
public PropertyRecord( long id )
{
super( id );
}
public void setNodeId( long nodeId )
{
nodeIdSet = true;
entityId = nodeId;
}
public void setRelId( long relId )
{
nodeIdSet = false;
entityId = relId;
}
public long getNodeId()
{
if ( nodeIdSet )
{
return entityId;
}
return -1;
}
public long getRelId()
{
if ( !nodeIdSet )
{
return entityId;
}
return -1;
}
/**
* Gets the sum of the sizes of the blocks in this record, in bytes.
*
* @return
*/
public int size()
{
int result = 0;
for ( PropertyBlock block : blockRecords )
{
result += block.getSize();
}
return result;
}
public List<PropertyBlock> getPropertyBlocks()
{
return blockRecords;
}
public List<DynamicRecord> getDeletedRecords()
{
return deletedRecords;
}
public void addDeletedRecord( DynamicRecord record )
{
deletedRecords.add( record );
}
public void addPropertyBlock(PropertyBlock block)
{
assert size() + block.getSize() <= PropertyType.getPayloadSize() :
("Exceeded capacity of property record " + this
+ ". My current size is reported as " + size() + "The added block was " + block + " (note that size is "
+ block.getSize() + ")"
);
blockRecords.add( block );
}
public PropertyBlock getPropertyBlock( int keyIndex )
{
for ( PropertyBlock block : blockRecords )
{
if ( block.getKeyIndexId() == keyIndex )
{
return block;
}
}
return null;
}
public PropertyBlock removePropertyBlock( int keyIndex )
{
for ( int i = 0; i < blockRecords.size(); i++ )
{
if ( blockRecords.get( i ).getKeyIndexId() == keyIndex )
{
return blockRecords.remove( i );
}
}
return null;
}
public long getNextProp()
{
return nextProp;
}
public void setNextProp( long nextProp )
{
this.nextProp = nextProp;
}
@Override
public String toString()
{
StringBuffer buf = new StringBuffer();
buf.append( "PropertyRecord[" ).append( getId() ).append( "," ).append(
inUse() ).append( "," ).append( prevProp ).append( "," ).append(
nextProp ).append( ", Value[" );
Iterator<PropertyBlock> itr = blockRecords.iterator();
while ( itr.hasNext() )
{
buf.append( itr.next() );
if ( itr.hasNext() )
{
buf.append( ", " );
}
}
buf.append( "], DeletedDynRecs[" );
if ( !deletedRecords.isEmpty() )
{
Iterator<DynamicRecord> it = deletedRecords.iterator();
while ( it.hasNext() )
{
buf.append( it.next() );
if ( it.hasNext() )
{
buf.append( ", " );
}
}
}
buf.append( "]]" );
return buf.toString();
}
public boolean isChanged()
{
return isChanged;
}
public void setChanged()
{
isChanged = true;
}
public long getPrevProp()
{
return prevProp;
}
public void setPrevProp( long prev )
{
prevProp = prev;
}
}