Search in sources :

Example 1 with GridLongList

use of org.apache.ignite.internal.util.GridLongList in project ignite by apache.

the class PagesList method init.

/**
     * @param metaPageId Metadata page ID.
     * @param initNew {@code True} if new list if created, {@code false} if should be initialized from metadata.
     * @throws IgniteCheckedException If failed.
     */
protected final void init(long metaPageId, boolean initNew) throws IgniteCheckedException {
    if (metaPageId != 0L) {
        if (initNew) {
            init(metaPageId, PagesListMetaIO.VERSIONS.latest());
        } else {
            Map<Integer, GridLongList> bucketsData = new HashMap<>();
            long nextId = metaPageId;
            while (nextId != 0) {
                final long pageId = nextId;
                final long page = acquirePage(pageId);
                try {
                    // No concurrent recycling on init.
                    long pageAddr = readLock(pageId, page);
                    assert pageAddr != 0L;
                    try {
                        PagesListMetaIO io = PagesListMetaIO.VERSIONS.forPage(pageAddr);
                        io.getBucketsData(pageAddr, bucketsData);
                        nextId = io.getNextMetaPageId(pageAddr);
                        assert nextId != pageId : "Loop detected [next=" + U.hexLong(nextId) + ", cur=" + U.hexLong(pageId) + ']';
                    } finally {
                        readUnlock(pageId, page, pageAddr);
                    }
                } finally {
                    releasePage(pageId, page);
                }
            }
            for (Map.Entry<Integer, GridLongList> e : bucketsData.entrySet()) {
                int bucket = e.getKey();
                long bucketSize = 0;
                Stripe[] old = getBucket(bucket);
                assert old == null;
                long[] upd = e.getValue().array();
                Stripe[] tails = new Stripe[upd.length];
                for (int i = 0; i < upd.length; i++) {
                    long tailId = upd[i];
                    long prevId = tailId;
                    int cnt = 0;
                    while (prevId != 0L) {
                        final long pageId = prevId;
                        final long page = acquirePage(pageId);
                        try {
                            long pageAddr = readLock(pageId, page);
                            assert pageAddr != 0L;
                            try {
                                PagesListNodeIO io = PagesListNodeIO.VERSIONS.forPage(pageAddr);
                                cnt += io.getCount(pageAddr);
                                prevId = io.getPreviousId(pageAddr);
                                // In reuse bucket the page itself can be used as a free page.
                                if (isReuseBucket(bucket) && prevId != 0L)
                                    cnt++;
                            } finally {
                                readUnlock(pageId, page, pageAddr);
                            }
                        } finally {
                            releasePage(pageId, page);
                        }
                    }
                    Stripe stripe = new Stripe(tailId, cnt == 0);
                    tails[i] = stripe;
                    bucketSize += cnt;
                }
                boolean ok = casBucket(bucket, null, tails);
                assert ok;
                bucketsSize[bucket].set(bucketSize);
            }
        }
    }
}
Also used : HashMap(java.util.HashMap) PagesListMetaIO(org.apache.ignite.internal.processors.cache.database.freelist.io.PagesListMetaIO) GridLongList(org.apache.ignite.internal.util.GridLongList) PagesListNodeIO(org.apache.ignite.internal.processors.cache.database.freelist.io.PagesListNodeIO) HashMap(java.util.HashMap) Map(java.util.Map)

Example 2 with GridLongList

use of org.apache.ignite.internal.util.GridLongList in project ignite by apache.

the class HadoopConcurrentHashMultimap method rehashIfNeeded.

/**
 * @param fromTbl Table.
 */
