aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/util/EclipseCollectionsLongMultiset.java
blob: 88773c5dbc2097c3b3c218cda6dd6b0a97496eda (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*******************************************************************************
 * Copyright (c) 2010-2018, Gabor Bergmann, IncQueryLabs Ltd.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-v20.html.
 * 
 * SPDX-License-Identifier: EPL-2.0
 *******************************************************************************/
package tools.refinery.viatra.runtime.matchers.util;

import java.util.Iterator;
import java.util.Set;
import java.util.function.BiConsumer;

import org.eclipse.collections.impl.map.mutable.primitive.LongIntHashMap;

/**
 * @author Gabor Bergmann
 * @since 2.0
 * <p> TODO refactor common methods with {@link EclipseCollectionsMultiset}
 * <p> TODO refactor into LongBagMemory etc.
 */
public class EclipseCollectionsLongMultiset extends LongIntHashMap implements IMultiset<Long> {

    @Override
    public boolean addOne(Long value) {
        int oldCount = super.getIfAbsent(value, 0);

        super.put(value, oldCount + 1);

        return oldCount == 0;
    }

    @Override
    public boolean addSigned(Long value, int count) {
        int oldCount = super.getIfAbsent(value, 0);
        int newCount = oldCount + count;
        
        boolean becomesZero = newCount == 0;
        if (newCount < 0)
            throw new IllegalStateException(String.format(
                    "Cannot remove %d occurrences of value '%s' as only %d would remain in %s", 
                    count, value, newCount, this));
        else if (becomesZero)
            super.removeKey(value);
        else // (newCount > 0)
            super.put(value, newCount);
       
        return becomesZero || oldCount == 0;
    }

    @Override
    public boolean removeOne(Long value) {
        return removeOneInternal(value, true);
    }
    /**
     * @since 2.3
     */
    @Override
    public boolean removeOneOrNop(Long value) {
        return removeOneInternal(value, false);
    }
    
    
    /**
     * @since 2.3
     */
    protected boolean removeOneInternal(Long value, boolean throwIfImpossible) {
        int oldCount = super.getIfAbsent(value, 0);
        if (oldCount == 0) {
            if (throwIfImpossible) throw new IllegalStateException(String.format(
                    "Cannot remove value '%s' that is not contained in %s", 
                    value, this));
            else return false;
        }
        
        int rest = oldCount - 1;
        boolean empty = rest == 0;

        if (!empty) {
            super.put(value, rest);
        } else {
            super.remove(value);
        }

        return empty;
    }

    @Override
    public void clearAllOf(Long value) {
        super.remove(value);
    }

    @Override
    public int getCount(Long value) {
        return super.getIfAbsent(value, 0);
    }
    @Override
    public int getCountUnsafe(Object value) {
        return value instanceof Long ? getCount((Long) value) : 0;
    }

    @Override
    public boolean containsNonZero(Long value) {
        return super.containsKey(value);
    }
    
    @Override
    public boolean containsNonZeroUnsafe(Object value) {
        return value instanceof Long && containsNonZero((Long) value);
    }

    @Override
    public Iterator<Long> iterator() {
        return EclipseCollectionsLongSetMemory.iteratorOf(super.keySet());
    }

    @Override
    public boolean addPositive(Long value, int count) {
        if (count < 0) {
            throw new IllegalArgumentException("The count value must be positive!");
        }

        int oldCount = super.getIfAbsent(value, 0);

        super.put(value, oldCount + count);

        return oldCount == 0;
    }

    @Override
    public Set<Long> distinctValues() {
        return new EclipseCollectionsLongSetMemory.SetWrapper(super.keySet());
    }

    @Override
    public void forEachEntryWithMultiplicities(BiConsumer<Long, Integer> entryConsumer) {
        super.forEachKeyValue(entryConsumer::accept);
    }
    
    @Override
    public int hashCode() {
        return IMemoryView.hashCode(this);
    }
    @Override
    public boolean equals(Object obj) {
        return IMemoryView.equals(this, obj);
    }

}