You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2021/02/17 15:54:01 UTC

[ignite-3] branch ignite-14198 created (now cf15dba)

This is an automated email from the ASF dual-hosted git repository.

agura pushed a change to branch ignite-14198
in repository https://gitbox.apache.org/repos/asf/ignite-3.git.


      at cf15dba  IGNITE-14198 Client interface for metastorage.

This branch includes the following new commits:

     new cf15dba  IGNITE-14198 Client interface for metastorage.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[ignite-3] 01/01: IGNITE-14198 Client interface for metastorage.

Posted by ag...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

agura pushed a commit to branch ignite-14198
in repository https://gitbox.apache.org/repos/asf/ignite-3.git

commit cf15dba2a9206d05246a58a563100126ee23eeca
Author: Andrey Gura <ag...@apache.org>
AuthorDate: Wed Feb 17 18:53:22 2021 +0300

    IGNITE-14198 Client interface for metastorage.
---
 modules/metastorage-client/pom.xml                 |  42 ++++++
 .../metastorage/client/MetaStorageService.java     | 155 ++++++++++++++++++++
 .../ignite/metastorage/client/package-info.java    |  21 +++
 modules/metastorage-common/pom.xml                 |  41 ++++++
 .../metastorage/common/AbstractCondition.java      |  77 ++++++++++
 .../ignite/metastorage/common/Condition.java       |  31 ++++
 .../ignite/metastorage/common/ConditionType.java   |  35 +++++
 .../apache/ignite/metastorage/common/Entry.java    | 162 +++++++++++++++++++++
 .../common/LexicographicComparator.java            |  46 ++++++
 .../ignite/metastorage/common/PutUpdate.java       |  47 ++++++
 .../ignite/metastorage/common/RemoveUpdate.java    |  38 +++++
 .../metastorage/common/RevisionCondition.java      |  48 ++++++
 .../apache/ignite/metastorage/common/Update.java   |  24 +++
 .../ignite/metastorage/common/ValueCondition.java  |  49 +++++++
 .../ignite/metastorage/common/package-info.java    |  21 +++
 pom.xml                                            |   2 +
 16 files changed, 839 insertions(+)

