1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 package org.apache.giraph.ooc.persistence;
20
21 import java.util.ArrayList;
22 import java.util.List;
23
24 /**
25 * Index chain used in out-of-core data accessor object (DAO) to access
26 * serialized data.
27 */
28 public class DataIndex {
29 /** Chain of data indices */
30 private final List<DataIndexEntry> indexList = new ArrayList<>(5);
31
32 /**
33 * Add an index to the index chain
34 *
35 * @param entry the entry to add to the chain
36 * @return the index chain itself
37 */
38 public DataIndex addIndex(DataIndexEntry entry) {
39 indexList.add(entry);
40 return this;
41 }
42
43 /**
44 * Remove/Pop the last index in the index chain
45 *
46 * @return the index chain itself
47 */
48 public DataIndex removeLastIndex() {
49 indexList.remove(indexList.size() - 1);
50 return this;
51 }
52
53 /**
54 * Create a copy of the existing DataIndex
55 *
56 * @return a copy of the existing index chain
57 */
58 public DataIndex copy() {
59 DataIndex index = new DataIndex();
60 for (DataIndexEntry entry : indexList) {
61 index.indexList.add(entry);
62 }
63 return index;
64 }
65
66 @Override
67 public boolean equals(Object obj) {
68 if (!(obj instanceof DataIndex)) {
69 return false;
70 }
71 DataIndex dataIndex = (DataIndex) obj;
72 return indexList.equals(dataIndex.indexList);
73 }
74
75 @Override
76 public int hashCode() {
77 return indexList.hashCode();
78 }
79
80 @Override
81 public String toString() {
82 StringBuffer sb = new StringBuffer();
83 for (DataIndexEntry entry : indexList) {
84 sb.append(entry);
85 }
86 return sb.toString();
87 }
88
89 /** Interface to unify different types of entries used as index chain */
90 public interface DataIndexEntry { }
91
92 /**
93 * Different static types of index chain entry
94 */
95 public enum TypeIndexEntry implements DataIndexEntry {
96 /** The whole partition */
97 PARTITION("_partition"),
98 /** Partition vertices */
99 PARTITION_VERTICES("_vertices"),
100 /** Partition edges */
101 PARTITION_EDGES("_edges"),
102 /** Partition messages */
103 MESSAGE("_messages"),
104 /** Edges stored in edge store for a partition */
105 EDGE_STORE("_edge_store"),
106 /** Raw data buffer (refer to DiskBackedDataStore) */
107 BUFFER("_buffer");
108
109 /** String realization of entry type */
110 private final String name;
111
112 /**
113 * Constructor
114 *
115 * @param name name of the type
116 */
117 TypeIndexEntry(String name) {
118 this.name = name;
119 }
120
121 public String getName() {
122 return name;
123 }
124
125 @Override
126 public String toString() {
127 return name;
128 }
129 }
130
131 /**
132 * Class representing any index chain that depends on something with id.
133 * Generally this is used for identifying indices in two types:
134 * - Index entry based on superstep id ('S' and the superstep number)
135 * - Index entry based on partition id ('P' and the partition id)
136 */
137 public static final class NumericIndexEntry implements DataIndexEntry {
138 /** Type of index */
139 private final char type;
140 /** Id of the index associated with the specified type */
141 private final long id;
142
143 /**
144 * Constructor
145 *
146 * @param type type of index (for now 'S' for superstep, or 'P' for
147 * partition)
148 * @param id id of the index associated with the given type
149 */
150 private NumericIndexEntry(char type, long id) {
151 this.type = type;
152 this.id = id;
153 }
154
155 @Override
156 public boolean equals(Object obj) {
157 if (!(obj instanceof NumericIndexEntry)) {
158 return false;
159 }
160 NumericIndexEntry index = (NumericIndexEntry) obj;
161 return index.type == type && index.id == id;
162 }
163
164 @Override
165 public int hashCode() {
166 int result = 17;
167 result = result * 37 + type;
168 result = result * 37 + (int) id;
169 result = result * 37 + (int) (id >> 32);
170 return result;
171 }
172
173 @Override
174 public String toString() {
175 return String.format("_%c%d", type, id);
176 }
177
178 /**
179 * Create a data index entry for a given partition
180 *
181 * @param partitionId id of the partition
182 * @return data index entry for a given partition
183 */
184 public static NumericIndexEntry createPartitionEntry(int partitionId) {
185 return new NumericIndexEntry('P', partitionId);
186 }
187
188 /**
189 * Create a data index entry for a given superstep
190 *
191 * @param superstep the superstep number
192 * @return data index entry for a given superstep
193 */
194 public static NumericIndexEntry createSuperstepEntry(long superstep) {
195 return new NumericIndexEntry('S', superstep);
196 }
197 }
198 }