/*
 * Copyright 2012 LMAX Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lmax.disruptor;

import com.lmax.disruptor.util.Util;

import sun.misc.Unsafe;

/**
 * <p>Concurrent sequence class used for tracking the progress of
 * the ring buffer and event processors.  Support a number
 * of concurrent operations including CAS and order writes.
 *
 * <p>Also attempts to be more efficient with regards to false
 * sharing by adding padding around the volatile field.
 */
public class Sequence
{
    static final long INITIAL_VALUE = -1L;
    private static final Unsafe UNSAFE;
    private static final long VALUE_OFFSET;

    static
    {
        UNSAFE = Util.getUnsafe();
        final int base = UNSAFE.arrayBaseOffset(long[].class);
        final int scale = UNSAFE.arrayIndexScale(long[].class);
        VALUE_OFFSET = base + (scale * 7);
    }

    private final long[] paddedValue = new long[15];

    /**
     * Create a sequence initialised to -1.
     */
    public Sequence()
    {
        this(INITIAL_VALUE);
    }

    /**
     * Create a sequence with a specified initial value.
     *
     * @param initialValue The initial value for this sequence.
     */
    public Sequence(final long initialValue)
    {
        UNSAFE.putOrderedLong(paddedValue, VALUE_OFFSET, initialValue);
    }

    /**
     * Perform a volatile read of this sequence's value.
     *
     * @return The current value of the sequence.
     */
    public long get()
    {
        return UNSAFE.getLongVolatile(paddedValue, VALUE_OFFSET);
    }

    /**
     * Perform an ordered write of this sequence.  The intent is
     * a Store/Store barrier between this write and any previous
     * store.
     *
     * @param value The new value for the sequence.
     */
    public void set(final long value)
    {
        UNSAFE.putOrderedLong(paddedValue, VALUE_OFFSET, value);
    }

    /**
     * Performs a volatile write of this sequence.  The intent is
     * a Store/Store barrier between this write and any previous
     * write and a Store/Load barrier between this write and any
     * subsequent volatile read.
     *
     * @param value The new value for the sequence.
     */
    public void setVolatile(final long value)
    {
        UNSAFE.putLongVolatile(paddedValue, VALUE_OFFSET, value);
    }

    /**
     * Perform a compare and set operation on the sequence.
     *
     * @param expectedValue The expected current value.
     * @param newValue The value to update to.
     * @return true if the operation succeeds, false otherwise.
     */
    public boolean compareAndSet(final long expectedValue, final long newValue)
    {
        return UNSAFE.compareAndSwapLong(paddedValue, VALUE_OFFSET, expectedValue, newValue);
    }

    /**
     * Atomically increment the sequence by one.
     *
     * @return The value after the increment
     */
    public long incrementAndGet()
    {
        return addAndGet(1L);
    }

    /**
     * Atomically add the supplied value.
     *
     * @param increment The value to add to the sequence.
     * @return The value after the increment.
     */
    public long addAndGet(final long increment)
    {
        long currentValue;
        long newValue;

        do
        {
            currentValue = get();
            newValue = currentValue + increment;
        }
        while (!compareAndSet(currentValue, newValue));

        return newValue;
    }

    public String toString()
    {
        return Long.toString(get());
    }
}

@@ -611,16 +611,41 @@
 uptor;%0A%0A
+import sun.misc.Unsafe;%0A%0A
 import c
@@ -674,39 +674,244 @@
 .Util;%0A%0A
-import sun.misc.Unsafe;
+%0Aclass LhsPadding%0A%7B%0A    protected long p1, p2, p3, p4, p5, p6, p7;%0A%7D%0A%0Aclass Value extends LhsPadding%0A%7B%0A    protected volatile long value;%0A%7D%0A%0Aclass RhsPadding extends Value%0A%7B%0A    protected long p9, p10, p11, p12, p13, p14, p15;%0A%7D
 %0A%0A/**%0A *
@@ -1240,16 +1240,35 @@
 Sequence
+ extends RhsPadding
 %0A%7B%0A    s
@@ -1454,229 +1454,220 @@
     
-final int base = UNSAFE.arrayBaseOffset(long%5B%5D.class);%0A        final int scale = UNSAFE.arrayIndexScale(long%5B%5D.class);%0A        VALUE_OFFSET = base + (scale * 7);%0A    %7D%0A%0A    private final long%5B%5D paddedValue = new long%5B15%5D;
+try%0A        %7B%0A            VALUE_OFFSET = UNSAFE.objectFieldOffset(Value.class.getDeclaredField(%22value%22));%0A        %7D%0A        catch (Exception e)%0A        %7B%0A            throw new RuntimeException(e);%0A        %7D%0A    %7D
 %0A%0A  
@@ -2009,35 +2009,28 @@
 OrderedLong(
-paddedValue
+this
 , VALUE_OFFS
@@ -2247,35 +2247,28 @@
 ongVolatile(
-paddedValue
+this
 , VALUE_OFFS
@@ -2568,35 +2568,28 @@
 OrderedLong(
-paddedValue
+this
 , VALUE_OFFS
@@ -2994,27 +2994,20 @@
 olatile(
-paddedValue
+this
 , VALUE_
@@ -3410,19 +3410,12 @@
 ong(
-paddedValue
+this
 , VA
@@ -4126,24 +4126,38 @@
 lue;%0A    %7D%0A%0A
+    @Override%0A
     public S

Use inheritence based field padding