diff --git a/modules/metastorage-client/pom.xml b/modules/metastorage-client/pom.xml
new file mode 100644
index 0000000..0d21c81
--- /dev/null
+++ b/modules/metastorage-client/pom.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.ignite</groupId>
+        <artifactId>ignite-parent</artifactId>
+        <version>1</version>
+        <relativePath>../../parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>metastorage-client</artifactId>
+    <version>3.0.0-SNAPSHOT</version>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>metastorage-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/modules/metastorage-client/src/main/java/org/apache/ignite/metastorage/client/MetaStorageService.java b/modules/metastorage-client/src/main/java/org/apache/ignite/metastorage/client/MetaStorageService.java
new file mode 100644
index 0000000..178f633
--- /dev/null
+++ b/modules/metastorage-client/src/main/java/org/apache/ignite/metastorage/client/MetaStorageService.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.client;
+
+
+import org.apache.ignite.metastorage.common.Condition;
+import org.apache.ignite.metastorage.common.Entry;
+import org.apache.ignite.metastorage.common.Update;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.concurrent.Future;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+/**
+ * Defines interface for access to a metastorage service.
+ */
+public interface MetaStorageService {
+    /**
+     * Returns metastorage revision.
+     *
+     * @return Metastorage revision.
+     */
+    @NotNull
+    Future<Long> revision();
+
+    /**
+     * Updates entry with given key and value.
+     *
+     * @param key Key. Couldn't be {@code null}.
+     * @param value Value.Couldn't be {@code null}.
+     * @return A previous entry which could be regular, empty or tombstone. Couldn't be {@code null}.
+     * @see Entry
+     */
+    @NotNull
+    Future<Entry> put(@NotNull byte[] key, @NotNull byte[] value);
+
+    /**
+     * Retrieves entry with a given key.
+     *
+     * @param key Key. Couldn't be {@code null}.
+     * @return An entry for given key or an empty/tombstone entry. Couldn't be {@code null}.
+     * @see Entry
+     */
+    @NotNull
+    Future<Entry> get(@NotNull byte[] key);
+
+    /**
+     * Retrieves entry with a given key and a revision.
+     *
+     * @param key Key. Couldn't be {@code null}.
+     * @param rev Revision. Must be positive.
+     * @return An entry for given key and a revision or an empty/tombstone entry. Couldn't be {@code null}.
+     * @see Entry
+     */
+    //TODO: Is it really needed???
+    @NotNull
+    Future<Entry> get(@NotNull byte[] key, long rev);
+
+    /**
+     * Removes an entry with a given key.
+     *
+     * @param key Key. Couldn't be {@code null}.
+     * @return A previous entry which could be regular, empty or tombstone. Couldn't be {@code null}.
+     * @see Entry
+     */
+    @NotNull
+    Future<Entry> remove(@NotNull byte[] key);
+
+    /**
+     * Updates entry conditionally.
+     *
+     * @param key Key. Couldn't be {@code null}.
+     * @param condition Condition.
+     * @param success Update which will be applied in case of condition success.
+     * @param failure Update which will be applied in case of condition failure.
+     * @return A previous entry which could be regular, empty or tombstone. Couldn't be {@code null}.
+     * @see Entry
+     */
+    Future<Entry> update(@NotNull byte[] key, Condition condition, Update success, Update failure);
+
+    /**
+     * Updates multiple entries conditionally.
+     *
+     * @param keys List of keys.
+     * @param condition List of conditions corresponding to keys list.
+     * @param success List of updates which will be applied to corresponding key in case of condition success.
+     * @param failure List of updates which will be applied to corresponding key in case of condition failure.
+     * @return A List of previous entries corresponding to list of keys, where each entry could be regular,
+     * empty or tombstone. Couldn't be {@code null}.
+     * @see Entry
+     */
+    // TODO: If I understand correctly, we always use one success and one failure condition for each key in transaction. May be I'm wrong.
+    // TODO: Probably, we should provide no-op conditions also (e.g. for implementation if-then only logic).
+    Future<List<Entry>> update(List<byte[]> keys, List<Condition> condition, List<Update> success, List<Update> failure);
+
+    /**
+     * Retrieves entries for a given key range in lexicographic order.
+     * Only entries with the latest revisions will be returned.
+     *
+     * @param keyFrom Start key of range (inclusive). Couldn't be {@code null}.
+     * @param keyTo End key of range (exclusive). Could be {@code null}.
+     * @param consumer Entry consumer which will be invoked for each entry. Entry couldn't be {@code null}.
+     * @return Future which will be completed when iteration will be finished. Couldn't be {@code null}.
+     */
+    @NotNull
+    Future<Void> iterate(@NotNull byte[] keyFrom, @Nullable byte[] keyTo, @NotNull Consumer<Entry> consumer);
+
+    /**
+     * Creates watcher on metastorage updates with given parameters.
+     *
+     * @param keyFrom Start key of range (inclusive). Could be {@code null}.
+     * @param keyTo End key of range (exclusive). Could be {@code null}.
+     * @param revision Start revision.
+     * @param consumer Entry consumer which will be invoked for each update. Entry couldn't be {@code null}.
+     * @return Watch identifier.
+     */
+    @NotNull
+    Future<Long> watch(@Nullable byte[] keyFrom, @Nullable byte[] keyTo, long revision,
+                       @NotNull BiConsumer<Entry, Entry> consumer);
+
+    /**
+     * Stops watch with a given identifier.
+     *
+     * @param watchId Watch identifier.
+     * @return Completed future in case of operation success. Couldn't be {@code null}.
+     */
+    @NotNull
+    Future<Void> stopWatch(long watchId);
+
+    /**
+     * Compacts metastorage (removes all tombstone entries and old entries except of entries with latest revision).
+     *
+     * @return Completed future. Couldn't be {@code null}.
+     */
+    Future<Void> compact();
+}
+
diff --git a/modules/metastorage-client/src/main/java/org/apache/ignite/metastorage/client/package-info.java b/modules/metastorage-client/src/main/java/org/apache/ignite/metastorage/client/package-info.java
new file mode 100644
index 0000000..b790384
--- /dev/null
+++ b/modules/metastorage-client/src/main/java/org/apache/ignite/metastorage/client/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Defines client interface for access to a metastorage server.
+ */
+package org.apache.ignite.metastorage.client;
\ No newline at end of file
diff --git a/modules/metastorage-common/pom.xml b/modules/metastorage-common/pom.xml
new file mode 100644
index 0000000..cd9e1c6
--- /dev/null
+++ b/modules/metastorage-common/pom.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.ignite</groupId>
+        <artifactId>ignite-parent</artifactId>
+        <version>1</version>
+        <relativePath>../../parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>metastorage-common</artifactId>
+    <version>3.0.0-SNAPSHOT</version>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.jetbrains</groupId>
+            <artifactId>annotations</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/AbstractCondition.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/AbstractCondition.java
new file mode 100644
index 0000000..9bfb570
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/AbstractCondition.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.common;
+
+import static org.apache.ignite.metastorage.common.ConditionType.EQUAL;
+import static org.apache.ignite.metastorage.common.ConditionType.GREATER;
+import static org.apache.ignite.metastorage.common.ConditionType.LESS;
+import static org.apache.ignite.metastorage.common.ConditionType.NOT_EQUAL;
+
+/**
+ * Abstract condition which is designed for a comparison based conditions.
+ *
+ * <p>The comparison type is defined by {@link ConditionType} enumeration. Only {@link #compare(Entry)} method
+ * should be implemented for getting correct comparison based condition evaluation.</p>
+ */
+public abstract class AbstractCondition implements Condition {
+    /** Condition type. */
+    private final ConditionType type;
+
+    /**
+     * Constructor.
+     *
+     * @param type Condition type.
+     */
+    public AbstractCondition(ConditionType type) {
+        this.type = type;
+    }
+
+    /**
+     * Returns condition type for this condition.
+     *
+     * @return Condition type.
+     */
+    protected ConditionType conditionType() {
+        return type;
+    }
+
+    /**
+     * Evaluates comparison based condition.
+     *
+     * @param e Entry which is a subject of conditional update.
+     * @return {@code True} if condition is successful, otherwise - {@code false}.
+     */
+    @Override public boolean eval(Entry e) {
+        int res = compare(e);
+
+        ConditionType type = conditionType();
+
+        return (type == EQUAL && res == 0) ||
+                (type == NOT_EQUAL && res != 0) ||
+                (type == LESS && res < 0) ||
+                (type == GREATER && res > 0);
+    }
+
+    /**
+     * This abstract method should implement comparison logic based on {@link java.util.Comparator} contract.
+     *
+     * @param e Entry.
+     * @return Comparison result as defined {@link java.util.Comparator} contract.
+     */
+    abstract protected int compare(Entry e);
+}
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/Condition.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/Condition.java
new file mode 100644
index 0000000..e1a81ed
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/Condition.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.common;
+
+/**
+ * Defines condition interface for metastorage conditional update.
+ */
+public interface Condition {
+    /**
+     * Should implements logic for condition evaluation.
+     *
+     * @param e Entry which is a subject of conditional update.
+     * @return {@code True} if condition is successful, otherwise - {@code false}.
+     */
+    boolean eval(Entry e);
+}
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/ConditionType.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/ConditionType.java
new file mode 100644
index 0000000..16383d2
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/ConditionType.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.common;
+
+/**
+ * Defines available condition types.
+ */
+enum ConditionType {
+    /** Equal to smth. */
+    EQUAL,
+
+    /** Not equal to smth. */
+    NOT_EQUAL,
+
+    /** Greater than smth. */
+    GREATER,
+
+    /** Less than smth. */
+    LESS
+}
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/Entry.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/Entry.java
new file mode 100644
index 0000000..719809f
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/Entry.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.common;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Represents a storage unit as entry with key, value and revision, where
+ * <ul>
+ *     <li>key - an unique entry's key represented by an array of bytes. Keys are comparable in lexicographic manner.</li>
+ *     <ul>value - a data which is associated with a key and represented as an array of bytes.</ul>
+ *     <ul>revision - a number which denotes a version of whole meta storage. Each change increments the revision.</ul>
+ * </ul>
+ *
+ * Instance of {@link #Entry} could represents:
+ * <ul>
+ *     <li>A regular entry which stores a particular key, a value and a revision number.</li>
+ *     <li>An empty entry which denotes absence a regular entry in the meta storage for a given key.
+ *     A revision is 0 for such kind of entry.</li>
+ *     <li>A tombstone entry which denotes that a regular entry for a given key was removed from storage on some revision.</li>
+ * </ul>
+ */
+public class Entry {
+    /** Entry key. Couldn't be {@code null}. */
+    @NotNull
+    final private byte[] key;
+
+    /**
+     * Entry value.
+     * <p>
+     *     {@code val == null} only for {@link #empty()} and {@link #tombstone()} entries.
+     * </p>
+     */
+    @Nullable
+    final private byte[] val;
+
+    /**
+     * Revision number corresponding to this particular entry.
+     * <p>
+     *     {@code rev == 0} for {@link #empty()} entry,
+     *     {@code rev > 0} for regular and {@link #tombstone()} entries.
+     * </p>
+     */
+    final private long rev;
+
+    /**
+     * Constructor.
+     *
+     * @param key Key bytes. Couldn't be {@code null}.
+     * @param val Value bytes. Couldn't be {@code null}.
+     * @param rev Revision.
+     */
+    // TODO: It seems user will never create Entry, so we can reduce constructor scope to protected or package-private and reuse it from two-place private constructor.
+    public Entry(@NotNull byte[] key, @NotNull byte[] val, long rev) {
+        assert key != null : "key can't be null";
+        assert val != null : "value can't be null";
+
+        this.key = key;
+        this.val = val;
+        this.rev = rev;
+    }
+
+    /**
+     * Constructor for empty and tombstone entries.
+     *
+     * @param key Key bytes. Couldn't be {@code null}.
+     * @param rev Revision.
+     */
+    private Entry(@NotNull byte[] key, long rev) {
+        assert key != null : "key can't be null";
+
+        this.key = key;
+        this.val = null;
+        this.rev = rev;
+    }
+
+    /**
+     * Creates an instance of empty entry for a given key.
+     *
+     * @param key Key bytes. Couldn't be {@code null}.
+     * @return Empty entry.
+     */
+    @NotNull
+    public static Entry empty(byte[] key) {
+        return new Entry(key, 0);
+    }
+
+    /**
+     * Creates an instance of tombstone entry for a given key and a revision.
+     *
+     * @param key Key bytes. Couldn't be {@code null}.
+     * @return Empty entry.
+     */
+    @NotNull
+    public static Entry tombstone(byte[] key, long rev) {
+        assert rev > 0 : "rev must be positive for tombstone entry.";
+
+        return new Entry(key, rev);
+    }
+
+    /**
+     * Returns a key.
+     *
+     * @return Key.
+     */
+    @NotNull
+    public byte[] key() {
+        return key;
+    }
+
+    /**
+     * Returns a value.
+     *
+     * @return Value.
+     */
+    @Nullable
+    public byte[] value() {
+        return val;
+    }
+
+    /**
+     * Returns a revision.
+     * @return Revision.
+     */
+    public long revision() {
+        return rev;
+    }
+
+    /**
+     * Returns value which denotes whether entry is tombstone or not.
+     *
+     * @return {@code True} if entry is tombstone, otherwise - {@code false}.
+     */
+    public boolean tombstone() {
+        return val == null && rev > 0;
+    }
+
+    /**
+     * Returns value which denotes whether entry is empty or not.
+     *
+     * @return {@code True} if entry is empty, otherwise - {@code false}.
+     */
+    public boolean empty() {
+        return val == null && rev == 0;
+    }
+}
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/LexicographicComparator.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/LexicographicComparator.java
new file mode 100644
index 0000000..c0e5f9d
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/LexicographicComparator.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.common;
+
+import java.util.Comparator;
+
+/**
+ * Byte array lexicographic comparator.
+ */
+public class LexicographicComparator implements Comparator<byte[]> {
+    /** Comparator instance. */
+    public static final Comparator<byte[]> INSTANCE = new LexicographicComparator();
+
+    /** {@inheritDoc} */
+    @Override public int compare(byte[] o1, byte[] o2) {
+        int minLength = Math.min(o1.length, o2.length);
+
+        for (int i = 0; i < minLength; ++i) {
+            int res = toInt(o1[i]) - toInt(o2[i]);
+
+            if (res != 0)
+                return res;
+        }
+
+        return o1.length - o2.length;
+    }
+
+    private static int toInt(byte val) {
+        return val & 0xFF;
+    }
+}
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/PutUpdate.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/PutUpdate.java
new file mode 100644
index 0000000..d1012df
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/PutUpdate.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.common;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Put (write) update.
+ */
+public class PutUpdate implements Update {
+    /** Key. */
+    @NotNull
+    private final byte[] key;
+
+    /** Value. */
+    @NotNull
+    private final byte[] val;
+
+    /**
+     * Constructor.
+     *
+     * @param key A target key which will be updated.
+     * @param val A target value which will be written for a given key.
+     */
+    public PutUpdate(@NotNull byte[] key, @NotNull byte[] val) {
+        assert key != null : "key can't be null";
+        assert val != null : "value can't be null";
+
+        this.key = key;
+        this.val = val;
+    }
+}
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/RemoveUpdate.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/RemoveUpdate.java
new file mode 100644
index 0000000..09e227c
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/RemoveUpdate.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.common;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Remove update.
+ */
+public class RemoveUpdate implements Update {
+    /** Key. */
+    @NotNull
+    private final byte[] key;
+
+    /**
+     * Constructor.
+     *
+     * @param key A target key which will be removed.
+     */
+    public RemoveUpdate(@NotNull byte[] key) {
+        this.key = key;
+    }
+}
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/RevisionCondition.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/RevisionCondition.java
new file mode 100644
index 0000000..cd08c9c
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/RevisionCondition.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.common;
+
+/**
+ * Condition, intended for revision evaluation.
+ */
+public class RevisionCondition extends AbstractCondition {
+    /** Revision. */
+    private final long rev;
+
+    /**
+     * Constructor.
+     *
+     * @param type Condition type.
+     * @param rev Revision for comparison.
+     */
+    public RevisionCondition(ConditionType type, long rev) {
+        super(type);
+
+        this.rev = rev;
+    }
+
+    /**
+     * Compares a given revision with a target one.
+     *
+     * @param e A target entry.
+     * @return Comparison result as defined {@link java.util.Comparator} contract.
+     */
+    @Override protected int compare(Entry e) {
+        return Long.compare(e.revision(), rev);
+    }
+}
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/Update.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/Update.java
new file mode 100644
index 0000000..58b211c
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/Update.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.common;
+
+/**
+ * Defines update command for metastorage conditional update.
+ */
+public interface Update {
+}
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/ValueCondition.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/ValueCondition.java
new file mode 100644
index 0000000..d437c87
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/ValueCondition.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.metastorage.common;
+
+/**
+ * Condition, intended for value evaluation.
+ */
+public class ValueCondition extends AbstractCondition {
+    /** Value. */
+    private final byte[] val;
+
+    /**
+     * Constructor.
+     *
+     * @param type Condition type.
+     * @param val Value for comparison.
+     */
+    public ValueCondition(ConditionType type, byte[] val) {
+        super(type);
+
+        this.val = val;
+    }
+
+    /**
+     * Compares a given value with a target one in lexicographical manner.
+     *
+     * @param e A target entry.
+     * @return Comparison result as defined {@link java.util.Comparator} contract.
+     */
+    // TODO: Actually, value could be compared in different manners. So we should have possibility to define comparison logic.
+    @Override protected int compare(Entry e) {
+        return LexicographicComparator.INSTANCE.compare(e.value(), val);
+    }
+}
diff --git a/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/package-info.java b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/package-info.java
new file mode 100644
index 0000000..fab9cc7
--- /dev/null
+++ b/modules/metastorage-common/src/main/java/org/apache/ignite/metastorage/common/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Contains entities required by both metastorage client and server implementations.
+ */
+package org.apache.ignite.metastorage.common;
diff --git a/pom.xml b/pom.xml
index abf5ce6..f0c5f2e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,6 +38,8 @@
         <module>modules/cli-common</module>
         <module>modules/configuration</module>
         <module>modules/configuration-annotation-processor</module>
+        <module>modules/metastorage-common</module>
+        <module>modules/metastorage-client</module>
         <module>modules/rest</module>
         <module>modules/runner</module>
     </modules>