aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/memories/timely/TimelyUnaryMaskedTupleMemory.java
blob: 178193af409d7b43722dee26ea57f05f63a19ebb (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
/*******************************************************************************
 * Copyright (c) 2010-2018, Gabor Bergmann, IncQuery Labs 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.memories.timely;

import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import tools.refinery.viatra.runtime.matchers.tuple.ITuple;
import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
import tools.refinery.viatra.runtime.matchers.tuple.TupleMask;
import tools.refinery.viatra.runtime.matchers.tuple.Tuples;
import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory;
import tools.refinery.viatra.runtime.matchers.util.TimelyMemory;
import tools.refinery.viatra.runtime.matchers.util.timeline.Diff;
import tools.refinery.viatra.runtime.matchers.util.timeline.Timeline;

/**
 * Timely specialization for unary mask. 
 * 
 * @author Tamas Szabo
 * @since 2.3
 */
public final class TimelyUnaryMaskedTupleMemory<Timestamp extends Comparable<Timestamp>>
        extends AbstractTimelyMaskedMemory<Timestamp, Object> {

    protected final int keyPosition;

    public TimelyUnaryMaskedTupleMemory(final TupleMask mask, final Object owner, final boolean isLazy) {
        super(mask, owner, isLazy);
        if (1 != mask.getSize())
            throw new IllegalArgumentException(mask.toString());
        this.keyPosition = mask.indices[0];
    }

    @Override
    public Iterable<Tuple> getSignatures() {
        return () -> {
            final Iterator<Object> wrapped = this.memoryMap.keySet().iterator();
            return new Iterator<Tuple>() {
                @Override
                public boolean hasNext() {
                    return wrapped.hasNext();
                }

                @Override
                public Tuple next() {
                    final Object key = wrapped.next();
                    return Tuples.staticArityFlatTupleOf(key);
                }
            };
        };
    }

    @Override
    public Diff<Timestamp> removeWithTimestamp(final Tuple tuple, final Tuple signature, final Timestamp timestamp) {
        final Object key = tuple.get(keyPosition);
        return removeInternal(key, tuple, timestamp);
    }

    @Override
    public Diff<Timestamp> addWithTimestamp(final Tuple tuple, final Tuple signature, final Timestamp timestamp) {
        final Object key = tuple.get(keyPosition);
        return addInternal(key, tuple, timestamp);
    }

    @Override
    public Collection<Tuple> get(final ITuple signature) {
        return getInternal(signature.get(0));
    }

    @Override
    public Map<Tuple, Timeline<Timestamp>> getWithTimeline(final ITuple signature) {
        return getWithTimestampInternal(signature.get(0));
    }

    @Override
    public boolean isPresentAtInfinity(ITuple signature) {
        return isPresentAtInfinityInteral(signature.get(0));
    }

    @Override
    public Iterable<Tuple> getResumableSignatures() {
        if (this.foldingStates == null || this.foldingStates.isEmpty()) {
            return Collections.emptySet();
        } else {
            return () -> {
                final Iterator<Object> wrapped = this.foldingStates.firstEntry().getValue().iterator();
                return new Iterator<Tuple>() {
                    @Override
                    public boolean hasNext() {
                        return wrapped.hasNext();
                    }

                    @Override
                    public Tuple next() {
                        final Object key = wrapped.next();
                        return Tuples.staticArityFlatTupleOf(key);
                    }
                };
            };
        }
    }

    @Override
    public Map<Tuple, Map<Tuple, Diff<Timestamp>>> resumeAt(final Timestamp timestamp) {
        final Map<Tuple, Map<Tuple, Diff<Timestamp>>> result = CollectionsFactory.createMap();
        final Timestamp resumableTimestamp = this.getResumableTimestamp();
        if (resumableTimestamp == null) {
            throw new IllegalStateException("There is nothing to fold!");
        } else if (resumableTimestamp.compareTo(timestamp) != 0) {
            throw new IllegalStateException("Expected to continue folding at " + resumableTimestamp + "!");
        }
        
        final Set<Object> signatures = this.foldingStates.remove(timestamp);
        for (final Object signature : signatures) {
            final TimelyMemory<Timestamp> memory = this.memoryMap.get(signature);
            final Map<Tuple, Diff<Timestamp>> diffMap = memory.resumeAt(resumableTimestamp);
            result.put(Tuples.staticArityFlatTupleOf(signature), diffMap);
            registerFoldingState(memory.getResumableTimestamp(), signature);
        }
        return result;
    }

}