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

weibin pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-graphar.git


The following commit(s) were added to refs/heads/main by this push:
     new 0026d4e  feat(java): add vertex, edge, graph info (#484)
0026d4e is described below

commit 0026d4e2094313b15f1aed73d17a7add9762b126
Author: John <[email protected]>
AuthorDate: Mon May 20 09:00:29 2024 +0800

    feat(java): add vertex, edge, graph info (#484)
---
 .../graphar/info/{type => }/AdjacentList.java      |   0
 .../java/org/apache/graphar/info/EdgeInfo.java     | 394 +++++++++++++++++++++
 .../java/org/apache/graphar/info/GraphInfo.java    | 285 +++++++++++++++
 .../apache/graphar/info/{type => }/Property.java   |   0
 .../graphar/info/{type => }/PropertyGroup.java     |   0
 .../java/org/apache/graphar/info/VertexInfo.java   | 209 +++++++++++
 6 files changed, 888 insertions(+)

diff --git 
a/maven-projects/info/src/main/java/org/apache/graphar/info/type/AdjacentList.java
 b/maven-projects/info/src/main/java/org/apache/graphar/info/AdjacentList.java
similarity index 100%
rename from 
maven-projects/info/src/main/java/org/apache/graphar/info/type/AdjacentList.java
rename to 
maven-projects/info/src/main/java/org/apache/graphar/info/AdjacentList.java
diff --git 
a/maven-projects/info/src/main/java/org/apache/graphar/info/EdgeInfo.java 
b/maven-projects/info/src/main/java/org/apache/graphar/info/EdgeInfo.java
new file mode 100644
index 0000000..1187b7d
--- /dev/null
+++ b/maven-projects/info/src/main/java/org/apache/graphar/info/EdgeInfo.java
@@ -0,0 +1,394 @@
+/*
+ * 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.graphar.info;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.apache.graphar.info.type.AdjListType;
+import org.apache.graphar.info.type.DataType;
+import org.apache.graphar.info.yaml.EdgeYamlParser;
+import org.apache.graphar.info.yaml.GraphYamlParser;
+import org.apache.graphar.util.GeneralParams;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FSDataInputStream;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.yaml.snakeyaml.LoaderOptions;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+
+public class EdgeInfo {
+    private final EdgeTriplet edgeTriplet;
+    private final long chunkSize;
+    private final long srcChunkSize;
+    private final long dstChunkSize;
+    private final boolean directed;
+    private final String prefix;
+    private final Map<AdjListType, AdjacentList> adjacentLists;
+    private final PropertyGroups propertyGroups;
+    private final String version;
+
+    public EdgeInfo(
+            String srcLabel,
+            String edgeLabel,
+            String dstLabel,
+            long srcChunkSize,
+            long chunkSize,
+            long dstChunkSize,
+            boolean directed,
+            String prefix,
+            List<AdjacentList> adjacentListsAsList,
+            List<PropertyGroup> propertyGroupsAsList,
+            String version) {
+        this.edgeTriplet = new EdgeTriplet(srcLabel, edgeLabel, dstLabel);
+        this.chunkSize = chunkSize;
+        this.srcChunkSize = srcChunkSize;
+        this.dstChunkSize = dstChunkSize;
+        this.directed = directed;
+        this.prefix = prefix;
+        this.adjacentLists =
+                adjacentListsAsList.stream()
+                        .collect(
+                                Collectors.toUnmodifiableMap(
+                                        AdjacentList::getType, 
Function.identity()));
+        this.propertyGroups = new PropertyGroups(propertyGroupsAsList);
+        this.version = version;
+    }
+
+    private EdgeInfo(EdgeYamlParser yamlParser) {
+        this(
+                yamlParser.getSrc_label(),
+                yamlParser.getEdge_label(),
+                yamlParser.getDst_label(),
+                yamlParser.getChunk_size(),
+                yamlParser.getSrc_chunk_size(),
+                yamlParser.getDst_chunk_size(),
+                yamlParser.isDirected(),
+                yamlParser.getPrefix(),
+                yamlParser.getAdjacent_lists().stream()
+                        .map(AdjacentList::new)
+                        .collect(Collectors.toUnmodifiableList()),
+                yamlParser.getProperty_groups().stream()
+                        .map(PropertyGroup::new)
+                        .collect(Collectors.toUnmodifiableList()),
+                yamlParser.getVersion());
+    }
+
+    private EdgeInfo(
+            EdgeTriplet edgeTriplet,
+            long chunkSize,
+            long srcChunkSize,
+            long dstChunkSize,
+            boolean directed,
+            String prefix,
+            Map<AdjListType, AdjacentList> adjacentLists,
+            PropertyGroups propertyGroups,
+            String version) {
+        this.edgeTriplet = edgeTriplet;
+        this.chunkSize = chunkSize;
+        this.srcChunkSize = srcChunkSize;
+        this.dstChunkSize = dstChunkSize;
+        this.directed = directed;
+        this.prefix = prefix;
+        this.adjacentLists = adjacentLists;
+        this.propertyGroups = propertyGroups;
+        this.version = version;
+    }
+
+    public static EdgeInfo load(String edgeInfoPath) throws IOException {
+        return load(edgeInfoPath, new Configuration());
+    }
+
+    public static EdgeInfo load(String edgeInfoPath, Configuration conf) 
throws IOException {
+        if (conf == null) {
+            throw new IllegalArgumentException("Configuration is null");
+        }
+        return load(edgeInfoPath, FileSystem.get(conf));
+    }
+
+    public static EdgeInfo load(String edgeInfoPath, FileSystem fileSystem) 
throws IOException {
+        if (fileSystem == null) {
+            throw new IllegalArgumentException("FileSystem is null");
+        }
+        FSDataInputStream inputStream = fileSystem.open(new 
Path(edgeInfoPath));
+        Yaml edgeInfoYamlLoader =
+                new Yaml(new Constructor(EdgeYamlParser.class, new 
LoaderOptions()));
+        EdgeYamlParser edgeInfoYaml = edgeInfoYamlLoader.load(inputStream);
+        return new EdgeInfo(edgeInfoYaml);
+    }
+
+    public Optional<EdgeInfo> addAdjacentListAsNew(AdjacentList adjacentList) {
+        if (adjacentList == null || 
adjacentLists.containsKey(adjacentList.getType())) {
+            return Optional.empty();
+        }
+        Map<AdjListType, AdjacentList> newAdjacentLists =
+                Stream.concat(
+                                adjacentLists.entrySet().stream(),
+                                Map.of(adjacentList.getType(), 
adjacentList).entrySet().stream())
+                        .collect(
+                                Collectors.toUnmodifiableMap(
+                                        Map.Entry::getKey, 
Map.Entry::getValue));
+        return Optional.of(
+                new EdgeInfo(
+                        edgeTriplet,
+                        chunkSize,
+                        srcChunkSize,
+                        dstChunkSize,
+                        directed,
+                        prefix,
+                        newAdjacentLists,
+                        propertyGroups,
+                        version));
+    }
+
+    public Optional<EdgeInfo> addPropertyGroupAsNew(PropertyGroup 
propertyGroup) {
+        return propertyGroups
+                .addPropertyGroupAsNew(propertyGroup)
+                .map(
+                        newPropertyGroups ->
+                                new EdgeInfo(
+                                        edgeTriplet,
+                                        chunkSize,
+                                        srcChunkSize,
+                                        dstChunkSize,
+                                        directed,
+                                        prefix,
+                                        adjacentLists,
+                                        newPropertyGroups,
+                                        version));
+    }
+
+    public boolean hasAdjListType(AdjListType adjListType) {
+        return adjacentLists.containsKey(adjListType);
+    }
+
+    public boolean hasProperty(String propertyName) {
+        return propertyGroups.hasProperty(propertyName);
+    }
+
+    public boolean hasPropertyGroup(PropertyGroup propertyGroup) {
+        return propertyGroups.hasPropertyGroup(propertyGroup);
+    }
+
+    public AdjacentList getAdjacentList(AdjListType adjListType) {
+        // AdjListType will be checked in this method,
+        // other methods which get adjacent list in this class should call 
this method first,
+        // so we don't check AdjListType in other methods.
+        checkAdjListTypeExist(adjListType);
+        return adjacentLists.get(adjListType);
+    }
+
+    public int getPropertyGroupNum() {
+        return propertyGroups.getPropertyGroupNum();
+    }
+
+    public PropertyGroup getPropertyGroup(String property) {
+        return propertyGroups.getPropertyGroup(property);
+    }
+
+    public String getPropertyGroupPrefix(PropertyGroup propertyGroup) {
+        checkPropertyGroupExist(propertyGroup);
+        return getPrefix() + "/" + propertyGroup.getPrefix();
+    }
+
+    public String getPropertyGroupChunkPath(PropertyGroup propertyGroup, long 
chunkIndex) {
+        // PropertyGroup will be checked in getPropertyGroupPrefix
+        return getPropertyGroupPrefix(propertyGroup) + "/chunk" + chunkIndex;
+    }
+
+    public String getAdjacentListPrefix(AdjListType adjListType) {
+        return getPrefix() + "/" + getAdjacentList(adjListType).getPrefix() + 
"/adj_list";
+    }
+
+    public String getAdjacentListChunkPath(AdjListType adjListType, long 
vertexChunkIndex) {
+        return getAdjacentListPrefix(adjListType) + "/chunk" + 
vertexChunkIndex;
+    }
+
+    public String getOffsetPrefix(AdjListType adjListType) {
+        return getAdjacentListPrefix(adjListType) + "/offset";
+    }
+
+    public String getOffsetChunkPath(AdjListType adjListType, long 
vertexChunkIndex) {
+        return getOffsetPrefix(adjListType) + "/chunk" + vertexChunkIndex;
+    }
+
+    public String getVerticesNumFilePath(AdjListType adjListType) {
+        return getAdjacentListPrefix(adjListType) + "/vertex_count";
+    }
+
+    public String getEdgesNumFilePath(AdjListType adjListType, long 
vertexChunkIndex) {
+        return getAdjacentListPrefix(adjListType) + "/edge_count" + 
vertexChunkIndex;
+    }
+
+    public DataType getPropertyType(String propertyName) {
+        return propertyGroups.getPropertyType(propertyName);
+    }
+
+    public boolean isPrimaryKey(String propertyName) {
+        return propertyGroups.isPrimaryKey(propertyName);
+    }
+
+    public boolean isNullableKey(String propertyName) {
+        return propertyGroups.isNullableKey(propertyName);
+    }
+
+    public void save(String filePath) throws IOException {
+        save(filePath, new Configuration());
+    }
+
+    public void save(String filePath, Configuration conf) throws IOException {
+        if (conf == null) {
+            throw new IllegalArgumentException("Configuration is null");
+        }
+        save(filePath, FileSystem.get(conf));
+    }
+
+    public void save(String fileName, FileSystem fileSystem) throws 
IOException {
+        if (fileSystem == null) {
+            throw new IllegalArgumentException("FileSystem is null");
+        }
+        FSDataOutputStream outputStream = fileSystem.create(new 
Path(fileName));
+        outputStream.writeBytes(dump());
+        outputStream.close();
+    }
+
+    public String dump() {
+        Yaml yaml = new Yaml(GraphYamlParser.getDumperOptions());
+        EdgeYamlParser edgeYaml = new EdgeYamlParser(this);
+        return yaml.dump(edgeYaml);
+    }
+
+    public String getConcat() {
+        return edgeTriplet.getConcat();
+    }
+
+    public String getSrcLabel() {
+        return edgeTriplet.getSrcLabel();
+    }
+
+    public String getEdgeLabel() {
+        return edgeTriplet.getEdgeLabel();
+    }
+
+    public String getDstLabel() {
+        return edgeTriplet.getDstLabel();
+    }
+
+    public long getChunkSize() {
+        return chunkSize;
+    }
+
+    public long getSrcChunkSize() {
+        return srcChunkSize;
+    }
+
+    public long getDstChunkSize() {
+        return dstChunkSize;
+    }
+
+    public boolean isDirected() {
+        return directed;
+    }
+
+    public String getPrefix() {
+        return prefix;
+    }
+
+    public Map<AdjListType, AdjacentList> getAdjacentLists() {
+        return adjacentLists;
+    }
+
+    public List<PropertyGroup> getPropertyGroups() {
+        return propertyGroups.getPropertyGroupList();
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    private void checkAdjListTypeExist(AdjListType adjListType) {
+        if (adjListType == null) {
+            throw new IllegalArgumentException("The adjacency list type is 
null");
+        }
+        if (!adjacentLists.containsKey(adjListType)) {
+            throw new IllegalArgumentException(
+                    "The adjacency list type "
+                            + adjListType
+                            + " does not exist in the edge info "
+                            + this.edgeTriplet.getConcat());
+        }
+    }
+
+    private void checkPropertyGroupExist(PropertyGroup propertyGroup) {
+        if (propertyGroup == null) {
+            throw new IllegalArgumentException("Property group is null");
+        }
+        if (!hasPropertyGroup(propertyGroup)) {
+            throw new IllegalArgumentException(
+                    "Property group "
+                            + propertyGroup
+                            + " does not exist in the edge "
+                            + getConcat());
+        }
+    }
+
+    private static class EdgeTriplet {
+        private final String srcLabel;
+        private final String edgeLabel;
+        private final String dstLabel;
+
+        public EdgeTriplet(String srcLabel, String edgeLabel, String dstLabel) 
{
+            this.srcLabel = srcLabel;
+            this.edgeLabel = edgeLabel;
+            this.dstLabel = dstLabel;
+        }
+
+        public String getConcat() {
+            return srcLabel
+                    + GeneralParams.regularSeparator
+                    + edgeLabel
+                    + GeneralParams.regularSeparator
+                    + dstLabel;
+        }
+
+        @Override
+        public String toString() {
+            return getConcat();
+        }
+
+        public String getSrcLabel() {
+            return srcLabel;
+        }
+
+        public String getEdgeLabel() {
+            return edgeLabel;
+        }
+
+        public String getDstLabel() {
+            return dstLabel;
+        }
+    }
+}
diff --git 
a/maven-projects/info/src/main/java/org/apache/graphar/info/GraphInfo.java 
b/maven-projects/info/src/main/java/org/apache/graphar/info/GraphInfo.java
new file mode 100644
index 0000000..977112a
--- /dev/null
+++ b/maven-projects/info/src/main/java/org/apache/graphar/info/GraphInfo.java
@@ -0,0 +1,285 @@
+/*
+ * 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.graphar.info;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.apache.graphar.info.yaml.GraphYamlParser;
+import org.apache.graphar.util.GeneralParams;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FSDataInputStream;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.yaml.snakeyaml.LoaderOptions;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+
+public class GraphInfo {
+    private final String name;
+    private final List<VertexInfo> vertexInfos;
+    private final List<EdgeInfo> edgeInfos;
+    private final String prefix;
+    private final Map<String, VertexInfo> vertexLabel2VertexInfo;
+    private final Map<String, EdgeInfo> edgeConcat2EdgeInfo;
+    private final String version;
+
+    public GraphInfo(
+            String name,
+            List<VertexInfo> vertexInfos,
+            List<EdgeInfo> edgeInfos,
+            String prefix,
+            String version) {
+        this.name = name;
+        this.vertexInfos = List.copyOf(vertexInfos);
+        this.edgeInfos = List.copyOf(edgeInfos);
+        this.prefix = prefix;
+        this.version = version;
+        this.vertexLabel2VertexInfo =
+                vertexInfos.stream()
+                        .collect(
+                                Collectors.toUnmodifiableMap(
+                                        VertexInfo::getLabel, 
Function.identity()));
+        this.edgeConcat2EdgeInfo =
+                edgeInfos.stream()
+                        .collect(
+                                Collectors.toUnmodifiableMap(
+                                        EdgeInfo::getConcat, 
Function.identity()));
+    }
+
+    private GraphInfo(GraphYamlParser graphYaml, Configuration conf) throws 
IOException {
+        this(
+                graphYaml.getName(),
+                vertexFileNames2VertexInfos(graphYaml.getVertices(), conf),
+                edgeFileNames2EdgeInfos(graphYaml.getEdges(), conf),
+                graphYaml.getPrefix(),
+                graphYaml.getVersion());
+    }
+
+    private GraphInfo(
+            String name,
+            List<VertexInfo> vertexInfos,
+            List<EdgeInfo> edgeInfos,
+            String prefix,
+            Map<String, VertexInfo> vertexLabel2VertexInfo,
+            Map<String, EdgeInfo> edgeConcat2EdgeInfo,
+            String version) {
+        this.name = name;
+        this.vertexInfos = vertexInfos;
+        this.edgeInfos = edgeInfos;
+        this.prefix = prefix;
+        this.vertexLabel2VertexInfo = vertexLabel2VertexInfo;
+        this.edgeConcat2EdgeInfo = edgeConcat2EdgeInfo;
+        this.version = version;
+    }
+
+    public static GraphInfo load(String graphPath) throws IOException {
+        return load(graphPath, new Configuration());
+    }
+
+    public static GraphInfo load(String graphPath, FileSystem fileSystem) 
throws IOException {
+        if (fileSystem == null) {
+            throw new IllegalArgumentException("FileSystem is null");
+        }
+        return load(graphPath, fileSystem.getConf());
+    }
+
+    public static GraphInfo load(String graphPath, Configuration conf) throws 
IOException {
+        if (conf == null) {
+            throw new IllegalArgumentException("Configuration is null");
+        }
+        Path path = new Path(graphPath);
+        FileSystem fileSystem = path.getFileSystem(conf);
+        FSDataInputStream inputStream = fileSystem.open(path);
+        Yaml graphYamlLoader =
+                new Yaml(new Constructor(GraphYamlParser.class, new 
LoaderOptions()));
+        GraphYamlParser graphYaml = graphYamlLoader.load(inputStream);
+        return new GraphInfo(graphYaml, conf);
+    }
+
+    public void save(String filePath) throws IOException {
+        save(filePath, new Configuration());
+    }
+
+    public void save(String filePath, Configuration conf) throws IOException {
+        if (conf == null) {
+            throw new IllegalArgumentException("Configuration is null");
+        }
+        save(filePath, FileSystem.get(conf));
+    }
+
+    public void save(String fileName, FileSystem fileSystem) throws 
IOException {
+        if (fileSystem == null) {
+            throw new IllegalArgumentException("FileSystem is null");
+        }
+        FSDataOutputStream outputStream = fileSystem.create(new 
Path(fileName));
+        outputStream.writeBytes(dump());
+        outputStream.close();
+    }
+
+    public String dump() {
+        Yaml yaml = new Yaml(GraphYamlParser.getDumperOptions());
+        GraphYamlParser graphYaml = new GraphYamlParser(this);
+        return yaml.dump(graphYaml);
+    }
+
+    public Optional<GraphInfo> addVertexAsNew(VertexInfo vertexInfo) {
+        if (vertexInfo == null || hasVertexInfo(vertexInfo.getLabel())) {
+            return Optional.empty();
+        }
+        List<VertexInfo> newVertexInfos =
+                Stream.concat(vertexInfos.stream(), Stream.of(vertexInfo))
+                        .collect(Collectors.toList());
+        Map<String, VertexInfo> newVertexLabel2VertexInfo =
+                Stream.concat(
+                                vertexLabel2VertexInfo.entrySet().stream(),
+                                Stream.of(Map.entry(vertexInfo.getLabel(), 
vertexInfo)))
+                        .collect(
+                                Collectors.toUnmodifiableMap(
+                                        Map.Entry::getKey, 
Map.Entry::getValue));
+        return Optional.of(
+                new GraphInfo(
+                        name,
+                        newVertexInfos,
+                        edgeInfos,
+                        prefix,
+                        newVertexLabel2VertexInfo,
+                        edgeConcat2EdgeInfo,
+                        version));
+    }
+
+    public Optional<GraphInfo> addEdgeAsNew(EdgeInfo edgeInfo) {
+        if (edgeInfo == null
+                || hasEdgeInfo(
+                        edgeInfo.getSrcLabel(), edgeInfo.getEdgeLabel(), 
edgeInfo.getDstLabel())) {
+            return Optional.empty();
+        }
+        List<EdgeInfo> newEdgeInfos =
+                Stream.concat(edgeInfos.stream(), 
Stream.of(edgeInfo)).collect(Collectors.toList());
+        Map<String, EdgeInfo> newEdgeConcat2EdgeInfo =
+                Stream.concat(
+                                edgeConcat2EdgeInfo.entrySet().stream(),
+                                Stream.of(Map.entry(edgeInfo.getConcat(), 
edgeInfo)))
+                        .collect(
+                                Collectors.toUnmodifiableMap(
+                                        Map.Entry::getKey, 
Map.Entry::getValue));
+        return Optional.of(
+                new GraphInfo(
+                        name,
+                        vertexInfos,
+                        newEdgeInfos,
+                        prefix,
+                        vertexLabel2VertexInfo,
+                        newEdgeConcat2EdgeInfo,
+                        version));
+    }
+
+    public boolean hasVertexInfo(String label) {
+        return vertexLabel2VertexInfo.containsKey(label);
+    }
+
+    public boolean hasEdgeInfo(String srcLabel, String edgeLabel, String 
dstLabel) {
+        return edgeConcat2EdgeInfo.containsKey(srcLabel + dstLabel + 
edgeLabel);
+    }
+
+    public VertexInfo getVertexInfo(String label) {
+        checkVertexExist(label);
+        return vertexLabel2VertexInfo.get(label);
+    }
+
+    public EdgeInfo getEdgeInfo(String srcLabel, String edgeLabel, String 
dstLabel) {
+        checkEdgeExist(srcLabel, edgeLabel, dstLabel);
+        return edgeConcat2EdgeInfo.get(srcLabel + edgeLabel + dstLabel);
+    }
+
+    public int getVertexInfoNum() {
+        return vertexInfos.size();
+    }
+
+    public int getEdgeInfoNum() {
+        return edgeInfos.size();
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public List<VertexInfo> getVertexInfos() {
+        return vertexInfos;
+    }
+
+    public List<EdgeInfo> getEdgeInfos() {
+        return edgeInfos;
+    }
+
+    public String getPrefix() {
+        return prefix;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    private static List<VertexInfo> vertexFileNames2VertexInfos(
+            List<String> vertexFileNames, Configuration conf) throws 
IOException {
+        ArrayList<VertexInfo> tempVertices = new 
ArrayList<>(vertexFileNames.size());
+        for (String vertexFileName : vertexFileNames) {
+            tempVertices.add(VertexInfo.load(vertexFileName, conf));
+        }
+        return List.copyOf(tempVertices);
+    }
+
+    private static List<EdgeInfo> edgeFileNames2EdgeInfos(
+            List<String> edgeFileNames, Configuration conf) throws IOException 
{
+        ArrayList<EdgeInfo> tempEdges = new ArrayList<>(edgeFileNames.size());
+        for (String edgeFileName : edgeFileNames) {
+            tempEdges.add(EdgeInfo.load(edgeFileName, conf));
+        }
+        return List.copyOf(tempEdges);
+    }
+
+    private void checkVertexExist(String label) {
+        if (!hasVertexInfo(label)) {
+            throw new IllegalArgumentException(
+                    "Vertex label " + label + " not exist in graph " + 
getName());
+        }
+    }
+
+    private void checkEdgeExist(String srcLabel, String dstLabel, String 
edgeLabel) {
+        if (!hasEdgeInfo(srcLabel, dstLabel, edgeLabel)) {
+            throw new IllegalArgumentException(
+                    "Edge label"
+                            + srcLabel
+                            + GeneralParams.regularSeparator
+                            + GeneralParams.regularSeparator
+                            + edgeLabel
+                            + GeneralParams.regularSeparator
+                            + dstLabel
+                            + " not exist in graph "
+                            + getName());
+        }
+    }
+}
diff --git 
a/maven-projects/info/src/main/java/org/apache/graphar/info/type/Property.java 
b/maven-projects/info/src/main/java/org/apache/graphar/info/Property.java
similarity index 100%
rename from 
maven-projects/info/src/main/java/org/apache/graphar/info/type/Property.java
rename to 
maven-projects/info/src/main/java/org/apache/graphar/info/Property.java
diff --git 
a/maven-projects/info/src/main/java/org/apache/graphar/info/type/PropertyGroup.java
 b/maven-projects/info/src/main/java/org/apache/graphar/info/PropertyGroup.java
similarity index 100%
rename from 
maven-projects/info/src/main/java/org/apache/graphar/info/type/PropertyGroup.java
rename to 
maven-projects/info/src/main/java/org/apache/graphar/info/PropertyGroup.java
diff --git 
a/maven-projects/info/src/main/java/org/apache/graphar/info/VertexInfo.java 
b/maven-projects/info/src/main/java/org/apache/graphar/info/VertexInfo.java
new file mode 100644
index 0000000..2ccadc6
--- /dev/null
+++ b/maven-projects/info/src/main/java/org/apache/graphar/info/VertexInfo.java
@@ -0,0 +1,209 @@
+/*
+ * 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.graphar.info;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import org.apache.graphar.info.type.DataType;
+import org.apache.graphar.info.yaml.GraphYamlParser;
+import org.apache.graphar.info.yaml.VertexYamlParser;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FSDataInputStream;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.yaml.snakeyaml.LoaderOptions;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+
+public class VertexInfo {
+    private final String label;
+    private final long chunkSize;
+    private final PropertyGroups propertyGroups;
+    private final String prefix;
+    private final String version;
+
+    public VertexInfo(
+            String label,
+            long chunkSize,
+            List<PropertyGroup> propertyGroups,
+            String prefix,
+            String version) {
+        this.label = label;
+        this.chunkSize = chunkSize;
+        this.propertyGroups = new PropertyGroups(propertyGroups);
+        this.prefix = prefix;
+        this.version = version;
+    }
+
+    private VertexInfo(VertexYamlParser parser) {
+        this(
+                parser.getLabel(),
+                parser.getChunk_size(),
+                parser.getProperty_groups().stream()
+                        .map(PropertyGroup::new)
+                        .collect(Collectors.toUnmodifiableList()),
+                parser.getPrefix(),
+                parser.getVersion());
+    }
+
+    private VertexInfo(
+            String label,
+            long chunkSize,
+            PropertyGroups propertyGroups,
+            String prefix,
+            String version) {
+        this.label = label;
+        this.chunkSize = chunkSize;
+        this.propertyGroups = propertyGroups;
+        this.prefix = prefix;
+        this.version = version;
+    }
+
+    public static VertexInfo load(String vertexInfoPath) throws IOException {
+        return load(vertexInfoPath, new Configuration());
+    }
+
+    public static VertexInfo load(String vertexInfoPath, Configuration conf) 
throws IOException {
+        if (conf == null) {
+            throw new IllegalArgumentException("Configuration is null");
+        }
+        return load(vertexInfoPath, FileSystem.get(conf));
+    }
+
+    public static VertexInfo load(String vertexInfoPath, FileSystem 
fileSystem) throws IOException {
+        if (fileSystem == null) {
+            throw new IllegalArgumentException("FileSystem is null");
+        }
+        FSDataInputStream inputStream = fileSystem.open(new 
Path(vertexInfoPath));
+        Yaml vertexInfoYamlLoader =
+                new Yaml(new Constructor(VertexYamlParser.class, new 
LoaderOptions()));
+        VertexYamlParser vertexInfoYaml = 
vertexInfoYamlLoader.load(inputStream);
+        return new VertexInfo(vertexInfoYaml);
+    }
+
+    public Optional<VertexInfo> addPropertyGroupAsNew(PropertyGroup 
propertyGroup) {
+        return propertyGroups
+                .addPropertyGroupAsNew(propertyGroup)
+                .map(
+                        newPropertyGroups ->
+                                new VertexInfo(
+                                        label, chunkSize, newPropertyGroups, 
prefix, version));
+    }
+
+    public int propertyGroupNum() {
+        return propertyGroups.getPropertyGroupNum();
+    }
+
+    public DataType getPropertyType(String propertyName) {
+        return propertyGroups.getPropertyType(propertyName);
+    }
+
+    public boolean hasProperty(String propertyName) {
+        return propertyGroups.hasProperty(propertyName);
+    }
+
+    public boolean isPrimaryKey(String propertyName) {
+        return propertyGroups.isPrimaryKey(propertyName);
+    }
+
+    public boolean isNullableKey(String propertyName) {
+        return propertyGroups.isNullableKey(propertyName);
+    }
+
+    public boolean hasPropertyGroup(PropertyGroup propertyGroup) {
+        return propertyGroups.hasPropertyGroup(propertyGroup);
+    }
+
+    public String getPropertyGroupPrefix(PropertyGroup propertyGroup) {
+        checkPropertyGroupExist(propertyGroup);
+        return getPrefix() + "/" + propertyGroup.getPrefix();
+    }
+
+    public String getPropertyGroupChunkPath(PropertyGroup propertyGroup, long 
chunkIndex) {
+        // PropertyGroup will be checked in getPropertyGroupPrefix
+        return getPropertyGroupPrefix(propertyGroup) + "/chunk" + chunkIndex;
+    }
+
+    public String getVerticesNumFilePath() {
+        return getPrefix() + "/vertex_count";
+    }
+
+    public void save(String filePath) throws IOException {
+        save(filePath, new Configuration());
+    }
+
+    public void save(String filePath, Configuration conf) throws IOException {
+        if (conf == null) {
+            throw new IllegalArgumentException("Configuration is null");
+        }
+        save(filePath, FileSystem.get(conf));
+    }
+
+    public void save(String fileName, FileSystem fileSystem) throws 
IOException {
+        if (fileSystem == null) {
+            throw new IllegalArgumentException("FileSystem is null");
+        }
+        FSDataOutputStream outputStream = fileSystem.create(new 
Path(fileName));
+        outputStream.writeBytes(dump());
+        outputStream.close();
+    }
+
+    public String dump() {
+        Yaml yaml = new Yaml(GraphYamlParser.getDumperOptions());
+        VertexYamlParser vertexYaml = new VertexYamlParser(this);
+        return yaml.dump(vertexYaml);
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    public long getChunkSize() {
+        return chunkSize;
+    }
+
+    public List<PropertyGroup> getPropertyGroups() {
+        return propertyGroups.getPropertyGroupList();
+    }
+
+    public String getPrefix() {
+        return prefix;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    private void checkPropertyGroupExist(PropertyGroup propertyGroup) {
+        if (propertyGroup == null) {
+            throw new IllegalArgumentException("Property group is null");
+        }
+        if (!hasPropertyGroup(propertyGroup)) {
+            throw new IllegalArgumentException(
+                    "Property group "
+                            + propertyGroup
+                            + " does not exist in the vertex "
+                            + getLabel());
+        }
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to