private void rehashIfNeeded(AtomicLongArray fromTbl) {
    if (fromTbl.length() == Integer.MAX_VALUE)
        return;
    long keys0 = keys();
    if (// New size has to be >= than 3/4 of capacity to rehash.
    keys0 < 3 * (fromTbl.length() >>> 2))
        return;
    if (// Check if someone else have done the job.
    fromTbl != newTbl)
        return;
    if (!state.compareAndSet(State.READING_WRITING, State.REHASHING)) {
        // Visiting is allowed, but we will not rehash.
        assert state.get() != State.CLOSING;
        return;
    }
    if (fromTbl != newTbl) {
        // Double check.
        // Switch back.
        state(State.REHASHING, State.READING_WRITING);
        return;
    }
    // Calculate new table capacity.
    int newLen = fromTbl.length();
    do {
        newLen <<= 1;
    } while (newLen < keys0);
    if (// Still more than 3/4.
    keys0 >= 3 * (newLen >>> 2))
        newLen <<= 1;
    // This is our target table for rehashing.
    AtomicLongArray toTbl = new AtomicLongArray(newLen);
    // Make the new table visible before rehashing.
    newTbl = toTbl;
    // Rehash.
    int newMask = newLen - 1;
    long failedMeta = 0;
    GridLongList collisions = new GridLongList(16);
    for (int i = 0; i < fromTbl.length(); i++) {
        // Scan source table.
        long meta = fromTbl.get(i);
        assert meta != -1;
        if (meta == 0) {
            // No entry.
            failedMeta = 0;
            if (// Mark as moved.
            !fromTbl.compareAndSet(i, 0, -1))
                // Retry.
                i--;
            continue;
        }
        do {
            // Collect all the collisions before the last one failed to nullify or 0.
            collisions.add(meta);
            meta = collision(meta);
        } while (meta != failedMeta);
        do {
            // Go from the last to the first to avoid 'in-flight' state for meta entries.
            meta = collisions.remove();
            int addr = keyHash(meta) & newMask;
            for (; ; ) {
                // Move meta entry to the new table.
                long toCollision = toTbl.get(addr);
                collision(meta, toCollision);
                if (toTbl.compareAndSet(addr, toCollision, meta))
                    break;
            }
        } while (!collisions.isEmpty());
        // Here 'meta' will be a root pointer in old table.
        if (!fromTbl.compareAndSet(i, meta, -1)) {
            // Try to mark as moved.
            failedMeta = meta;
            // Retry the same address in table because new keys were added.
            i--;
        } else
            failedMeta = 0;
    }
    // Now old and new tables will be the same again.
    oldTbl = toTbl;
    state(State.REHASHING, State.READING_WRITING);
}
Also used : AtomicLongArray(java.util.concurrent.atomic.AtomicLongArray) GridLongList(org.apache.ignite.internal.util.GridLongList)

Example 3 with GridLongList

use of org.apache.ignite.internal.util.GridLongList in project ignite by apache.

the class GridDhtAtomicUpdateRequest method addWriteValue.

/**
 * {@inheritDoc}
 */
@Override
public void addWriteValue(KeyCacheObject key, @Nullable CacheObject val, EntryProcessor<Object, Object, Object> entryProcessor, long ttl, long conflictExpireTime, @Nullable GridCacheVersion conflictVer, boolean addPrevVal, @Nullable CacheObject prevVal, long updateCntr) {
    assert key.partition() >= 0 : key;
    keys.add(key);
    if (forceTransformBackups) {
        assert entryProcessor != null;
        entryProcessors.add(entryProcessor);
    } else
        vals.add(val);
    if (addPrevVal) {
        if (prevVals == null)
            prevVals = new ArrayList<>();
        prevVals.add(prevVal);
    }
    if (updateCntrs == null)
        updateCntrs = new GridLongList();
    updateCntrs.add(updateCntr);
    // In case there is no conflict, do not create the list.
    if (conflictVer != null) {
        if (conflictVers == null) {
            conflictVers = new ArrayList<>();
            for (int i = 0; i < keys.size() - 1; i++) conflictVers.add(null);
        }
        conflictVers.add(conflictVer);
    } else if (conflictVers != null)
        conflictVers.add(null);
    if (ttl >= 0) {
        if (ttls == null) {
            ttls = new GridLongList(keys.size());
            for (int i = 0; i < keys.size() - 1; i++) ttls.add(CU.TTL_NOT_CHANGED);
        }
    }
    if (ttls != null)
        ttls.add(ttl);
    if (conflictExpireTime >= 0) {
        if (conflictExpireTimes == null) {
            conflictExpireTimes = new GridLongList(keys.size());
            for (int i = 0; i < keys.size() - 1; i++) conflictExpireTimes.add(CU.EXPIRE_TIME_CALCULATE);
        }
    }
    if (conflictExpireTimes != null)
        conflictExpireTimes.add(conflictExpireTime);
}
Also used : ArrayList(java.util.ArrayList) GridLongList(org.apache.ignite.internal.util.GridLongList)

Example 4 with GridLongList

use of org.apache.ignite.internal.util.GridLongList in project ignite by apache.

the class PagesList method putReuseBag.

/**
 * @param pageId Page ID.
 * @param page Page pointer.
 * @param pageAddr Page address.
 * @param io IO.
 * @param bag Reuse bag.
 * @param bucket Bucket.
 * @return {@code true} If succeeded.
 * @throws IgniteCheckedException if failed.
 */
