All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.objectfabric.All Maven / Gradle / Ivy

There is a newer version: 0.9.1
Show newest version
/**
 * This file is part of ObjectFabric (http://objectfabric.org).
 *
 * ObjectFabric is licensed under the Apache License, Version 2.0, the terms
 * of which may be found at http://www.apache.org/licenses/LICENSE-2.0.html.
 * 
 * Copyright ObjectFabric Inc.
 * 
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

package org.objectfabric;

import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;

import org.objectfabric.TObject.Transaction;
import org.objectfabric.TObject.Version;
import org.objectfabric.Workspace.Granularity;
import org.objectfabric.generated.Limit32;
import org.objectfabric.generated.LimitN;
import org.objectfabric.generated.LimitsObjectModel;

@SuppressWarnings({ "unchecked", "rawtypes" })
class All {

    public static final int INCREMENTS = 10;

    final TMap Root;

    final AtomicInteger ListenerCount = new AtomicInteger();

    All(final Resource resource, final int writers, final int flags) {
        LimitsObjectModel.register();

        LimitN limitN = new LimitN(resource);
        Root = new TMap(resource);
        int n = 0;
        Root.put("" + n++, limitN);
        Root.put("" + n++, new Limit32(resource));
        Root.put("" + n++, new TMap(resource));

        // Create arrays using object model to also test .NET
        TType[] type = new TType[] { Immutable.BYTE.type() };
        Root.put("" + n++, Platform.get().defaultObjectModel().createInstance(resource, -LimitN.FIELD_COUNT - 1, type));
        // Object
        Root.put("" + n++, Platform.get().defaultObjectModel().createInstance(resource, -LimitN.FIELD_COUNT - 1, null));
        type = new TType[] { TObject.TYPE };
        Root.put("" + n++, Platform.get().defaultObjectModel().createInstance(resource, -LimitN.FIELD_COUNT - 1, type));

        final int[] last = new int[LimitN.FIELD_COUNT];

        limitN.addListener(new IndexListener() {

            @SuppressWarnings("null")
            @Override
            public void onSet(final int field) {
                resource.atomicRead(new Runnable() {

                    @Override
                    public void run() {
                        check(Root, flags, field, writers == 1 ? last : null);
                        ListenerCount.incrementAndGet();
                    }
                });
            }
        });
    }

    public static int update(TMap root, int flags) {
        int n = 0;
        LimitN limitN = (LimitN) root.get("" + n++);
        Limit32 limit32 = (Limit32) root.get("" + n++);
        TMap map = (TMap) root.get("" + n++);
        TIndexed byteArray = (TIndexed) root.get("" + n++);
        TIndexed objectArray = (TIndexed) root.get("" + n++);
        TIndexed tObjectArray = (TIndexed) root.get("" + n++);

        Workspace workspace = limit32.resource().workspaceImpl();
        ArrayList previous = new ArrayList();

        for (int i = 0; i < INCREMENTS; i++) {
            int index, value;

            for (;;) {
                index = Platform.get().randomInt(LimitN.FIELD_COUNT);

                // To assert increments of 1 when granularity is ALL
                if (!previous.contains(index)) {
                    previous.add(index);
                    break;
                }
            }

            //

            int ref = (Integer) limitN.getField(index);
            limitN.setField(index, ref + 1);

            //

            if (index < Limit32.FIELD_COUNT) {
                value = (Integer) limit32.getField(index);
                Debug.assertAlways(value == ref);
                limit32.setField(index, value + 1);
            }

            //

            value = map.get(index) != null ? map.get(index) : 0;
            Debug.assertAlways(value == ref);
            map.put(index, value + 1);

            //

            value = (Byte) byteArray.getAsObject(index);
            Debug.assertAlways(value == ref);
            byteArray.setAsObject(index, (byte) (value + 1));

            //

            Object boxed = objectArray.getAsObject(index);

            if (boxed instanceof Byte) {
                value = (Byte) boxed;
                Debug.assertAlways(value == ref);
                objectArray.setAsObject(index, value + 1);
            } else
                objectArray.setAsObject(index, 1);

            //

            Limit32 object = (Limit32) tObjectArray.getAsObject(index);

            if (object != null) {
                value = object.int20();
                Debug.assertAlways(value == ref);
                object.int20(value + 1);
                tObjectArray.setAsObject(index, object);
            } else {
                object = new Limit32(tObjectArray.resource());
                object.int20(1);
                tObjectArray.setAsObject(index, object);
            }

            //

            Version[] writes = workspace.transaction().getWrites();
            Bits.Entry[] a = getBits(writes, limitN);
            Bits.Entry[] b = getBits(writes, byteArray);

            if (a != null && b != null)
                Debug.assertAlways(Bits.get(a, index) == Bits.get(b, index));
        }

        int delta = INCREMENTS;

        if ((flags & Multi.FLAG_RESETS) != 0) {
            for (n = 0; n < 3; n++) {
                int index = Platform.get().randomInt(LimitN.FIELD_COUNT);
                int before = (Integer) limitN.getField(index);
                delta -= before;
                limitN.setField(index, 0);

                if (index < Limit32.FIELD_COUNT)
                    limit32.setField(index, 0);

                map.remove(index);
                byteArray.setAsObject(index, (byte) 0);
                objectArray.setAsObject(index, null);
                tObjectArray.setAsObject(index, null);
            }
        }

        return delta;
    }

    public static void check(TMap root, int flags) {
        for (int index = 0; index < LimitN.FIELD_COUNT; index++)
            check(root, flags, index, null);
    }

    public static void check(TMap root, int flags, final int index, int[] last) {
        int n = 0;
        final LimitN limitN = (LimitN) root.get("" + n++);
        final Limit32 limit32 = (Limit32) root.get("" + n++);
        final TMap map = (TMap) root.get("" + n++);
        final TIndexed byteArray = (TIndexed) root.get("" + n++);
        final TIndexed objectArray = (TIndexed) root.get("" + n++);
        final TIndexed tObjectArray = (TIndexed) root.get("" + n++);

        int ref = (Integer) limitN.getField(index);
        final Workspace workspace = limitN.resource().workspaceImpl();

        workspace.atomic(new Runnable() {

            @Override
            public void run() {
                Bits.Entry[] a = getSnapshotBits(workspace.transaction(), limitN);
                Bits.Entry[] b = getSnapshotBits(workspace.transaction(), byteArray);

                if (a != null && b != null) {
                    Debug.assertAlways(a.length == b.length);
                    Debug.assertAlways(Bits.get(a, index) == Bits.get(b, index));
                }
            }
        });

        Debug.assertAlways((Integer) limitN.getField(index) == ref);

        if (index < Limit32.FIELD_COUNT)
            Debug.assertAlways(((Integer) limit32.getField(index)) == ref);

        Debug.assertAlways((map.get(index) != null ? map.get(index) : 0) == ref);
        Debug.assertAlways((Byte) byteArray.getAsObject(index) == ref);

        Object boxed = objectArray.getAsObject(index);

        if (boxed instanceof Byte)
            Debug.assertAlways((Byte) boxed == ref);
        else
            Debug.assertAlways(ref == 0);

        //

        Limit32 object = (Limit32) tObjectArray.getAsObject(index);

        if (object != null)
            Debug.assertAlways(object.int20() == ref);
        else
            Debug.assertAlways(ref == 0);

        //

        if (last != null) {
            if (ref == 0) {
                if (Debug.ENABLED)
                    Debug.assertion((flags & Multi.FLAG_RESETS) != 0);

                last[index] = 0;
            } else
                last[index]++;

            if (workspace.granularity() == Granularity.COALESCE)
                Debug.assertAlways(ref >= last[index]);
            else if (workspace.granularity() == Granularity.ALL)
                Debug.assertAlways(ref == last[index]);
        }
    }

    private static Bits.Entry[] getSnapshotBits(Transaction transaction, TObject object) {
        if (transaction.getSnapshot().writes().length == 2)
            return getBits(transaction.getSnapshot().writes()[1], object);

        return null;
    }

    private static Bits.Entry[] getBits(Version[] versions, TObject object) {
        TIndexedNRead read = null;

        if (versions != null)
            read = (TIndexedNRead) TransactionBase.getVersion(versions, object);

        return read != null ? read.getBits() : null;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy