blob: a8023933c6c94c3372216e6877e33de760874063 [file] [log] [blame]
Jordan Halterman2bf177c2017-06-29 01:49:08 -07001/*
2 * Copyright 2017-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.store.primitives.resources.impl;
17
18import java.util.Objects;
19
20import io.atomix.protocols.raft.service.AbstractRaftService;
21import io.atomix.protocols.raft.service.Commit;
22import io.atomix.protocols.raft.service.RaftServiceExecutor;
23import io.atomix.protocols.raft.storage.snapshot.SnapshotReader;
24import io.atomix.protocols.raft.storage.snapshot.SnapshotWriter;
25import org.onlab.util.KryoNamespace;
26import org.onosproject.store.serializers.KryoNamespaces;
27import org.onosproject.store.service.Serializer;
28
29import static org.onosproject.store.primitives.resources.impl.AtomixCounterOperations.ADD_AND_GET;
30import static org.onosproject.store.primitives.resources.impl.AtomixCounterOperations.AddAndGet;
31import static org.onosproject.store.primitives.resources.impl.AtomixCounterOperations.COMPARE_AND_SET;
32import static org.onosproject.store.primitives.resources.impl.AtomixCounterOperations.CompareAndSet;
33import static org.onosproject.store.primitives.resources.impl.AtomixCounterOperations.GET;
34import static org.onosproject.store.primitives.resources.impl.AtomixCounterOperations.GET_AND_ADD;
35import static org.onosproject.store.primitives.resources.impl.AtomixCounterOperations.GET_AND_INCREMENT;
36import static org.onosproject.store.primitives.resources.impl.AtomixCounterOperations.GetAndAdd;
37import static org.onosproject.store.primitives.resources.impl.AtomixCounterOperations.INCREMENT_AND_GET;
38import static org.onosproject.store.primitives.resources.impl.AtomixCounterOperations.SET;
39import static org.onosproject.store.primitives.resources.impl.AtomixCounterOperations.Set;
40
41/**
42 * Atomix long state.
43 */
44public class AtomixCounterService extends AbstractRaftService {
45 private static final Serializer SERIALIZER = Serializer.using(KryoNamespace.newBuilder()
46 .register(KryoNamespaces.BASIC)
47 .register(AtomixCounterOperations.NAMESPACE)
48 .build());
49
50 private Long value = 0L;
51
52 @Override
53 protected void configure(RaftServiceExecutor executor) {
54 executor.register(SET, SERIALIZER::decode, this::set);
55 executor.register(GET, this::get, SERIALIZER::encode);
56 executor.register(COMPARE_AND_SET, SERIALIZER::decode, this::compareAndSet, SERIALIZER::encode);
57 executor.register(INCREMENT_AND_GET, this::incrementAndGet, SERIALIZER::encode);
58 executor.register(GET_AND_INCREMENT, this::getAndIncrement, SERIALIZER::encode);
59 executor.register(ADD_AND_GET, SERIALIZER::decode, this::addAndGet, SERIALIZER::encode);
60 executor.register(GET_AND_ADD, SERIALIZER::decode, this::getAndAdd, SERIALIZER::encode);
61 }
62
63 @Override
64 public void snapshot(SnapshotWriter writer) {
65 writer.writeLong(value);
66 }
67
68 @Override
69 public void install(SnapshotReader reader) {
70 value = reader.readLong();
71 }
72
73 /**
74 * Handles a set commit.
75 *
76 * @param commit the commit to handle
77 */
78 protected void set(Commit<Set> commit) {
79 value = commit.value().value();
80 }
81
82 /**
83 * Handles a get commit.
84 *
85 * @param commit the commit to handle
86 * @return counter value
87 */
88 protected Long get(Commit<Void> commit) {
89 return value;
90 }
91
92 /**
93 * Handles a compare and set commit.
94 *
95 * @param commit the commit to handle
96 * @return counter value
97 */
98 protected boolean compareAndSet(Commit<CompareAndSet> commit) {
99 if (Objects.equals(value, commit.value().expect())) {
100 value = commit.value().update();
101 return true;
102 }
103 return false;
104 }
105
106 /**
107 * Handles an increment and get commit.
108 *
109 * @param commit the commit to handle
110 * @return counter value
111 */
112 protected long incrementAndGet(Commit<Void> commit) {
113 Long oldValue = value;
114 value = oldValue + 1;
115 return value;
116 }
117
118 /**
119 * Handles a get and increment commit.
120 *
121 * @param commit the commit to handle
122 * @return counter value
123 */
124 protected long getAndIncrement(Commit<Void> commit) {
125 Long oldValue = value;
126 value = oldValue + 1;
127 return oldValue;
128 }
129
130 /**
131 * Handles an add and get commit.
132 *
133 * @param commit the commit to handle
134 * @return counter value
135 */
136 protected long addAndGet(Commit<AddAndGet> commit) {
137 Long oldValue = value;
138 value = oldValue + commit.value().delta();
139 return value;
140 }
141
142 /**
143 * Handles a get and add commit.
144 *
145 * @param commit the commit to handle
146 * @return counter value
147 */
148 protected long getAndAdd(Commit<GetAndAdd> commit) {
149 Long oldValue = value;
150 value = oldValue + commit.value().delta();
151 return oldValue;
152 }
153}