@SuppressWarnings("ForLoopReplaceableByForEach")
private boolean putReuseBag(final long pageId, final long page, final long pageAddr, PagesListNodeIO io, ReuseBag bag, int bucket) throws IgniteCheckedException {
    assert bag != null : "bag is null";
    assert !bag.isEmpty() : "bag is empty";
    if (io.getNextId(pageAddr) != 0L)
        // Splitted.
        return false;
    long nextId;
    long prevId = pageId;
    long prevPage = page;
    long prevAddr = pageAddr;
    Boolean walPlc = null;
    // TODO may be unlock right away and do not keep all these pages locked?
    GridLongList locked = null;
    try {
        while ((nextId = bag.pollFreePage()) != 0L) {
            int idx = io.addPage(prevAddr, nextId, pageSize());
            if (idx == -1) {
                // Attempt to add page failed: the node page is full.
                final long nextPage = acquirePage(nextId);
                try {
                    // Page from reuse bag can't be concurrently recycled.
                    long nextPageAddr = writeLock(nextId, nextPage);
                    assert nextPageAddr != 0L;
                    if (locked == null)
                        locked = new GridLongList(6);
                    locked.add(nextId);
                    locked.add(nextPage);
                    locked.add(nextPageAddr);
                    setupNextPage(io, prevId, prevAddr, nextId, nextPageAddr);
                    if (needWalDeltaRecord(prevId, prevPage, walPlc))
                        wal.log(new PagesListSetNextRecord(grpId, prevId, nextId));
                    // Here we should never write full page, because it is known to be new.
                    if (needWalDeltaRecord(nextId, nextPage, FALSE))
                        wal.log(new PagesListInitNewPageRecord(grpId, nextId, io.getType(), io.getVersion(), nextId, prevId, 0L));
                    // In reuse bucket the page itself can be used as a free page.
                    if (isReuseBucket(bucket))
                        incrementBucketSize(bucket);
                    // Switch to this new page, which is now a part of our list
                    // to add the rest of the bag to the new page.
                    prevAddr = nextPageAddr;
                    prevId = nextId;
                    prevPage = nextPage;
                    // Starting from tis point all wal records are written for reused pages from the bag.
                    // This mean that we use delta records only.
                    walPlc = FALSE;
                } finally {
                    releasePage(nextId, nextPage);
                }
            } else {
                // TODO: use single WAL record for bag?
                if (needWalDeltaRecord(prevId, prevPage, walPlc))
                    wal.log(new PagesListAddPageRecord(grpId, prevId, nextId));
                incrementBucketSize(bucket);
            }
        }
    } finally {
        if (locked != null) {
            // We have to update our bucket with the new tail.
            updateTail(bucket, pageId, prevId);
            // Release write.
            for (int i = 0; i < locked.size(); i += 3) writeUnlock(locked.get(i), locked.get(i + 1), locked.get(i + 2), FALSE, true);
        }
    }
    return true;
}
Also used : PagesListAddPageRecord(org.apache.ignite.internal.pagemem.wal.record.delta.PagesListAddPageRecord) GridLongList(org.apache.ignite.internal.util.GridLongList) PagesListSetNextRecord(org.apache.ignite.internal.pagemem.wal.record.delta.PagesListSetNextRecord) PagesListInitNewPageRecord(org.apache.ignite.internal.pagemem.wal.record.delta.PagesListInitNewPageRecord)

Example 5 with GridLongList

use of org.apache.ignite.internal.util.GridLongList in project ignite by apache.

the class CacheGroupAffinityMessage method createAssigns.

/**
 */
private List<GridLongList> createAssigns(List<List<ClusterNode>> assign0) {
    if (assign0 != null) {
        List<GridLongList> assigns = new ArrayList<>(assign0.size());
        for (int i = 0; i < assign0.size(); i++) {
            List<ClusterNode> nodes = assign0.get(i);
            GridLongList l = new GridLongList(nodes.size());
            for (int n = 0; n < nodes.size(); n++) l.add(nodes.get(n).order());
            assigns.add(l);
        }
        return assigns;
    }
    return null;
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) GridLongList(org.apache.ignite.internal.util.GridLongList) ArrayList(java.util.ArrayList)

Aggregations

GridLongList (org.apache.ignite.internal.util.GridLongList)39 Test (org.junit.Test)11 ArrayList (java.util.ArrayList)7 HashMap (java.util.HashMap)6 ByteBuffer (java.nio.ByteBuffer)5 DirectMessageWriter (org.apache.ignite.internal.direct.DirectMessageWriter)5 MessageWriter (org.apache.ignite.plugin.extensions.communication.MessageWriter)5 Map (java.util.Map)4 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)4 ClusterNode (org.apache.ignite.cluster.ClusterNode)4 IgniteException (org.apache.ignite.IgniteException)3 PagesListAddPageRecord (org.apache.ignite.internal.pagemem.wal.record.delta.PagesListAddPageRecord)3 PagesListInitNewPageRecord (org.apache.ignite.internal.pagemem.wal.record.delta.PagesListInitNewPageRecord)3 PagesListSetNextRecord (org.apache.ignite.internal.pagemem.wal.record.delta.PagesListSetNextRecord)3 LinkedHashMap (java.util.LinkedHashMap)2 List (java.util.List)2 TreeMap (java.util.TreeMap)2 UUID (java.util.UUID)2 AtomicLong (java.util.concurrent.atomic.AtomicLong)2 PagesListMetaIO (org.apache.ignite.internal.processors.cache.persistence.freelist.io.PagesListMetaIO)2