diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000..f74700d6
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,14 @@
+# Please see the documentation for all configuration options:
+# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+
+ - package-ecosystem: "maven"
+ directory: "/"
+ schedule:
+ interval: "weekly"
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 00000000..8b456aa1
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,29 @@
+name: CI
+
+on:
+ push:
+ branches: [ master ]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v7
+ - name: Set up Maven Central Repository
+ uses: actions/setup-java@v5
+ with:
+ java-version: '17'
+ distribution: 'temurin'
+ server-id: central
+ server-username: OSSRH_USER
+ server-password: OSSRH_PASS
+ gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
+ gpg-passphrase: GPG_PASSPHRASE
+ - name: Publish package
+ run: mvn -B -Djava.awt.headless=true deploy -P release
+ env:
+ OSSRH_USER: ${{ secrets.OSSRH_TOKEN_USER }}
+ OSSRH_PASS: ${{ secrets.OSSRH_TOKEN_PASSWD }}
+ GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
+ - name: Submit test coverage to Coveralls
+ run: mvn test jacoco:report coveralls:report -DrepoToken=${{ secrets.COVERALLS_TOKEN }}
diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
new file mode 100644
index 00000000..918883b3
--- /dev/null
+++ b/.github/workflows/pr.yml
@@ -0,0 +1,17 @@
+name: PR
+
+on:
+ pull_request:
+
+jobs:
+ build_and_test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v7
+ - name: Set up JDK 17
+ uses: actions/setup-java@v5
+ with:
+ java-version: '17'
+ distribution: 'temurin'
+ - name: Build project with Maven
+ run: mvn -B package --file pom.xml
diff --git a/.gitignore b/.gitignore
index d12f9eaf..e56582dc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,6 @@ nbactions.xml
/store-benchmark/target/
/store/graphstore-api/target/
/store/graphstore/target/
+.idea
+*.iml
+.vscode/**
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index d6468833..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-sudo: false
-language: java
-jdk:
- - oraclejdk8
-branches:
- only:
- - master
-cache:
- directories:
- - $HOME/.m2
-before_install:
- - cd store
- - openssl aes-256-cbc -k "$GPG_PUBRING_ENCRYPTION" -in src/travis/pubring.gpg.enc -d -a -out src/travis/pubring.gpg
- - openssl aes-256-cbc -k "$GPG_SECRETRING_ENCRYPTION" -in src/travis/secretring.gpg.enc -d -a -out src/travis/secretring.gpg
-install:
- - echo "
- * The attribute system is built with a set of supported column types. This
- * class contains utilities to parse and convert supported types. It also
- * contains utilities to manipulate primitive arrays (the preferred array type)
- * and date/time types. Default time zone for parsing/printing dates is UTC.
+ * The attribute system is built with a set of supported column types. This class contains utilities to parse and
+ * convert supported types. It also contains utilities to manipulate primitive arrays (the preferred array type) and
+ * date/time types. Default time zone for parsing/printing dates is UTC.
*/
public class AttributeUtils {
@@ -105,11 +111,11 @@ public class AttributeUtils {
// These are used to avoid creating a lot of new instances of
// DateTimeFormatter
- private static final Map
- * For instance,
* This function transforms wrapped primitive arrays in primitive arrays.
*
@@ -744,8 +772,7 @@ private static List getStandardizedList(List list) {
}
}
if (oCls != null && !(isSimpleType(oCls) || isArrayType(oCls))) {
- throw new IllegalArgumentException("The list contains unsupported type " + oCls.getClass()
- .getCanonicalName());
+ throw new IllegalArgumentException("The list contains unsupported type " + oCls.getCanonicalName());
}
if (oCls != null) {
if (oCls.equals(Integer.class)) {
@@ -774,8 +801,8 @@ private static List getStandardizedList(List list) {
}
private static Set getStandardizedSet(Set set) {
- Class listClass = set.getClass();
- if (TYPED_LIST_TYPES.contains(listClass)) {
+ Class setClass = set.getClass();
+ if (TYPED_SET_TYPES.contains(setClass)) {
return set;
}
@@ -790,8 +817,7 @@ private static Set getStandardizedSet(Set set) {
}
}
if (oCls != null && !(isSimpleType(oCls) || isArrayType(oCls))) {
- throw new IllegalArgumentException("The set contains unsupported type " + oCls.getClass()
- .getCanonicalName());
+ throw new IllegalArgumentException("The set contains unsupported type " + oCls.getCanonicalName());
}
if (oCls != null) {
if (oCls.equals(Integer.class)) {
@@ -837,13 +863,12 @@ private static Map getStandardizedMap(Map, ?> map) {
}
}
if (value != null && !(isSimpleType(value.getClass()) || isArrayType(value.getClass()))) {
- throw new IllegalArgumentException("The map contains unsupported value type " + value.getClass()
- .getCanonicalName());
+ throw new IllegalArgumentException(
+ "The map contains unsupported value type " + value.getClass().getCanonicalName());
}
}
if (oCls != null && !isSimpleType(oCls)) {
- throw new IllegalArgumentException("The map contains unsupported key type " + oCls.getClass()
- .getCanonicalName());
+ throw new IllegalArgumentException("The map contains unsupported key type " + oCls.getCanonicalName());
}
if (oCls != null) {
if (oCls.equals(Integer.class)) {
@@ -883,14 +908,20 @@ public static boolean isNumberType(Class type) {
}
type = getStandardizedType(type);
return Number.class.isAssignableFrom(type) || int[].class.isAssignableFrom(type) || float[].class
- .isAssignableFrom(type) || double[].class.isAssignableFrom(type) || byte[].class.isAssignableFrom(type) || short[].class
- .isAssignableFrom(type) || long[].class.isAssignableFrom(type) || type
- .equals(TimestampIntegerMap.class) || type.equals(TimestampFloatMap.class) || type
- .equals(TimestampDoubleMap.class) || type.equals(TimestampLongMap.class) || type
- .equals(TimestampShortMap.class) || type.equals(TimestampByteMap.class) || type
- .equals(IntervalIntegerMap.class) || type.equals(IntervalFloatMap.class) || type
- .equals(IntervalDoubleMap.class) || type.equals(IntervalLongMap.class) || type
- .equals(IntervalShortMap.class) || type.equals(IntervalByteMap.class);
+ .isAssignableFrom(type) || double[].class.isAssignableFrom(type) || byte[].class
+ .isAssignableFrom(type) || short[].class.isAssignableFrom(type) || long[].class
+ .isAssignableFrom(type) || type.equals(TimestampIntegerMap.class) || type
+ .equals(TimestampFloatMap.class) || type
+ .equals(TimestampDoubleMap.class) || type
+ .equals(TimestampLongMap.class) || type
+ .equals(TimestampShortMap.class) || type
+ .equals(TimestampByteMap.class) || type
+ .equals(IntervalIntegerMap.class) || type
+ .equals(IntervalFloatMap.class) || type
+ .equals(IntervalDoubleMap.class) || type
+ .equals(IntervalLongMap.class) || type
+ .equals(IntervalShortMap.class) || type
+ .equals(IntervalByteMap.class);
}
/**
@@ -922,8 +953,8 @@ public static boolean isBooleanType(Class type) {
throw new IllegalArgumentException("Unsupported type " + type.getCanonicalName());
}
type = getStandardizedType(type);
- return type.equals(Boolean.class) || type.equals(boolean[].class) || type.equals(TimestampBooleanMap.class) || type
- .equals(IntervalBooleanMap.class);
+ return type.equals(Boolean.class) || type.equals(boolean[].class) || type
+ .equals(TimestampBooleanMap.class) || type.equals(IntervalBooleanMap.class);
}
/**
@@ -935,7 +966,7 @@ public static boolean isBooleanType(Class type) {
public static boolean isDynamicType(Class type) {
return (!type.equals(TimestampMap.class) && TimestampMap.class.isAssignableFrom(type)) || type
.equals(TimestampSet.class) || (!type.equals(IntervalMap.class) && IntervalMap.class
- .isAssignableFrom(type)) || type.equals(IntervalSet.class);
+ .isAssignableFrom(type)) || type.equals(IntervalSet.class);
}
/**
@@ -947,7 +978,8 @@ public static boolean isDynamicType(Class type) {
* @return true if type is a simple type, false otherwise
*/
public static boolean isSimpleType(Class type) {
- return (type.isPrimitive() && type != void.class) || type == Double.class || type == Float.class || type == Long.class || type == Integer.class || type == Short.class || type == Character.class || type == Byte.class || type == Boolean.class || type == String.class;
+ return (type
+ .isPrimitive() && type != void.class) || type == Double.class || type == Float.class || type == Long.class || type == Integer.class || type == Short.class || type == Character.class || type == Byte.class || type == Boolean.class || type == String.class;
}
/**
@@ -1002,46 +1034,50 @@ public static String getTypeName(Class type) {
* Parses the given time and returns its milliseconds representation.
*
* @param dateTime type to parse
- * @param timeZone time zone to use or null to use default time zone (UTC)
+ * @param zoneId time zone to use or null to use default time zone (UTC)
* @return milliseconds representation
+ * @throws DateTimeParseException if the time cannot be parsed
*/
- public static double parseDateTime(String dateTime, DateTimeZone timeZone) {
- return getDateTimeParserByTimeZone(timeZone).parseDateTime(dateTime).getMillis();
+ public static double parseDateTime(String dateTime, ZoneId zoneId) throws DateTimeParseException {
+ DateTimeFormatter dateTimeParserByTimeZone = getDateTimeParserByTimeZone(zoneId);
+ Instant instant = dateTimeParserByTimeZone.parse(dateTime, Instant::from);
+ return (double) instant.toEpochMilli();
}
/**
- * Parses the given time and returns its milliseconds representation.
- * Default time zone is used (UTC).
+ * Parses the given time and returns its milliseconds representation. Default time zone is used (UTC).
*
* @param dateTime the type to parse
* @return milliseconds representation
+ * @throws DateTimeParseException if the time cannot be parsed
*/
- public static double parseDateTime(String dateTime) {
+ public static double parseDateTime(String dateTime) throws DateTimeParseException {
return parseDateTime(dateTime, null);
}
/**
- * Parses an ISO date with or without time or a timestamp (in milliseconds).
- * Returns the date or timestamp converted to a timestamp in milliseconds.
+ * Parses an ISO date with or without time or a timestamp (in milliseconds). Returns the date or timestamp converted
+ * to a timestamp in milliseconds.
*
* @param timeStr Date or timestamp string
- * @param timeZone Time zone to use or null to use default time zone (UTC)
+ * @param zoneId Time zone to use or null to use default time zone (UTC)
* @return Timestamp
+ * @throws DateTimeParseException if the time cannot be parsed
*/
- public static double parseDateTimeOrTimestamp(String timeStr, DateTimeZone timeZone) {
- return FormattingAndParsingUtils.parseDateTimeOrTimestamp(timeStr, timeZone);
+ public static double parseDateTimeOrTimestamp(String timeStr, ZoneId zoneId) throws DateTimeParseException {
+ return FormattingAndParsingUtils.parseDateTimeOrTimestamp(timeStr, zoneId);
}
/**
- * Parses an ISO date with or without time or a timestamp (in milliseconds).
- * Returns the date or timestamp converted to a timestamp in milliseconds.
- * Default time zone is used (UTC).
+ * Parses an ISO date with or without time or a timestamp (in milliseconds). Returns the date or timestamp converted
+ * to a timestamp in milliseconds. Default time zone is used (UTC).
*
* @param timeStr Date or timestamp string
* @return Timestamp
+ * @throws DateTimeParseException if the time cannot be parsed
*/
- public static double parseDateTimeOrTimestamp(String timeStr) {
- return FormattingAndParsingUtils.parseDateTimeOrTimestamp(timeStr, null);
+ public static double parseDateTimeOrTimestamp(String timeStr) throws DateTimeParseException {
+ return FormattingAndParsingUtils.parseDateTimeOrTimestamp(timeStr);
}
/**
@@ -1058,19 +1094,31 @@ public static String printTimestamp(double timestamp) {
* Returns the date's string representation of the given timestamp.
*
* @param timestamp time, in milliseconds
- * @param timeZone time zone to use or null to use default time zone (UTC)
+ * @param zoneId time zone to use or null to use default time zone (UTC)
* @return formatted date
*/
- public static String printDate(double timestamp, DateTimeZone timeZone) {
+ public static String printDate(double timestamp, ZoneId zoneId) {
if (Double.isInfinite(timestamp) || Double.isNaN(timestamp)) {
return printTimestamp(timestamp);
}
- return getDatePrinterByTimeZone(timeZone).print((long) timestamp);
+ return printDate(Instant.ofEpochMilli((long) timestamp), zoneId);
+ }
+
+ /**
+ * Returns the date's string representation of the given instant.
+ *
+ * @param instant instant to format
+ * @param zoneId time zone to use or null to use default time zone (UTC)
+ * @return formatted date
+ */
+ public static String printDate(Instant instant, ZoneId zoneId) {
+ DateTimeFormatter datePrinterByTimeZone = getDatePrinterByTimeZone(zoneId);
+ ZonedDateTime zonedDateTime = instant.atZone(datePrinterByTimeZone.getZone());
+ return zonedDateTime.format(datePrinterByTimeZone);
}
/**
- * Returns the date's string representation of the given timestamp. Default
- * time zone is used (UTC).
+ * Returns the date's string representation of the given timestamp. Default time zone is used (UTC).
*
* @param timestamp time, in milliseconds
* @return formatted date
@@ -1083,19 +1131,32 @@ public static String printDate(double timestamp) {
* Returns the time's string representation of the given timestamp.
*
* @param timestamp time, in milliseconds
- * @param timeZone time zone to use or null to use default time zone (UTC)
+ * @param zoneId time zone to use or null to use default time zone (UTC)
* @return formatted time
*/
- public static String printDateTime(double timestamp, DateTimeZone timeZone) {
+ public static String printDateTime(double timestamp, ZoneId zoneId) {
if (Double.isInfinite(timestamp) || Double.isNaN(timestamp)) {
return printTimestamp(timestamp);
}
- return getDateTimePrinterByTimeZone(timeZone).print((long) timestamp);
+ return printDateTime(Instant.ofEpochMilli((long) timestamp), zoneId);
}
/**
- * Returns the time's tring representation of the given timestamp. Default
- * time zone is used (UTC).
+ * Returns the time's string representation of the given instant.
+ *
+ * @param instant instant to format
+ * @param zoneId time zone to use or null to use default time zone (UTC)
+ * @return formatted time
+ */
+ public static String printDateTime(Instant instant, ZoneId zoneId) {
+ DateTimeFormatter dateTimePrinterByTimeZone = getDateTimePrinterByTimeZone(zoneId);
+ ZonedDateTime zonedDateTime2 = instant.atZone(dateTimePrinterByTimeZone.getZone());
+ OffsetDateTime time = OffsetDateTime.from(zonedDateTime2);
+ return time.format(dateTimePrinterByTimeZone);
+ }
+
+ /**
+ * Returns the time's string representation of the given timestamp. Default time zone is used (UTC).
*
* @param timestamp time, in milliseconds
* @return formatted time
@@ -1105,20 +1166,19 @@ public static String printDateTime(double timestamp) {
}
/**
- * Returns the string representation of the given timestamp in the given
- * format.
+ * Returns the string representation of the given timestamp in the given format.
*
* @param timestamp time, in milliseconds
* @param timeFormat time format
- * @param timeZone time zone to use or null to use default time zone (UTC).
+ * @param zoneId time zone to use or null to use default time zone (UTC).
* @return formatted timestamp
*/
- public static String printTimestampInFormat(double timestamp, TimeFormat timeFormat, DateTimeZone timeZone) {
+ public static String printTimestampInFormat(double timestamp, TimeFormat timeFormat, ZoneId zoneId) {
switch (timeFormat) {
case DATE:
- return AttributeUtils.printDate(timestamp, timeZone);
+ return AttributeUtils.printDate(timestamp, zoneId);
case DATETIME:
- return AttributeUtils.printDateTime(timestamp, timeZone);
+ return AttributeUtils.printDateTime(timestamp, zoneId);
case DOUBLE:
return AttributeUtils.printTimestamp(timestamp);
}
@@ -1127,8 +1187,7 @@ public static String printTimestampInFormat(double timestamp, TimeFormat timeFor
}
/**
- * Returns the string representation of the given timestamp in the given
- * format. Default time zone is used (UTC).
+ * Returns the string representation of the given timestamp in the given format. Default time zone is used (UTC).
*
* @param timestamp time, in milliseconds
* @param timeFormat time format
@@ -1139,8 +1198,7 @@ public static String printTimestampInFormat(double timestamp, TimeFormat timeFor
}
/**
- * Returns the string representation of the given array. The used format is
- * the same format supported by
+ * Returns the string representation of the given array. The used format is the same format supported by
* {@link #parse(java.lang.String, java.lang.Class)} method
*
* @param arr Input array. Can be an array of objects or primitives.
@@ -1169,4 +1227,152 @@ public static boolean isNodeColumn(Column colum) {
public static boolean isEdgeColumn(Column colum) {
return colum.getTable().getElementClass().equals(Edge.class);
}
+
+ /**
+ * Returns a copy of the provided object.
+ *
+ * The copy is a deep copy for arrays, {@link IntervalSet}, {@link TimestampSet}, sets and lists
+ *
+ * @param obj object to copy
+ * @return copy of the provided object
+ */
+ public static Object copy(Object obj) {
+ if (obj == null) {
+ return null;
+ }
+ Class typeClass = obj.getClass();
+ if (!isSupported(typeClass)) {
+ throw new IllegalArgumentException("Unsupported type " + typeClass.getCanonicalName());
+ }
+ typeClass = getStandardizedType(typeClass);
+ obj = standardizeValue(obj);
+
+ // Primitive
+ if (isSimpleType(typeClass)) {
+ return obj;
+ }
+
+ // Instant
+ if (typeClass.equals(Instant.class)) {
+ return obj;
+ }
+
+ // Interval types:
+ if (typeClass.equals(IntervalSet.class)) {
+ return new IntervalSet((IntervalSet) obj);
+ } else if (typeClass.equals(IntervalStringMap.class)) {
+ return new IntervalStringMap((IntervalStringMap) obj);
+ } else if (typeClass.equals(IntervalByteMap.class)) {
+ return new IntervalByteMap((IntervalByteMap) obj);
+ } else if (typeClass.equals(IntervalShortMap.class)) {
+ return new IntervalShortMap((IntervalShortMap) obj);
+ } else if (typeClass.equals(IntervalIntegerMap.class)) {
+ return new IntervalIntegerMap((IntervalIntegerMap) obj);
+ } else if (typeClass.equals(IntervalLongMap.class)) {
+ return new IntervalLongMap((IntervalLongMap) obj);
+ } else if (typeClass.equals(IntervalFloatMap.class)) {
+ return new IntervalFloatMap((IntervalFloatMap) obj);
+ } else if (typeClass.equals(IntervalDoubleMap.class)) {
+ return new IntervalDoubleMap((IntervalDoubleMap) obj);
+ } else if (typeClass.equals(IntervalBooleanMap.class)) {
+ return new IntervalBooleanMap((IntervalBooleanMap) obj);
+ } else if (typeClass.equals(IntervalCharMap.class)) {
+ return new IntervalCharMap((IntervalCharMap) obj);
+ }
+
+ // Timestamp types:
+ if (typeClass.equals(TimestampSet.class)) {
+ return new TimestampSet((TimestampSet) obj);
+ } else if (typeClass.equals(TimestampStringMap.class)) {
+ return new TimestampStringMap((TimestampStringMap) obj);
+ } else if (typeClass.equals(TimestampByteMap.class)) {
+ return new TimestampByteMap((TimestampByteMap) obj);
+ } else if (typeClass.equals(TimestampShortMap.class)) {
+ return new TimestampShortMap((TimestampShortMap) obj);
+ } else if (typeClass.equals(TimestampIntegerMap.class)) {
+ return new TimestampIntegerMap((TimestampIntegerMap) obj);
+ } else if (typeClass.equals(TimestampLongMap.class)) {
+ return new TimestampLongMap((TimestampLongMap) obj);
+ } else if (typeClass.equals(TimestampFloatMap.class)) {
+ return new TimestampFloatMap((TimestampFloatMap) obj);
+ } else if (typeClass.equals(TimestampDoubleMap.class)) {
+ return new TimestampDoubleMap((TimestampDoubleMap) obj);
+ } else if (typeClass.equals(TimestampBooleanMap.class)) {
+ return new TimestampBooleanMap((TimestampBooleanMap) obj);
+ } else if (typeClass.equals(TimestampCharMap.class)) {
+ return new TimestampCharMap((TimestampCharMap) obj);
+ }
+
+ // Array
+ if (isArrayType(typeClass)) {
+ Class componentType = typeClass.getComponentType();
+ int length = Array.getLength(obj);
+ Object dest = Array.newInstance(componentType, length);
+ System.arraycopy(obj, 0, dest, 0, length);
+ return dest;
+ }
+
+ // List
+ if (obj instanceof CharArrayList) {
+ return new CharArrayList((CharArrayList) obj);
+ } else if (obj instanceof BooleanArrayList) {
+ return new BooleanArrayList((BooleanArrayList) obj);
+ } else if (obj instanceof ByteArrayList) {
+ return new ByteArrayList((ByteArrayList) obj);
+ } else if (obj instanceof ShortArrayList) {
+ return new ShortArrayList((ShortArrayList) obj);
+ } else if (obj instanceof IntArrayList) {
+ return new IntArrayList((IntArrayList) obj);
+ } else if (obj instanceof LongArrayList) {
+ return new LongArrayList((LongArrayList) obj);
+ } else if (obj instanceof FloatArrayList) {
+ return new FloatArrayList((FloatArrayList) obj);
+ } else if (obj instanceof DoubleArrayList) {
+ return new DoubleArrayList((DoubleArrayList) obj);
+ } else if (obj instanceof ObjectArrayList) {
+ return new ObjectArrayList((ObjectArrayList) obj);
+ }
+
+ // Map
+ if (obj instanceof Char2ObjectOpenHashMap) {
+ return new Char2ObjectOpenHashMap((Char2ObjectOpenHashMap) obj);
+ } else if (obj instanceof Byte2ObjectOpenHashMap) {
+ return new Byte2ObjectOpenHashMap((Byte2ObjectOpenHashMap) obj);
+ } else if (obj instanceof Short2ObjectOpenHashMap) {
+ return new Short2ObjectOpenHashMap((Short2ObjectOpenHashMap) obj);
+ } else if (obj instanceof Int2ObjectOpenHashMap) {
+ return new Int2ObjectOpenHashMap((Int2ObjectOpenHashMap) obj);
+ } else if (obj instanceof Long2ObjectOpenHashMap) {
+ return new Long2ObjectOpenHashMap((Long2ObjectOpenHashMap) obj);
+ } else if (obj instanceof Float2ObjectOpenHashMap) {
+ return new Float2ObjectOpenHashMap((Float2ObjectOpenHashMap) obj);
+ } else if (obj instanceof Double2ObjectOpenHashMap) {
+ return new Double2ObjectOpenHashMap((Double2ObjectOpenHashMap) obj);
+ } else if (obj instanceof Object2ObjectOpenHashMap) {
+ return new Object2ObjectOpenHashMap((Object2ObjectOpenHashMap) obj);
+ }
+
+ // Set
+ if (obj instanceof CharOpenHashSet) {
+ return new CharOpenHashSet((CharOpenHashSet) obj);
+ } else if (obj instanceof BooleanOpenHashSet) {
+ return new BooleanOpenHashSet((BooleanOpenHashSet) obj);
+ } else if (obj instanceof ByteOpenHashSet) {
+ return new ByteOpenHashSet((ByteOpenHashSet) obj);
+ } else if (obj instanceof ShortOpenHashSet) {
+ return new ShortOpenHashSet((ShortOpenHashSet) obj);
+ } else if (obj instanceof IntOpenHashSet) {
+ return new IntOpenHashSet((IntOpenHashSet) obj);
+ } else if (obj instanceof LongOpenHashSet) {
+ return new LongOpenHashSet((LongOpenHashSet) obj);
+ } else if (obj instanceof FloatOpenHashSet) {
+ return new FloatOpenHashSet((FloatOpenHashSet) obj);
+ } else if (obj instanceof DoubleOpenHashSet) {
+ return new DoubleOpenHashSet((DoubleOpenHashSet) obj);
+ } else if (obj instanceof ObjectOpenHashSet) {
+ return new ObjectOpenHashSet((ObjectOpenHashSet) obj);
+ }
+
+ return obj;
+ }
}
diff --git a/store/src/main/java/org/gephi/graph/api/Column.java b/src/main/java/org/gephi/graph/api/Column.java
similarity index 84%
rename from store/src/main/java/org/gephi/graph/api/Column.java
rename to src/main/java/org/gephi/graph/api/Column.java
index 45f75e14..9d52d2ed 100644
--- a/store/src/main/java/org/gephi/graph/api/Column.java
+++ b/src/main/java/org/gephi/graph/api/Column.java
@@ -18,8 +18,7 @@
/**
* A column belongs to a table and represent a dimension in the data.
*
- * A column has primarily a unique identifier and a type, which both are set at
- * the creation time.
+ * A column has primarily a unique identifier and a type, which both are set at the creation time.
*
* @see Table
*/
@@ -33,8 +32,7 @@ public interface Column {
public String getId();
/**
- * Returns the column's integer index, which is the position of the column
- * in the store.
+ * Returns the column's integer index, which is the position of the column in the store.
*
* @return the column's index
*/
@@ -96,6 +94,13 @@ public interface Column {
*/
public boolean isDynamic();
+ /**
+ * Returns true if this column is dynamic and has a TimeMap type.
+ *
+ * @return true if dynamic attribute type, false otherwise
+ */
+ public boolean isDynamicAttribute();
+
/**
* Returns true if this column has a number type.
*
@@ -103,11 +108,17 @@ public interface Column {
*/
public boolean isNumber();
+ /**
+ * Returns true if this column exists and belong to a table.
+ *
+ * @return true if exists, false otherwise
+ */
+ public boolean exists();
+
/**
* Returns true if this column is a property.
*
- * This is equivalent to test if the column's origin is
- * Origin.PROPERTY
+ * This is equivalent to test if the column's origin is Origin.PROPERTY
*
* @return true if property, false otherwise
*/
@@ -139,6 +150,7 @@ public interface Column {
*
* @param withDiff true if column observer should provide column differences
* @return the column observer
+ * @throws UnsupportedOperationException if observers are disabled (from Configuration)
*/
public ColumnObserver createColumnObserver(boolean withDiff);
}
diff --git a/store/src/main/java/org/gephi/graph/api/ColumnDiff.java b/src/main/java/org/gephi/graph/api/ColumnDiff.java
similarity index 93%
rename from store/src/main/java/org/gephi/graph/api/ColumnDiff.java
rename to src/main/java/org/gephi/graph/api/ColumnDiff.java
index deaf8703..5252168c 100644
--- a/store/src/main/java/org/gephi/graph/api/ColumnDiff.java
+++ b/src/main/java/org/gephi/graph/api/ColumnDiff.java
@@ -18,8 +18,8 @@
/**
* Interface to retrieve elements touched in a column.
*
- * This interface is associated with a {@link ColumnObserver} and provides an
- * easy access to the elements which value has been modified.
+ * This interface is associated with a {@link ColumnObserver} and provides an easy access to the elements which value
+ * has been modified.
*/
public interface ColumnDiff {
diff --git a/src/main/java/org/gephi/graph/api/ColumnIndex.java b/src/main/java/org/gephi/graph/api/ColumnIndex.java
new file mode 100644
index 00000000..0508d18f
--- /dev/null
+++ b/src/main/java/org/gephi/graph/api/ColumnIndex.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2012-2013 Gephi Consortium
+ *
+ * Licensed 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.gephi.graph.api;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A column index is associated with a column and keeps track of each unique value and can also return the minimum and
+ * maximum values in case of a sortable value type.
+ *
+ * @param
+ * Only applies for sortable indices.
+ *
+ * @return the minimum value
+ */
+ Number getMinValue();
+
+ /**
+ * Returns the maximum value.
+ *
+ * Only applies for sortable indices.
+ *
+ * @return the maximum value
+ */
+ Number getMaxValue();
+
+ /**
+ * Returns the column for which this column index belongs to.
+ *
+ * @return the column
+ */
+ Column getColumn();
+
+ /**
+ * Returns the index's version. The version is incremented every time the index is modified.
+ *
+ * @return index's version
+ */
+ int getVersion();
+}
diff --git a/store/src/main/java/org/gephi/graph/api/ColumnIterable.java b/src/main/java/org/gephi/graph/api/ColumnIterable.java
similarity index 100%
rename from store/src/main/java/org/gephi/graph/api/ColumnIterable.java
rename to src/main/java/org/gephi/graph/api/ColumnIterable.java
diff --git a/store/src/main/java/org/gephi/graph/api/ColumnObserver.java b/src/main/java/org/gephi/graph/api/ColumnObserver.java
similarity index 74%
rename from store/src/main/java/org/gephi/graph/api/ColumnObserver.java
rename to src/main/java/org/gephi/graph/api/ColumnObserver.java
index 18137585..89d8368a 100644
--- a/store/src/main/java/org/gephi/graph/api/ColumnObserver.java
+++ b/src/main/java/org/gephi/graph/api/ColumnObserver.java
@@ -18,20 +18,18 @@
/**
* Observer over a column to monitor changes in the attributes values.
*
- * Column observer can be used to periodically monitor changes made to a column.
- * This scenario is common is multi-threaded applications where a thread is
- * responsible to take action when something has changed in the column's data.
+ * Column observer can be used to periodically monitor changes made to a column. This scenario is common is
+ * multi-threaded applications where a thread is responsible to take action when something has changed in the column's
+ * data.
*
- * Column observer users should periodically call the
- *
- * This observer monitors all the rows for this column and consider something
- * has changed when an element's value for this column has been changed.
+ * This observer monitors all the rows for this column and consider something has changed when an element's value for
+ * this column has been changed.
*
- * Observers should be destroyed when not needed anymore. A new observer can be
- * obtained from the
+ * This class can be passed as a parameter to {@link GraphModel.Factory#newInstance(org.gephi.graph.api.Configuration)}
+ * to create a GraphModel with custom configuration.
+ *
+ * Create instances by using the builder:
+ *
+ *
+ * Note that setting configurations after the GraphModel has been created won't have any effect.
+ *
+ * By default, both node and edge id types are
+ * See the builder documentation for more information on default values.
+ *
+ * @see GraphModel
+ * @see Builder
+ */
+public class Configuration {
+
+ private ConfigurationImpl delegate;
+
+ /**
+ * Default constructor.
+ *
+ * @deprecated Use the
+ *
+ * Note that this class is not thread-safe.
+ */
+ public static class Builder {
+
+ private ConfigurationImpl configuration;
+
+ private Builder() {
+ configuration = new ConfigurationImpl();
+ }
+
+ private Builder(ConfigurationImpl configuration) {
+ this.configuration = configuration;
+ }
+
+ /**
+ * Builds the configuration.
+ *
+ * @return the configuration
+ */
+ public Configuration build() {
+ // Check for potential inconsistencies
+ if (!configuration.isEnableNodeProperties() && configuration.isEnableSpatialIndex()) {
+ throw new IllegalStateException("Spatial index can't be enabled if node properties are disabled");
+ }
+
+ return new Configuration(configuration);
+ }
+
+ /**
+ * Sets the node id type.
+ *
+ * Only simple types such as primitives, wrappers and String are supported.
+ *
+ * Default is
+ * Only simple types such as primitives, wrappers and String are supported.
+ *
+ * Default is
+ * Only simple types such as primitives, wrappers and String are supported.
+ *
+ * Default is
+ *
+ * Default is
+ * Default is
+ * Default is
+ * Default is
+ * If enabled, edge types are automatically registered when edges are added. If disabled, one needs to call
+ * {@link GraphModel#addEdgeType(Object)} explicitly for each type.
+ *
+ * Default is
+ * If enabled, {@link NodeProperties} are created for each node. If those properties aren't needed, disabling
+ * them can save memory.
+ *
+ * Default is
+ * If enabled, {@link EdgeProperties} are created for each edge. If those properties aren't needed, disabling
+ * them can save memory.
+ *
+ * Default is
+ * If enabled, the spatial index is updated while node positions are updated. If unused, disabling it is
+ * recommended as it adds some overhead.
+ *
+ * The spatial index can be retrieved from {@link Graph#getSpatialIndex()}.
+ *
+ * Default is
+ * If enabled, the reverse index is updated while node attributes are updated. This powers
+ * {@link GraphModel#getNodeIndex()} but has a negative impact on memory usage (as any reverse index does). When
+ * disabled, the features of {@link Index
+ * Default is
+ * If enabled, the reverse index is updated while node attributes are updated. This powers
+ * {@link GraphModel#getEdgeIndex()} but has a negative impact on memory usage (as any reverse index does). When
+ * disabled, the features of {@link Index
+ * Default is
+ * If enabled, the reverse index is updated while element's time set is updated. This powers
+ * {@link GraphModel#getNodeTimeIndex()} and {@link GraphModel#getEdgeTimeIndex()} ()} but has a negative impact
+ * on memory usage (as any reverse index does).
+ *
+ * Default is
+ * If disabled, only a single edge of a given type can exist between two nodes.
+ *
+ * Default is
+ * If disabled, the client is responsible for handling multithreading themselves or calling methods such as
+ * {@link Graph#readLock()} or {@link Graph#writeLock()}. If enabled, each read methods (including iterators)
+ * handle locking. Similarly, each write method handle locking.
+ *
+ * Default is
+ * Only simple types such as primitives, wrappers and String are supported.
+ *
+ * @deprecated Use {@link #builder()} instead.
+ *
+ * @param nodeIdType node id type
+ * @throws IllegalArgumentException if the type isn't supported
+ */
+ @Deprecated
+ public void setNodeIdType(Class nodeIdType) {
+ this.delegate = new Builder(this.delegate).nodeIdType(nodeIdType).configuration;
+ }
+
+ /**
+ * Returns the edge id type.
+ *
+ * @return edge id type
+ */
+ public Class getEdgeIdType() {
+ return delegate.getEdgeIdType();
+ }
+
+ /**
+ * Sets the edge id type.
+ *
+ * Only simple types such as primitives, wrappers and String are supported.
+ *
+ * @deprecated Use {@link #builder()} instead.
+ *
+ * @param edgeIdType edge id type
+ * @throws IllegalArgumentException if the type isn't supported
+ */
+ @Deprecated
+ public void setEdgeIdType(Class edgeIdType) {
+ this.delegate = new Builder(this.delegate).edgeIdType(edgeIdType).configuration;
+ }
+
+ /**
+ * Returns the edge label type.
+ *
+ * @return edge label type
+ */
+ public Class getEdgeLabelType() {
+ return delegate.getEdgeLabelType();
+ }
+
+ /**
+ * Sets the edge label type.
+ *
+ * @deprecated Use {@link #builder()} instead.
+ *
+ * @param edgeLabelType edge label type
+ * @throws IllegalArgumentException if the type isn't supported
+ */
+ @Deprecated
+ public void setEdgeLabelType(Class edgeLabelType) {
+ this.delegate = new Builder(this.delegate).edgeLabelType(edgeLabelType).configuration;
+ }
+
+ /**
+ * Returns the edge weight type.
+ *
+ * @return edge weight type
+ */
+ public Class getEdgeWeightType() {
+ return delegate.getEdgeWeightType();
+ }
+
+ /**
+ * Sets the edge weight type.
+ *
+ * @deprecated Use {@link #builder()} instead.
+ *
+ * @param edgeWeightType edge weight type
+ * @throws IllegalArgumentException if the type isn't supported
+ */
+ @Deprecated
+ public void setEdgeWeightType(Class edgeWeightType) {
+ this.delegate = new Builder(this.delegate).edgeWeightType(edgeWeightType).configuration;
+ }
+
+ /**
+ * Returns the time representation.
+ *
+ * @return time representation
+ */
+ public TimeRepresentation getTimeRepresentation() {
+ return delegate.getTimeRepresentation();
+ }
+
+ /**
+ * Sets the time representation.
+ *
+ * @deprecated Use {@link #builder()} instead.
+ *
+ * @param timeRepresentation time representation
+ */
+ @Deprecated
+ public void setTimeRepresentation(TimeRepresentation timeRepresentation) {
+ this.delegate = new Builder(this.delegate).timeRepresentation(timeRepresentation).configuration;
+ }
+
+ /**
+ * Returns whether an edge weight column is created.
+ *
+ * @return edge weight column
+ */
+ public Boolean getEdgeWeightColumn() {
+ return delegate.isEdgeWeightColumn();
+ }
+
+ /**
+ * Sets whether to create an edge weight column.
+ *
+ *
+ * @deprecated Use {@link #builder()} instead.
+ *
+ * @param edgeWeightColumn edge weight column
+ */
+ @Deprecated
+ public void setEdgeWeightColumn(Boolean edgeWeightColumn) {
+ this.delegate = new Builder(this.delegate).edgeWeightColumn(edgeWeightColumn).configuration;
+ }
+
+ public boolean isEnableAutoLocking() {
+ return delegate.isEnableAutoLocking();
+ }
+
+ public boolean isEnableAutoEdgeTypeRegistration() {
+ return delegate.isEnableAutoEdgeTypeRegistration();
+ }
+
+ public boolean isEnableIndexNodes() {
+ return delegate.isEnableIndexNodes();
+ }
+
+ public boolean isEnableIndexEdges() {
+ return delegate.isEnableIndexEdges();
+ }
+
+ public boolean isEnableIndexTime() {
+ return delegate.isEnableIndexTime();
+ }
+
+ public boolean isEnableObservers() {
+ return delegate.isEnableObservers();
+ }
+
+ public boolean isEnableNodeProperties() {
+ return delegate.isEnableNodeProperties();
+ }
+
+ public boolean isEnableEdgeProperties() {
+ return delegate.isEnableEdgeProperties();
+ }
+
+ public boolean isEnableSpatialIndex() {
+ return delegate.isEnableSpatialIndex();
+ }
+
+ public boolean isEnableParallelEdgesSameType() {
+ return delegate.isEnableParallelEdgesSameType();
+ }
+
+ /**
+ * Copy this configuration.
+ *
+ * @return a copy of this configuration
+ */
+ public Configuration copy() {
+ return new Configuration(delegate);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof Configuration)) {
+ return false;
+ }
+
+ Configuration that = (Configuration) o;
+
+ return delegate.equals(that.delegate);
+ }
+
+ @Override
+ public int hashCode() {
+ return delegate.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return delegate.toString();
+ }
+
+ /**
+ * Returns a string representation of the differences between this configuration and another one.
+ *
+ * @param other the other configuration
+ * @return a string representation of the differences
+ */
+ public String diffAsString(Configuration other) {
+ return delegate.diffAsString(other.delegate);
+ }
+}
diff --git a/store/src/main/java/org/gephi/graph/api/DirectedGraph.java b/src/main/java/org/gephi/graph/api/DirectedGraph.java
similarity index 96%
rename from store/src/main/java/org/gephi/graph/api/DirectedGraph.java
rename to src/main/java/org/gephi/graph/api/DirectedGraph.java
index b34f80c1..08c232b2 100644
--- a/store/src/main/java/org/gephi/graph/api/DirectedGraph.java
+++ b/src/main/java/org/gephi/graph/api/DirectedGraph.java
@@ -18,8 +18,8 @@
/**
* Directed graph.
*
- * This interface has additional methods specific to directed graphs compared to
- * the Graph interface it inherits from.
+ * This interface has additional methods specific to directed graphs compared to the Graph interface it
+ * inherits from.
*/
public interface DirectedGraph extends Graph {
@@ -34,8 +34,7 @@ public interface DirectedGraph extends Graph {
public Edge getEdge(Node source, Node target);
/**
- * Gets the edge adjacent to source and target with an edge of the given
- * type.
+ * Gets the edge adjacent to source and target with an edge of the given type.
*
* @param source the source node
* @param target the target node
@@ -56,8 +55,7 @@ public interface DirectedGraph extends Graph {
public boolean isAdjacent(Node source, Node target);
/**
- * Returns true if source and target are adjacent with an edge of the given
- * type.
+ * Returns true if source and target are adjacent with an edge of the given type.
*
* @param source the source node
* @param target the target node
@@ -146,8 +144,7 @@ public interface DirectedGraph extends Graph {
/**
* Gets the edge in the other direction of the given edge.
*
- * This takes in account the edge type so only edges of the same type can be
- * mutual.
+ * This takes in account the edge type so only edges of the same type can be mutual.
*
* @param edge the edge to get the mutual edge
* @return the mutual edge, or null
diff --git a/store/src/main/java/org/gephi/graph/api/DirectedSubgraph.java b/src/main/java/org/gephi/graph/api/DirectedSubgraph.java
similarity index 100%
rename from store/src/main/java/org/gephi/graph/api/DirectedSubgraph.java
rename to src/main/java/org/gephi/graph/api/DirectedSubgraph.java
diff --git a/store/src/main/java/org/gephi/graph/api/Edge.java b/src/main/java/org/gephi/graph/api/Edge.java
similarity index 90%
rename from store/src/main/java/org/gephi/graph/api/Edge.java
rename to src/main/java/org/gephi/graph/api/Edge.java
index e0d596ff..022678e4 100644
--- a/store/src/main/java/org/gephi/graph/api/Edge.java
+++ b/src/main/java/org/gephi/graph/api/Edge.java
@@ -62,8 +62,7 @@ public interface Edge extends Element, EdgeProperties {
/**
* Returns the edge's weight in the given graph view.
*
- * Views can configure a time interval and therefore the edge weight over
- * time may vary.
+ * Views can configure a time interval and therefore the edge weight over time may vary.
*
* @param view graph view
* @return weight
@@ -114,6 +113,13 @@ public interface Edge extends Element, EdgeProperties {
*/
public int getType();
+ /**
+ * Sets the edge's type.
+ *
+ * @param type the type
+ */
+ public void setType(int type);
+
/**
* Returns the edge's type label.
*
@@ -134,4 +140,11 @@ public interface Edge extends Element, EdgeProperties {
* @return true if directed, false otherwise
*/
public boolean isDirected();
+
+ /**
+ * Returns true if this edge is directed and another edge exists in the opposite direction.
+ *
+ * @return true if mutual, false otherwise
+ */
+ public boolean isMutual();
}
diff --git a/store/src/main/java/org/gephi/graph/api/EdgeIterable.java b/src/main/java/org/gephi/graph/api/EdgeIterable.java
similarity index 69%
rename from store/src/main/java/org/gephi/graph/api/EdgeIterable.java
rename to src/main/java/org/gephi/graph/api/EdgeIterable.java
index 69a243e7..79c7b254 100644
--- a/store/src/main/java/org/gephi/graph/api/EdgeIterable.java
+++ b/src/main/java/org/gephi/graph/api/EdgeIterable.java
@@ -19,6 +19,9 @@
import java.util.Collections;
import java.util.Iterator;
import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.Spliterators;
/**
* An edge iterable.
@@ -54,10 +57,31 @@ public interface EdgeIterable extends ElementIterable
+ * Implementations return a splittable, sized, fail-fast spliterator suitable for parallel streams. When not
+ * possible, a non-splittable spliterator is returned.
+ *
+ * @return edge spliterator
+ */
+ @Override
+ default Spliterator
+ * For dynamic columns the returned {@link org.gephi.graph.api.types.TimeMap TimeMap} or
+ * {@link org.gephi.graph.api.types.TimeSet TimeSet} is the instance held by this element. Mutating it directly
+ * leaves the time index stale: use the
+ * For dynamic columns the returned {@link org.gephi.graph.api.types.TimeMap TimeMap} or
+ * {@link org.gephi.graph.api.types.TimeSet TimeSet} is the instance held by this element. Mutating it directly
+ * leaves the time index stale: use the
+ * The time bounds is an interval made of the minimum and maximum time observed in this element.
+ *
+ * @return time bounds
+ */
+ public Interval getTimeBounds();
+
/**
* Clears all attribute values.
*/
diff --git a/store/src/main/java/org/gephi/graph/api/ElementIterable.java b/src/main/java/org/gephi/graph/api/ElementIterable.java
similarity index 71%
rename from store/src/main/java/org/gephi/graph/api/ElementIterable.java
rename to src/main/java/org/gephi/graph/api/ElementIterable.java
index 09eb3eb6..c22417b6 100644
--- a/store/src/main/java/org/gephi/graph/api/ElementIterable.java
+++ b/src/main/java/org/gephi/graph/api/ElementIterable.java
@@ -19,6 +19,11 @@
import java.util.Collections;
import java.util.Iterator;
import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
/**
* Element iterable.
@@ -40,6 +45,24 @@ public interface ElementIterable
- * Estimators are associated with actions that require to transform a sorted set
- * of values over time into a single value.
+ * Estimators are associated with actions that require to transform a sorted set of values over time into a single
+ * value.
*/
public enum Estimator {
@@ -59,8 +59,7 @@ public boolean is(Estimator estimator) {
}
/**
- * Returns true if this estimator is any of the given
- *
+ * The version gets altered when the graph structure changes.
+ *
+ * @see GraphObserver for a more sophisticated way to track changes
+ * @return graph version
+ */
+ public int getVersion();
+
/**
* Returns true if this graph is directed.
*
@@ -499,5 +547,18 @@ public interface Graph {
*/
public void writeUnlock();
- public SpatialContext getSpatialContext();
+ /**
+ * Returns the graph lock, in case locking is enabled. The graph lock controls the multi-thread access to the graph
+ * structure.
+ *
+ * @return graph lock
+ */
+ GraphLock getLock();
+
+ /**
+ * Returns the spatial index.
+ *
+ * @return spatial index
+ */
+ SpatialIndex getSpatialIndex();
}
diff --git a/store/src/main/java/org/gephi/graph/api/GraphBridge.java b/src/main/java/org/gephi/graph/api/GraphBridge.java
similarity index 75%
rename from store/src/main/java/org/gephi/graph/api/GraphBridge.java
rename to src/main/java/org/gephi/graph/api/GraphBridge.java
index d2c1f898..8d413104 100644
--- a/store/src/main/java/org/gephi/graph/api/GraphBridge.java
+++ b/src/main/java/org/gephi/graph/api/GraphBridge.java
@@ -18,27 +18,23 @@
/**
* Helper that helps transfer elements from another graph store.
*
- * This bridge can be used to insert elements that belong to another graph in
- * this graph store. It operates a deep copy so the destination elements are
- * independent from the source and have exactly the same properties and
- * attributes.
+ * This bridge can be used to insert elements that belong to another graph in this graph store. It operates a deep copy
+ * so the destination elements are independent from the source and have exactly the same properties and attributes.
*/
public interface GraphBridge {
/**
* Copy the given nodes to the current graph store.
*
- * The
- * All edges attached to
- * This operation takes care of copying attribute columns and values, edge
- * type labels and element properties.
+ * This operation takes care of copying attribute columns and values, edge type labels and element properties.
*
- * Beware that the source's configuration should match this graph store
- * configuration.
+ * Beware that the source's configuration should match this graph store configuration.
*
* @param nodes nodes to copy
*/
diff --git a/store/src/main/java/org/gephi/graph/api/GraphDiff.java b/src/main/java/org/gephi/graph/api/GraphDiff.java
similarity index 95%
rename from store/src/main/java/org/gephi/graph/api/GraphDiff.java
rename to src/main/java/org/gephi/graph/api/GraphDiff.java
index a3c2c085..1c95ed51 100644
--- a/store/src/main/java/org/gephi/graph/api/GraphDiff.java
+++ b/src/main/java/org/gephi/graph/api/GraphDiff.java
@@ -18,8 +18,8 @@
/**
* Interface to retrieve added and removed elements from the graph.
*
- * This interface is associated with a {@link GraphObserver} and provides an
- * easy access to the elements added or removed.
+ * This interface is associated with a {@link GraphObserver} and provides an easy access to the elements added or
+ * removed.
*/
public interface GraphDiff {
diff --git a/store/src/main/java/org/gephi/graph/api/GraphFactory.java b/src/main/java/org/gephi/graph/api/GraphFactory.java
similarity index 97%
rename from store/src/main/java/org/gephi/graph/api/GraphFactory.java
rename to src/main/java/org/gephi/graph/api/GraphFactory.java
index 36d85cff..fdb7c302 100644
--- a/store/src/main/java/org/gephi/graph/api/GraphFactory.java
+++ b/src/main/java/org/gephi/graph/api/GraphFactory.java
@@ -20,8 +20,8 @@
*
* All new nodes and edges are created by this factory.
*
- * Both nodes and edges have unique identifiers. If not provided, a unique id
- * will be automatically assigned to the elements.
+ * Both nodes and edges have unique identifiers. If not provided, a unique id will be automatically assigned to the
+ * elements.
*/
public interface GraphFactory {
diff --git a/src/main/java/org/gephi/graph/api/GraphLock.java b/src/main/java/org/gephi/graph/api/GraphLock.java
new file mode 100644
index 00000000..5ae4d08c
--- /dev/null
+++ b/src/main/java/org/gephi/graph/api/GraphLock.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2012-2013 Gephi Consortium
+ *
+ * Licensed 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.gephi.graph.api;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Wrapper around
+ * This call waits without bound. A read hold blocks every writer, and once a writer is waiting, new readers wait
+ * behind it as well, so a read hold that is never released stalls all graph operations. Do not hold the read lock
+ * across a wait on another thread, and do not abandon an auto-locking iterator (see {@link NodeIterable} and
+ * {@link EdgeIterable}) before it is exhausted or {@code doBreak()} has been called. Use
+ * {@link #tryReadLock(long, TimeUnit)} when the caller cannot afford to wait indefinitely.
+ */
+ void readLock();
+
+ /**
+ * Attempts to release this lock. If the number of readers is now zero then the lock is made available for write
+ * lock attempts. If the current thread does not hold this lock then IllegalMonitorStateException is thrown.
+ *
+ * @throws IllegalMonitorStateException if the current thread does not hold this lock
+ */
+ void readUnlock();
+
+ /**
+ * Release this lock by releasing all current read locks.
+ */
+ void readUnlockAll();
+
+ /**
+ * Acquires the write lock. Acquires the write lock if neither the read nor write lock are held by another thread
+ * and returns immediately, setting the write lock hold count to one.
+ *
+ * @throws IllegalMonitorStateException if the current thread holds a read lock already
+ * @see #tryWriteLock(long, TimeUnit)
+ */
+ void writeLock();
+
+ /**
+ * Attempts to release this lock. If the current thread is the holder of this lock then the hold count is
+ * decremented. If the hold count is now zero then the lock is released. If the current thread is not the holder of
+ * this lock then IllegalMonitorStateException is thrown.
+ *
+ * throws @IllegalMonitorStateException if the current thread does not hold this lock
+ */
+ void writeUnlock();
+
+ /**
+ * Queries the number of reentrant read holds on this lock by the current thread. A reader thread has a hold on a
+ * lock for each lock action that is not matched by an unlock action.
+ *
+ * @return the number of holds on the read lock by the current thread, or zero if the read lock is not held by the
+ * current thread
+ */
+ int getReadHoldCount();
+
+ /**
+ * Queries the number of reentrant write holds on this lock by the current thread. A writer thread has a hold on a
+ * lock for each lock action that is not matched by an unlock action.
+ *
+ * @return the number of holds on the write lock by the current thread, or zero if the write lock is not held by the
+ * current thread
+ */
+ int getWriteHoldCount();
+
+ /**
+ * Acquires the read lock if the write lock is not held by another thread within the given waiting time.
+ *
+ * Unlike {@link #readLock()}, the wait is bounded and interruptible. A caller that receives {@code false} has not
+ * acquired the lock and must not call {@link #readUnlock()}.
+ *
+ * @param timeout the time to wait for the read lock
+ * @param unit the time unit of the timeout argument
+ * @return true if the read lock was acquired
+ * @throws InterruptedException if the current thread is interrupted while waiting
+ * @throws UnsupportedOperationException if the implementation does not support timed acquisition
+ */
+ default boolean tryReadLock(long timeout, TimeUnit unit) throws InterruptedException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Acquires the write lock if neither the read nor write lock are held by another thread within the given waiting
+ * time.
+ *
+ * Unlike {@link #writeLock()}, the wait is bounded and interruptible. A caller that receives {@code false} has not
+ * acquired the lock and must not call {@link #writeUnlock()}.
+ *
+ * @param timeout the time to wait for the write lock
+ * @param unit the time unit of the timeout argument
+ * @return true if the write lock was acquired
+ * @throws IllegalMonitorStateException if the current thread holds a read lock already
+ * @throws InterruptedException if the current thread is interrupted while waiting
+ * @throws UnsupportedOperationException if the implementation does not support timed acquisition
+ */
+ default boolean tryWriteLock(long timeout, TimeUnit unit) throws InterruptedException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Queries the number of read holds on this lock across all threads. This differs from {@link #getReadHoldCount()},
+ * which counts only the current thread. A non-zero value while no thread is expected to be reading points at a read
+ * hold that was never released.
+ *
+ * @return the total number of read holds, or zero if the read lock is not held
+ * @throws UnsupportedOperationException if the implementation does not expose this
+ */
+ default int getReadLockCount() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Queries whether the write lock is held by any thread.
+ *
+ * @return true if any thread holds the write lock
+ * @throws UnsupportedOperationException if the implementation does not expose this
+ */
+ default boolean isWriteLocked() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns an estimate of the number of threads waiting to acquire either the read or the write lock. The value is
+ * an estimate because the number of threads may change while this method traverses internal data structures. It is
+ * designed for monitoring, not for synchronization control.
+ *
+ * @return the estimated number of waiting threads
+ * @throws UnsupportedOperationException if the implementation does not expose this
+ */
+ default int getQueueLength() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/store/src/main/java/org/gephi/graph/api/GraphModel.java b/src/main/java/org/gephi/graph/api/GraphModel.java
similarity index 63%
rename from store/src/main/java/org/gephi/graph/api/GraphModel.java
rename to src/main/java/org/gephi/graph/api/GraphModel.java
index 493f064d..d89a1703 100644
--- a/store/src/main/java/org/gephi/graph/api/GraphModel.java
+++ b/src/main/java/org/gephi/graph/api/GraphModel.java
@@ -18,72 +18,66 @@
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
+import java.time.ZoneId;
+import java.util.function.Predicate;
import org.gephi.graph.impl.GraphModelImpl;
-import org.joda.time.DateTimeZone;
/**
* Graph API's entry point.
*
- *
* New instances can be obtained via the embedded factory:
- *
+ *
*
- * Then,
- * The
- * Any number of attributes can be associated to elements but are managed
- * through the
- * Attributes are automatically indexed and information such as the number of
- * elements with a particular value can be obtained from the
- * Finally, this API supports the concept of graph views. A view is a mask on
- * the graph structure and represents a subgraph. The user controls the set of
- * nodes and edges in the view by obtaining a
* Elements should be created through the {@link #factory() } method.
*
- * For performance reasons, edge labels are internally represented as integers
- * and the mapping between arbitrary labels is managed through the
- * {@link #addEdgeType(java.lang.Object)
- * } and
- * {@link #getEdgeType(java.lang.Object) } methods. By default, edges have a
- *
+ * This is a read-only column.
+ *
+ * @return node id column
+ */
+ public Column nodeId();
+
+ /**
+ * Return edge identifier column.
+ *
+ * This is a read-only column.
+ *
+ * @return edge id column
+ */
+ public Column edgeId();
+
+ /**
+ * Return node label column.
+ *
+ * @return node label column
+ */
+ public Column nodeLabel();
+
+ /**
+ * Return edge label column.
+ *
+ * @return edge label column
+ */
+ public Column edgeLabel();
+
+ /**
+ * Return edge weigth column.
+ *
+ * @return edge weight column
+ */
+ public Column edgeWeight();
+
+ /**
+ * Return node time-set (timestamp or interval) column.
+ *
+ * @return node time-set column
+ */
+ public Column nodeTimeSet();
+
+ /**
+ * Return edge time-set (timestamp or interval) column.
+ *
+ * @return edge time-set column
+ */
+ public Column edgeTimeSet();
+
+ /**
+ * Return node degree column.
+ *
+ * @return node degree column
+ */
+ public Column degree();
+
+ /**
+ * Return node in-degree column.
+ *
+ * Only for directed graphs.
+ *
+ * @return node in-degree column
+ */
+ public Column inDegree();
+
+ /**
+ * Return node out-degree column.
+ *
+ * Only for directed graphs.
+ *
+ * @return node out-degree column
+ */
+ public Column outDegree();
+
+ /**
+ * Return edge type column.
+ *
+ * Only for multi-graphs.
+ *
+ * @return node in-degree column
+ */
+ public Column edgeType();
+ }
+
/**
* Returns the graph factory.
*
@@ -269,6 +371,15 @@ public static void write(DataOutput output, GraphModel graphModel) throws IOExce
*/
public void setVisibleView(GraphView view);
+ /**
+ * Returns the default columns.
+ *
+ * Default columns are always available for each element.
+ *
+ * @return default columns
+ */
+ public DefaultColumns defaultColumns();
+
/**
* Adds a new edge type and returns the integer identifier.
*
@@ -316,6 +427,15 @@ public static void write(DataOutput output, GraphModel graphModel) throws IOExce
*/
public Object[] getEdgeTypeLabels();
+ /**
+ * Returns the edge type labels.
+ *
+ * @param includeEmpty true to include labels without edges
+ *
+ * @return edge type labels
+ */
+ public Object[] getEdgeTypeLabels(boolean includeEmpty);
+
/**
* Returns true if the graph is directed.
*
@@ -353,6 +473,11 @@ public static void write(DataOutput output, GraphModel graphModel) throws IOExce
/**
* Creates a new graph view.
+ *
+ * By default, the view applies to both nodes and edges, so this is equivalent to
+ * {@link #createView(boolean, boolean) createView(true, true)}.
+ *
+ * New views are by default empty, i.e. no nodes and no edges are visible in the view.
*
* @return newly created graph view
*/
@@ -361,9 +486,22 @@ public static void write(DataOutput output, GraphModel graphModel) throws IOExce
/**
* Creates a new graph view.
*
- * The node and edge parameters allows to restrict the view filtering to
- * only nodes or only edges. By default, the view applies to both nodes and
- * edges.
+ * The node and edge filters allows to restrict the view filtering to only nodes or only edges. If node only, all
+ * edges connected to included nodes will be included too. If edge only, all nodes are included but only the edges
+ * matching the view are included.
+ *
+ * @param nodeFilter predicate to filter nodes, or null to include all nodes
+ * @param edgeFilter predicate to filter edges, or null to include all edges
+ * @return newly created graph view
+ */
+ public GraphView createView(Predicate
+ * The node and edge parameters allows to restrict the view filtering to only nodes or only edges. If node only, all
+ * edges connected to included nodes will be included too. If edge only, all nodes are included but only the edges
+ * matching the view are included.
*
* @param node true to enable node view, false otherwise
* @param edge true to enable edge view, false otherwise
@@ -382,9 +520,8 @@ public static void write(DataOutput output, GraphModel graphModel) throws IOExce
/**
* Creates a new graph based on an existing view.
*
- * The node and edge parameters allows to restrict the view filtering to
- * only nodes or only edges. By default, the view applies to both nodes and
- * edges.
+ * The node and edge parameters allows to restrict the view filtering to only nodes or only edges. By default, the
+ * view applies to both nodes and edges.
*
* @param view view to copy
* @param node true to enable node view, false otherwise
@@ -403,8 +540,7 @@ public static void write(DataOutput output, GraphModel graphModel) throws IOExce
/**
* Sets the given time interval to the view.
*
- * Each view can be configured with a time interval to filter a graph over
- * time.
+ * Each view can be configured with a time interval to filter a graph over time.
*
* @param view the view to configure
* @param interval the time interval
@@ -412,22 +548,18 @@ public static void write(DataOutput output, GraphModel graphModel) throws IOExce
public void setTimeInterval(GraphView view, Interval interval);
/**
- * Returns the node table. Contains all the columns associated to
- * node elements.
+ * Returns the node table. Contains all the columns associated to node elements.
*
- * A
- * A
- * The time bounds is an interval made of the minimum and maximum time
- * observed in the entire graph.
+ * The time bounds is an interval made of the minimum and maximum time observed in the entire graph.
*
* @return time bounds
*/
@@ -506,8 +654,7 @@ public static void write(DataOutput output, GraphModel graphModel) throws IOExce
/**
* Gets the time bounds for the visible graph.
*
- * The time bounds is an interval made of the minimum and maximum time
- * observed in the entire graph.
+ * The time bounds is an interval made of the minimum and maximum time observed in the entire graph.
*
* @return time bounds
*/
@@ -516,8 +663,7 @@ public static void write(DataOutput output, GraphModel graphModel) throws IOExce
/**
* Gets the time bounds for the given graph view.
*
- * The time bounds is an interval made of the minimum and maximum time
- * observed in the entire graph.
+ * The time bounds is an interval made of the minimum and maximum time observed in the entire graph.
*
* @param view the graph view
* @return time bounds
@@ -528,8 +674,7 @@ public static void write(DataOutput output, GraphModel graphModel) throws IOExce
* Creates and returns a new graph observer.
*
* @param graph the graph to observe
- * @param withGraphDiff true to include graph difference feature, false
- * otherwise
+ * @param withGraphDiff true to include graph difference feature, false otherwise
* @return newly created graph observer
*/
public GraphObserver createGraphObserver(Graph graph, boolean withGraphDiff);
@@ -553,14 +698,14 @@ public static void write(DataOutput output, GraphModel graphModel) throws IOExce
*
* @return time zone
*/
- public DateTimeZone getTimeZone();
+ public ZoneId getTimeZone();
/**
* Sets the time zone used to display time.
*
* @param timeZone time zone
*/
- public void setTimeZone(DateTimeZone timeZone);
+ public void setTimeZone(ZoneId timeZone);
/**
* Returns the current configuration.
@@ -571,21 +716,22 @@ public static void write(DataOutput output, GraphModel graphModel) throws IOExce
/**
* Sets a new configuration for this graph model.
- *
- * Note that this method only works if the graph model is empty.
+ *
+ * @deprecated setting configuration after graph model creation is no longer supported. Best is to use the
+ * {@link Configuration#builder()} to create a new configuration and then use it at graph model creation
+ * from {@link GraphModel.Factory#newInstance(Configuration)}.
*
* @param configuration new configuration
- * @throws IllegalStateException if the graph model isn't empty
*/
+ @Deprecated
public void setConfiguration(Configuration configuration);
/**
* Returns the maximum store id number nodes have in this model.
*
- * Each node has a unique store identifier which can be retrieved from
- * {@link Node#getStoreId() }. This maximum number can help design algorithms
- * thar rely on storing nodes in a array. Note that not all consecutive ids
- * may be assigned.
+ * Each node has a unique store identifier which can be retrieved from {@link Node#getStoreId() }. This maximum
+ * number can help design algorithms thar rely on storing nodes in a array. Note that not all consecutive ids may be
+ * assigned.
*
* @return maximum node store id
*/
@@ -594,10 +740,9 @@ public static void write(DataOutput output, GraphModel graphModel) throws IOExce
/**
* Returns the maximum store id number edges have in this model.
*
- * Each edge has a unique store identifier which can be retrieved from
- * {@link Edge#getStoreId() }. This maximum number can help design algorithms
- * thar rely on storing edges in a array. Note that not all consecutive ids
- * may be assigned.
+ * Each edge has a unique store identifier which can be retrieved from {@link Edge#getStoreId() }. This maximum
+ * number can help design algorithms thar rely on storing edges in a array. Note that not all consecutive ids may be
+ * assigned.
*
* @return maximum edge store id
*/
diff --git a/store/src/main/java/org/gephi/graph/api/GraphObserver.java b/src/main/java/org/gephi/graph/api/GraphObserver.java
similarity index 69%
rename from store/src/main/java/org/gephi/graph/api/GraphObserver.java
rename to src/main/java/org/gephi/graph/api/GraphObserver.java
index 221e961a..19d984e5 100644
--- a/store/src/main/java/org/gephi/graph/api/GraphObserver.java
+++ b/src/main/java/org/gephi/graph/api/GraphObserver.java
@@ -18,26 +18,22 @@
/**
* Observer over a graph to monitor changes and obtain the list of differences.
*
- * The graph observer is a mechanism used to monitor periodically changes made
- * to the graph. This scenario is common in multi-threaded application where a
- * thread is modifying the graph and one or multiple threads need to take action
- * when updates are made.
+ * The graph observer is a mechanism used to monitor periodically changes made to the graph. This scenario is common in
+ * multi-threaded application where a thread is modifying the graph and one or multiple threads need to take action when
+ * updates are made.
*
- * Graph observer users should periodically call the
- *
- * In addition of a boolean flag whether the graph has changed, an observer can
- * collect data about the differences such as nodes added or removed. Users
- * should call the
- * Observers should be destroyed when not needed anymore. A new observer can be
- * obtained from the
- * Note that observer instances are not thread-safe and should not be called
- * from multiple threads simultaneously.
+ * Note that observer instances are not thread-safe and should not be called from multiple threads simultaneously.
*
* @see GraphModel
*/
@@ -77,8 +73,7 @@ public interface GraphObserver {
public boolean isDestroyed();
/**
- * Returns true if this observer has never got its
- * hasGraphChanged() method called.
+ * Returns true if this observer has never got its hasGraphChanged() method called.
*
* @return true if new observer, false otherwise
*/
diff --git a/store/src/main/java/org/gephi/graph/api/GraphView.java b/src/main/java/org/gephi/graph/api/GraphView.java
similarity index 71%
rename from store/src/main/java/org/gephi/graph/api/GraphView.java
rename to src/main/java/org/gephi/graph/api/GraphView.java
index 94e233d0..f6f6e035 100644
--- a/store/src/main/java/org/gephi/graph/api/GraphView.java
+++ b/src/main/java/org/gephi/graph/api/GraphView.java
@@ -18,27 +18,20 @@
/**
* View on the graph.
*
- * Each graph can have views and use these views to obtain subgraphs. A view is
- * a filter on the main graph structure where some nodes and/or edges are
- * missing.
+ * Each graph can have views and use these views to obtain subgraphs. A view is a filter on the main graph structure
+ * where some nodes and/or edges are missing.
*
- * The graph model has a main view, which is always 100% of nodes and edges.
- * Users can then create views and modify them by enabling/disabling elements.
- * Views can only have elements which are in the model. As a consequence, if a
- * element is removed from the graph it's also removed from all the views. By
- * default, the view is empty.
+ * The graph model has a main view, which is always 100% of nodes and edges. Users can then create views and modify them
+ * by enabling/disabling elements. Views can only have elements which are in the model. As a consequence, if a element
+ * is removed from the graph it's also removed from all the views. By default, the view is empty.
*
- * The main benefits of views is the ability to obtain a
- * Views can apply on nodes only, edges only or both. This is configured when
- * the view is created. Nodes-only view let the system automatically control the
- * set of edges. Enabling a node in the view will automatically enable all it's
+ * Views can apply on nodes only, edges only or both. This is configured when the view is created. Nodes-only view let
+ * the system automatically control the set of edges. Enabling a node in the view will automatically enable all it's
* edges if the opposite nodes are also in the view.
*
* @see GraphModel
diff --git a/store/src/main/java/org/gephi/graph/api/Index.java b/src/main/java/org/gephi/graph/api/Index.java
similarity index 84%
rename from store/src/main/java/org/gephi/graph/api/Index.java
rename to src/main/java/org/gephi/graph/api/Index.java
index d9d6e5ee..12ce559c 100644
--- a/store/src/main/java/org/gephi/graph/api/Index.java
+++ b/src/main/java/org/gephi/graph/api/Index.java
@@ -18,10 +18,10 @@
import java.util.Collection;
/**
- * An index is associated with each table and keeps track of each unique value
- * in indexed columns.
+ * An index is associated with each table and keeps track of each unique value in columns.
*
- *
+ * Each column is associated with a @{{@link ColumnIndex}}.
+ *
* @param
- * Any two intervals i and i' satisfy the interval trichotomy;
- * that is, exactly one of the following three properties holds:
+ * Any two intervals i and i' satisfy the interval trichotomy; that is, exactly one of the following
+ * three properties holds:
*
- * Note that if two intervals are equal ({@code i.low = i'.low} and
- * {@code i.high = i'.high}), they overlap as well. But if they simply
- * overlap (for instance {@code i.low < i'.low} and {@code i.high >
+ * Note that if two intervals are equal ({@code i.low = i'.low} and {@code i.high = i'.high}), they overlap as well.
+ * But if they simply overlap (for instance {@code i.low < i'.low} and {@code i.high >
* i'.high}) they aren't equal.
*
* @param interval the interval to be compared
*
- * @return a negative integer, zero, or a positive integer as this interval
- * is to the left of, overlaps with, or is to the right of the
- * specified interval.
+ * @return a negative integer, zero, or a positive integer as this interval is to the left of, overlaps with, or is
+ * to the right of the specified interval.
*
* @throws NullPointerException if {@code interval} is null.
*/
@@ -101,9 +99,8 @@ public int compareTo(Interval interval) {
* Compares this interval to the given timetamp.
*
* @param timestamp timestamp
- * @return a negative integer, zero or a positive integer if this interval
- * is to the left of, overlaps with, or is to the right with the
- * specified timestamp.
+ * @return a negative integer, zero or a positive integer if this interval is to the left of, overlaps with, or is
+ * to the right with the specified timestamp.
*
* @throws NullPointerException if {@code timestamp} is null.
*/
@@ -142,14 +139,12 @@ public double getHigh() {
* Compares this interval with the specified object for equality.
*
*
- * Note that two intervals are equal if {@code i.low = i'.low} and
- * {@code i.high = i'.high}.
+ * Note that two intervals are equal if {@code i.low = i'.low} and {@code i.high = i'.high}.
*
* @param obj object to which this interval is to be compared
*
- * @return {@code true} if and only if the specified {@code Object} is a
- * {@code Interval} whose low and high are equal to this
- * {@code Interval's}.
+ * @return {@code true} if and only if the specified {@code Object} is a {@code Interval} whose low and high are
+ * equal to this {@code Interval's}.
*
*/
@Override
diff --git a/store/src/main/java/org/gephi/graph/api/Node.java b/src/main/java/org/gephi/graph/api/Node.java
similarity index 100%
rename from store/src/main/java/org/gephi/graph/api/Node.java
rename to src/main/java/org/gephi/graph/api/Node.java
diff --git a/store/src/main/java/org/gephi/graph/api/NodeIterable.java b/src/main/java/org/gephi/graph/api/NodeIterable.java
similarity index 72%
rename from store/src/main/java/org/gephi/graph/api/NodeIterable.java
rename to src/main/java/org/gephi/graph/api/NodeIterable.java
index fab69126..e25b0fd2 100644
--- a/store/src/main/java/org/gephi/graph/api/NodeIterable.java
+++ b/src/main/java/org/gephi/graph/api/NodeIterable.java
@@ -19,6 +19,9 @@
import java.util.Collections;
import java.util.Iterator;
import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.Spliterators;
/**
* A node iterable.
@@ -54,6 +57,27 @@ public interface NodeIterable extends ElementIterable
+ * Implementations return a splittable, sized, fail-fast spliterator suitable for parallel streams. When not
+ * possible, a non-splittable spliterator is returned.
+ *
+ * @return node spliterator
+ */
+ @Override
+ default Spliterator
+ * The spatial index is not enabled by default. To enable it, set the appropriate configuration:
+ *
+ * When nodes are moved, added or removed, the spatial index is automatically updated. Edges are not indexed, but they
+ * are queried based on whether their source or target nodes are in the given area.
+ *
+ * The Z position is not taken into account when querying the spatial index, only X/Y are supported.
+ *
+ * All nodes in the provided area are guaranteed to be returned, but some nodes outside the area may also be
+ * returned.
+ *
+ * @param rect area to query
+ * @return nodes in the area
+ */
+ NodeIterable getApproximateNodesInArea(Rect2D rect);
+
+ /**
+ * Returns the nodes in the given area using a faster, but approximate method, filtered by the given predicate.
+ *
+ * All nodes in the provided area are guaranteed to be returned, but some nodes outside the area may also be
+ * returned.
+ *
+ * @param rect area to query
+ * @param predicate filter predicate
+ * @return nodes in the area
+ */
+ NodeIterable getApproximateNodesInArea(Rect2D rect, Predicate super Node> predicate);
+
+ /**
+ * Returns the edges in the given area. Edges may be returned twice.
+ *
+ * @param rect area to query
+ * @return edges in the area
+ */
+ EdgeIterable getEdgesInArea(Rect2D rect);
+
+ /**
+ * Returns the edges in the given area, filtered by the given predicate. Edges may be returned twice.
+ *
+ * @param rect area to query
+ * @param predicate filter predicate
+ * @return edges in the area
+ */
+ EdgeIterable getEdgesInArea(Rect2D rect, Predicate super Edge> predicate);
+
+ /**
+ * Returns the edges in the given area using a faster, but approximate method.
+ *
+ * All edges in the provided area are guaranteed to be returned, but some edges outside the area may also be
+ * returned. Edges may also be returned twice.
+ *
+ * @param rect area to query
+ * @return edges in the area
+ */
+ EdgeIterable getApproximateEdgesInArea(Rect2D rect);
+
+ /**
+ * Returns the edges in the given area using a faster, but approximate method, filtered by the given predicate.
+ *
+ * All edges in the provided area are guaranteed to be returned, but some edges outside the area may also be
+ * returned. Edges may also be returned twice.
+ *
+ * @param rect area to query
+ * @param predicate filter predicate
+ * @return edges in the area
+ */
+ EdgeIterable getApproximateEdgesInArea(Rect2D rect, Predicate super Edge> predicate);
+
+ /**
+ * Returns the bounding rectangle that contains all nodes in the graph. The boundaries are calculated based on each
+ * node's position and size.
+ *
+ * @return the bounding rectangle, or null if there are no nodes
+ */
+ Rect2D getBoundaries();
+
+ /**
+ * Acquires a read lock on the spatial index. This is recommended when using the query functions in a stream
+ * context, to avoid the spatial index being modified while being queried.
+ *
+ * Every call to this method must be matched with a call to {@link #spatialIndexReadUnlock()}.
+ */
+ void spatialIndexReadLock();
+
+ /**
+ * Releases a read lock on the spatial index. This must be called after a call to {@link #spatialIndexReadLock()}.
+ */
+ void spatialIndexReadUnlock();
+}
diff --git a/store/src/main/java/org/gephi/graph/api/Subgraph.java b/src/main/java/org/gephi/graph/api/Subgraph.java
similarity index 79%
rename from store/src/main/java/org/gephi/graph/api/Subgraph.java
rename to src/main/java/org/gephi/graph/api/Subgraph.java
index 00e88a8b..3b7671b6 100644
--- a/store/src/main/java/org/gephi/graph/api/Subgraph.java
+++ b/src/main/java/org/gephi/graph/api/Subgraph.java
@@ -20,11 +20,10 @@
/**
* A subgraph is a subset of a graph based on a graph view.
*
- * A subgraph has the same or less elements compared to the graph it's based on.
- * This interface inherits from Graph and all read operations behave in
- * a similar fashion. For instance, calling getNodes will return only
- * nodes in this subgraph. However, write operations such as addNode or
- * removeNode are used to control which elements are part of the view.
+ * A subgraph has the same or less elements compared to the graph it's based on. This interface inherits from
+ * Graph and all read operations behave in a similar fashion. For instance, calling getNodes will
+ * return only nodes in this subgraph. However, write operations such as addNode or removeNode are
+ * used to control which elements are part of the view.
*
*/
public interface Subgraph extends Graph {
@@ -110,6 +109,16 @@ public interface Subgraph extends Graph {
@Override
public boolean removeAllNodes(Collection extends Node> nodes);
+ /**
+ * Retains only nodes in this subgraph that are contained in the specified collection.
+ *
+ * The nodes should be part of the root graph.
+ *
+ * @param nodes the node collection
+ * @return true if at least one node has been removed, false otherwise
+ */
+ public boolean retainNodes(Collection extends Node> nodes);
+
/**
* Removes an edge from this subgraph.
*
@@ -132,6 +141,16 @@ public interface Subgraph extends Graph {
@Override
public boolean removeAllEdges(Collection extends Edge> edges);
+ /**
+ * Retains only edges in this subgraph that are contained in the specified collection.
+ *
+ * The edges should be part of the root graph.
+ *
+ * @param edges the edge collection
+ * @return true if at least one edge has been removed, false otherwise
+ */
+ public boolean retainEdges(Collection extends Edge> edges);
+
/**
* Fills the subgraph so all elements in the graph are in the subgraph.
*/
@@ -156,8 +175,7 @@ public interface Subgraph extends Graph {
public void intersection(Subgraph subGraph);
/**
- * Inverse this subgraph so all elements in the graph are removed and all
- * elements not in the graph are added.
+ * Inverse this subgraph so all elements in the graph are removed and all elements not in the graph are added.
*/
public void not();
}
diff --git a/store/src/main/java/org/gephi/graph/api/Table.java b/src/main/java/org/gephi/graph/api/Table.java
similarity index 83%
rename from store/src/main/java/org/gephi/graph/api/Table.java
rename to src/main/java/org/gephi/graph/api/Table.java
index 3112c428..2db59acc 100644
--- a/store/src/main/java/org/gephi/graph/api/Table.java
+++ b/src/main/java/org/gephi/graph/api/Table.java
@@ -13,11 +13,11 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
+
package org.gephi.graph.api;
/**
- * The table is the container for columns. Column ids in all methods are
- * converted to lower case.
+ * The table is the container for columns. Column ids in all methods are converted to lower case.
*/
public interface Table extends ColumnIterable {
@@ -109,6 +109,14 @@ public interface Table extends ColumnIterable {
*/
public int countColumns();
+ /**
+ * Counts the columns of the given origin.
+ *
+ * @param origin the origin
+ * @return the number of columns set with this origin
+ */
+ public int countColumns(Origin origin);
+
/**
* The element class of this column.
*
@@ -130,4 +138,25 @@ public interface Table extends ColumnIterable {
* @return graph
*/
public Graph getGraph();
+
+ /**
+ * Returns true if this table is the node table.
+ *
+ * @return true if node table, false otherwise
+ */
+ public boolean isNodeTable();
+
+ /**
+ * Returns true if this table is the node table.
+ *
+ * @return true if node table, false otherwise
+ */
+ public boolean isEdgeTable();
+
+ /**
+ * Returns the table lock, which controls the multi-thread access to the table.
+ *
+ * @return table lock
+ */
+ TableLock getLock();
}
diff --git a/store/src/main/java/org/gephi/graph/api/TableDiff.java b/src/main/java/org/gephi/graph/api/TableDiff.java
similarity index 95%
rename from store/src/main/java/org/gephi/graph/api/TableDiff.java
rename to src/main/java/org/gephi/graph/api/TableDiff.java
index 2ad3f944..1e29ef83 100644
--- a/store/src/main/java/org/gephi/graph/api/TableDiff.java
+++ b/src/main/java/org/gephi/graph/api/TableDiff.java
@@ -20,8 +20,8 @@
/**
* Interface to retrieve added, removed and modified columns from the table.
*
- * This interface is associated with a {@link TableObserver} and provides an
- * easy access to the columns added or removed.
+ * This interface is associated with a {@link TableObserver} and provides an easy access to the columns added or
+ * removed.
*/
public interface TableDiff {
diff --git a/src/main/java/org/gephi/graph/api/TableLock.java b/src/main/java/org/gephi/graph/api/TableLock.java
new file mode 100644
index 00000000..b8b79c46
--- /dev/null
+++ b/src/main/java/org/gephi/graph/api/TableLock.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2012-2013 Gephi Consortium
+ *
+ * Licensed 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.gephi.graph.api;
+
+public interface TableLock {
+
+ /**
+ * Acquires the lock. Acquires the lock if it is not held by another thread and returns immediately, setting the
+ * lock hold count to one.
+ */
+ void lock();
+
+ /**
+ * Attempts to release this lock. If the current thread is the holder of this lock then the hold count is
+ * decremented. If the hold count is now zero then the lock is released. If the current thread is not the holder of
+ * this lock then IllegalMonitorStateException is thrown.
+ *
+ * @throws IllegalMonitorStateException if the current thread does not hold this lock
+ */
+ void unlock();
+
+ /**
+ * Queries the number of holds on this lock by the current thread. A thread has a hold on a lock for each lock
+ * action that is not matched by an unlock action.
+ *
+ * @return the number of holds on this lock by the current thread, or zero if this lock is not held by the current
+ * thread
+ */
+ int getHoldCount();
+}
diff --git a/store/src/main/java/org/gephi/graph/api/TableObserver.java b/src/main/java/org/gephi/graph/api/TableObserver.java
similarity index 74%
rename from store/src/main/java/org/gephi/graph/api/TableObserver.java
rename to src/main/java/org/gephi/graph/api/TableObserver.java
index 8aab4381..bebbad5c 100644
--- a/store/src/main/java/org/gephi/graph/api/TableObserver.java
+++ b/src/main/java/org/gephi/graph/api/TableObserver.java
@@ -18,18 +18,16 @@
/**
* Observer over a table to monitor changes.
*
- * The table observer is a mechanism used to monitor periodically changes made
- * to the table. This scenario is common in multi-threaded application where a
- * thread is modifying the table and one or multiple threads need to take action
- * when updates are made.
+ * The table observer is a mechanism used to monitor periodically changes made to the table. This scenario is common in
+ * multi-threaded application where a thread is modifying the table and one or multiple threads need to take action when
+ * updates are made.
*
- * Table observer users should periodically call the
- *
- * Observers should be destroyed when not needed anymore. A new observer can be
- * obtained from the
- * Both the elements (i.e nodes and edges) existence in time and the attributes'
- * values in time can be represented in two different ways: using timestamps or
- * using intervals. They can be mixed thought and therefore need to be
+ * Both the elements (i.e nodes and edges) existence in time and the attributes' values in time can be represented in
+ * two different ways: using timestamps or using intervals. They can be mixed thought and therefore need to be
* configured by the user.
*
- * Each representation has its advantages and disadvantages. For instance,
- * timestamps are great when observations are made at fixed periods. On the
- * other hand, intervals are great when the time is arbitrary and elements or
- * attributes have long continuous existence.
+ * Each representation has its advantages and disadvantages. For instance, timestamps are great when observations are
+ * made at fixed periods. On the other hand, intervals are great when the time is arbitrary and elements or attributes
+ * have long continuous existence.
*
* @see Configuration
*/
@@ -34,16 +32,14 @@ public enum TimeRepresentation {
/**
* Timestamp representation (fixed).
*
- * Time is represented using timestamps. Timestamps are single value and
- * represent a single moment in time.
+ * Time is represented using timestamps. Timestamps are single value and represent a single moment in time.
*/
TIMESTAMP,
/**
* Interval representation (continuous).
*
- * Time is represented using intervals, with a beginning and an end.
- * Intervals are always included on both bounds but allows an infinite
- * bound.
+ * Time is represented using intervals, with a beginning and an end. Intervals are always included on both bounds
+ * but allows an infinite bound.
*/
INTERVAL;
}
diff --git a/store/src/main/java/org/gephi/graph/api/UndirectedGraph.java b/src/main/java/org/gephi/graph/api/UndirectedGraph.java
similarity index 100%
rename from store/src/main/java/org/gephi/graph/api/UndirectedGraph.java
rename to src/main/java/org/gephi/graph/api/UndirectedGraph.java
diff --git a/store/src/main/java/org/gephi/graph/api/UndirectedSubgraph.java b/src/main/java/org/gephi/graph/api/UndirectedSubgraph.java
similarity index 100%
rename from store/src/main/java/org/gephi/graph/api/UndirectedSubgraph.java
rename to src/main/java/org/gephi/graph/api/UndirectedSubgraph.java
diff --git a/src/main/java/org/gephi/graph/api/UnsupportedFormatVersionException.java b/src/main/java/org/gephi/graph/api/UnsupportedFormatVersionException.java
new file mode 100644
index 00000000..649172ce
--- /dev/null
+++ b/src/main/java/org/gephi/graph/api/UnsupportedFormatVersionException.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2012-2013 Gephi Consortium
+ *
+ * Licensed 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.gephi.graph.api;
+
+import java.io.IOException;
+
+/**
+ * Thrown when reading a serialized graph model written by a newer, incompatible version of graphstore than the one
+ * doing the reading.
+ *
+ * Extends {@link IOException} so it is caught by existing code that only handles I/O errors, while callers that want to
+ * report a specific, localized message can catch this type directly and use {@link #getFileVersion()} and
+ * {@link #getMaxSupportedVersion()} instead of parsing the message.
+ */
+public class UnsupportedFormatVersionException extends IOException {
+
+ private final float fileVersion;
+ private final float maxSupportedVersion;
+
+ public UnsupportedFormatVersionException(float fileVersion, float maxSupportedVersion) {
+ super("Unsupported serialization format version: " + fileVersion + ". This file was written by a newer version of graphstore than this library supports (up to " + maxSupportedVersion + "). Please upgrade graphstore to read this file.");
+ this.fileVersion = fileVersion;
+ this.maxSupportedVersion = maxSupportedVersion;
+ }
+
+ /**
+ * Returns the format version the file was written with.
+ *
+ * @return file format version
+ */
+ public float getFileVersion() {
+ return fileVersion;
+ }
+
+ /**
+ * Returns the highest format version this version of graphstore can read.
+ *
+ * @return max supported format version
+ */
+ public float getMaxSupportedVersion() {
+ return maxSupportedVersion;
+ }
+}
diff --git a/src/main/java/org/gephi/graph/api/package.html b/src/main/java/org/gephi/graph/api/package.html
new file mode 100644
index 00000000..ae5d4a6f
--- /dev/null
+++ b/src/main/java/org/gephi/graph/api/package.html
@@ -0,0 +1,8 @@
+
+
- * Using this constructor can improve performances if the number of
- * timestamps is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of timestamps is known in advance as it minimizes
+ * array resizes.
*
* @param capacity timestamp capacity
*/
@@ -51,8 +51,7 @@ public IntervalBooleanMap(int capacity) {
/**
* Constructor with an initial interval map.
*
- * The
- * This method may return a reference to the underlying array so clients
- * should make a copy if the array is written to.
+ * This method may return a reference to the underlying array so clients should make a copy if the array is written
+ * to.
*
* @return array of all values
*/
diff --git a/store/src/main/java/org/gephi/graph/api/types/IntervalByteMap.java b/src/main/java/org/gephi/graph/api/types/IntervalByteMap.java
similarity index 91%
rename from store/src/main/java/org/gephi/graph/api/types/IntervalByteMap.java
rename to src/main/java/org/gephi/graph/api/types/IntervalByteMap.java
index 80b25d38..5bf835c7 100644
--- a/store/src/main/java/org/gephi/graph/api/types/IntervalByteMap.java
+++ b/src/main/java/org/gephi/graph/api/types/IntervalByteMap.java
@@ -38,8 +38,8 @@ public IntervalByteMap() {
/**
* Constructor with capacity.
*
- * Using this constructor can improve performances if the number of
- * timestamps is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of timestamps is known in advance as it minimizes
+ * array resizes.
*
* @param capacity timestamp capacity
*/
@@ -51,8 +51,7 @@ public IntervalByteMap(int capacity) {
/**
* Constructor with an initial interval map.
*
- * The
- * This method may return a reference to the underlying array so clients
- * should make a copy if the array is written to.
+ * This method may return a reference to the underlying array so clients should make a copy if the array is written
+ * to.
*
* @return array of all values
*/
diff --git a/store/src/main/java/org/gephi/graph/api/types/IntervalCharMap.java b/src/main/java/org/gephi/graph/api/types/IntervalCharMap.java
similarity index 90%
rename from store/src/main/java/org/gephi/graph/api/types/IntervalCharMap.java
rename to src/main/java/org/gephi/graph/api/types/IntervalCharMap.java
index 5353cdec..affcf8d1 100644
--- a/store/src/main/java/org/gephi/graph/api/types/IntervalCharMap.java
+++ b/src/main/java/org/gephi/graph/api/types/IntervalCharMap.java
@@ -38,8 +38,8 @@ public IntervalCharMap() {
/**
* Constructor with capacity.
*
- * Using this constructor can improve performances if the number of
- * timestamps is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of timestamps is known in advance as it minimizes
+ * array resizes.
*
* @param capacity timestamp capacity
*/
@@ -51,8 +51,7 @@ public IntervalCharMap(int capacity) {
/**
* Constructor with an initial interval map.
*
- * The
- * This method may return a reference to the underlying array so clients
- * should make a copy if the array is written to.
+ * This method may return a reference to the underlying array so clients should make a copy if the array is written
+ * to.
*
* @return array of all values
*/
diff --git a/store/src/main/java/org/gephi/graph/api/types/IntervalDoubleMap.java b/src/main/java/org/gephi/graph/api/types/IntervalDoubleMap.java
similarity index 90%
rename from store/src/main/java/org/gephi/graph/api/types/IntervalDoubleMap.java
rename to src/main/java/org/gephi/graph/api/types/IntervalDoubleMap.java
index ae29a31f..15dd2cc9 100644
--- a/store/src/main/java/org/gephi/graph/api/types/IntervalDoubleMap.java
+++ b/src/main/java/org/gephi/graph/api/types/IntervalDoubleMap.java
@@ -38,8 +38,8 @@ public IntervalDoubleMap() {
/**
* Constructor with capacity.
*
- * Using this constructor can improve performances if the number of
- * timestamps is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of timestamps is known in advance as it minimizes
+ * array resizes.
*
* @param capacity timestamp capacity
*/
@@ -51,8 +51,7 @@ public IntervalDoubleMap(int capacity) {
/**
* Constructor with an initial interval map.
*
- * The
- * This method may return a reference to the underlying array so clients
- * should make a copy if the array is written to.
+ * This method may return a reference to the underlying array so clients should make a copy if the array is written
+ * to.
*
* @return array of all values
*/
diff --git a/store/src/main/java/org/gephi/graph/api/types/IntervalFloatMap.java b/src/main/java/org/gephi/graph/api/types/IntervalFloatMap.java
similarity index 91%
rename from store/src/main/java/org/gephi/graph/api/types/IntervalFloatMap.java
rename to src/main/java/org/gephi/graph/api/types/IntervalFloatMap.java
index 15dd5e85..9092f7a4 100644
--- a/store/src/main/java/org/gephi/graph/api/types/IntervalFloatMap.java
+++ b/src/main/java/org/gephi/graph/api/types/IntervalFloatMap.java
@@ -39,8 +39,8 @@ public IntervalFloatMap() {
/**
* Constructor with capacity.
*
- * Using this constructor can improve performances if the number of
- * timestamps is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of timestamps is known in advance as it minimizes
+ * array resizes.
*
* @param capacity timestamp capacity
*/
@@ -52,8 +52,7 @@ public IntervalFloatMap(int capacity) {
/**
* Constructor with an initial interval map.
*
- * The
- * This method may return a reference to the underlying array so clients
- * should make a copy if the array is written to.
+ * This method may return a reference to the underlying array so clients should make a copy if the array is written
+ * to.
*
* @return array of all values
*/
diff --git a/store/src/main/java/org/gephi/graph/api/types/IntervalIntegerMap.java b/src/main/java/org/gephi/graph/api/types/IntervalIntegerMap.java
similarity index 91%
rename from store/src/main/java/org/gephi/graph/api/types/IntervalIntegerMap.java
rename to src/main/java/org/gephi/graph/api/types/IntervalIntegerMap.java
index 4ccbc4e6..31c12bf5 100644
--- a/store/src/main/java/org/gephi/graph/api/types/IntervalIntegerMap.java
+++ b/src/main/java/org/gephi/graph/api/types/IntervalIntegerMap.java
@@ -38,8 +38,8 @@ public IntervalIntegerMap() {
/**
* Constructor with capacity.
*
- * Using this constructor can improve performances if the number of
- * timestamps is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of timestamps is known in advance as it minimizes
+ * array resizes.
*
* @param capacity timestamp capacity
*/
@@ -51,8 +51,7 @@ public IntervalIntegerMap(int capacity) {
/**
* Constructor with an initial interval map.
*
- * The
- * This method may return a reference to the underlying array so clients
- * should make a copy if the array is written to.
+ * This method may return a reference to the underlying array so clients should make a copy if the array is written
+ * to.
*
* @return array of all values
*/
diff --git a/store/src/main/java/org/gephi/graph/api/types/IntervalLongMap.java b/src/main/java/org/gephi/graph/api/types/IntervalLongMap.java
similarity index 91%
rename from store/src/main/java/org/gephi/graph/api/types/IntervalLongMap.java
rename to src/main/java/org/gephi/graph/api/types/IntervalLongMap.java
index 40d397e6..9126ae5a 100644
--- a/store/src/main/java/org/gephi/graph/api/types/IntervalLongMap.java
+++ b/src/main/java/org/gephi/graph/api/types/IntervalLongMap.java
@@ -38,8 +38,8 @@ public IntervalLongMap() {
/**
* Constructor with capacity.
*
- * Using this constructor can improve performances if the number of
- * timestamps is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of timestamps is known in advance as it minimizes
+ * array resizes.
*
* @param capacity timestamp capacity
*/
@@ -51,8 +51,7 @@ public IntervalLongMap(int capacity) {
/**
* Constructor with an initial interval map.
*
- * The
- * This method may return a reference to the underlying array so clients
- * should make a copy if the array is written to.
+ * This method may return a reference to the underlying array so clients should make a copy if the array is written
+ * to.
*
* @return array of all values
*/
diff --git a/store/src/main/java/org/gephi/graph/api/types/IntervalMap.java b/src/main/java/org/gephi/graph/api/types/IntervalMap.java
similarity index 95%
rename from store/src/main/java/org/gephi/graph/api/types/IntervalMap.java
rename to src/main/java/org/gephi/graph/api/types/IntervalMap.java
index adbcdc88..8c0c026c 100644
--- a/store/src/main/java/org/gephi/graph/api/types/IntervalMap.java
+++ b/src/main/java/org/gephi/graph/api/types/IntervalMap.java
@@ -16,22 +16,21 @@
package org.gephi.graph.api.types;
import java.lang.reflect.Array;
-import org.gephi.graph.api.Estimator;
import java.math.BigDecimal;
import java.math.RoundingMode;
+import java.time.ZoneId;
import java.util.Arrays;
import org.gephi.graph.api.AttributeUtils;
+import org.gephi.graph.api.Estimator;
import org.gephi.graph.api.Interval;
import org.gephi.graph.api.TimeFormat;
import org.gephi.graph.impl.FormattingAndParsingUtils;
-import org.joda.time.DateTimeZone;
/**
- * Abstract class that implement a sorted map between intervals and attribute
- * values.
+ * Abstract class that implement a sorted map between intervals and attribute values.
*
- * Implementations which extend this class customize the map for a unique type,
- * which is represented by the
- * Using this constructor can improve performances if the number of
- * timestamps is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of timestamps is known in advance as it minimizes
+ * array resizes.
*
* @param capacity timestamp capacity
*/
@@ -283,8 +282,8 @@ protected int removeInner(double intervalStart, double intervalEnd) {
if (startValue == intervalStart && endValue > intervalEnd) {
return -1;
}
- if ((shift = (intervalEnd > endValue ? 2 : intervalEnd < endValue ? -2 : intervalStart > startValue ? 2
- : 0)) == 0) {
+ if ((shift = (intervalEnd > endValue ? 2
+ : intervalEnd < endValue ? -2 : intervalStart > startValue ? 2 : 0)) == 0) {
if (removeIndex == realSize - 2) {
size--;
} else {
@@ -310,8 +309,7 @@ public boolean isEmpty() {
}
/**
- * Returns true if this map contains an interval that starts or ends at
- *
- * The intervals are represented in a flat and sorted array (e.g.
- * {[1.0,2.0], [5.0,6.0]}) returns [1.0,2.0,5.0,6.0]).
+ * The intervals are represented in a flat and sorted array (e.g. {[1.0,2.0], [5.0,6.0]}) returns
+ * [1.0,2.0,5.0,6.0]).
*
- * This method may return a reference to the underlying array so clients
- * should make a copy if the array is written to.
+ * This method may return a reference to the underlying array so clients should make a copy if the array is written
+ * to.
*
* @return array of all intervals
*/
@@ -604,7 +602,7 @@ protected Double getAverageDouble(final Interval interval) {
}
@Override
- public String toString(TimeFormat timeFormat, DateTimeZone timeZone) {
+ public String toString(TimeFormat timeFormat, ZoneId zoneId) {
if (size == 0) {
return FormattingAndParsingUtils.EMPTY_VALUE;
}
@@ -615,13 +613,14 @@ public String toString(TimeFormat timeFormat, DateTimeZone timeZone) {
sb.append('<');
for (int i = 0; i < size; i++) {
sb.append('[');
- sb.append(AttributeUtils.printTimestampInFormat(array[i * 2], timeFormat, timeZone));
+ sb.append(AttributeUtils.printTimestampInFormat(array[i * 2], timeFormat, zoneId));
sb.append(", ");
- sb.append(AttributeUtils.printTimestampInFormat(array[i * 2 + 1], timeFormat, timeZone));
+ sb.append(AttributeUtils.printTimestampInFormat(array[i * 2 + 1], timeFormat, zoneId));
sb.append(", ");
String stringValue = values[i].toString();
- if (FormattingAndParsingUtils.containsDynamicSpecialCharacters(stringValue) || stringValue.trim().isEmpty()) {
+ if (FormattingAndParsingUtils.containsDynamicSpecialCharacters(stringValue) || stringValue.trim()
+ .isEmpty()) {
sb.append('"');
sb.append(stringValue.replace("\\", "\\\\").replace("\"", "\\\""));
sb.append('"');
diff --git a/store/src/main/java/org/gephi/graph/api/types/IntervalSet.java b/src/main/java/org/gephi/graph/api/types/IntervalSet.java
similarity index 88%
rename from store/src/main/java/org/gephi/graph/api/types/IntervalSet.java
rename to src/main/java/org/gephi/graph/api/types/IntervalSet.java
index ef3210e3..e1ad1147 100644
--- a/store/src/main/java/org/gephi/graph/api/types/IntervalSet.java
+++ b/src/main/java/org/gephi/graph/api/types/IntervalSet.java
@@ -15,12 +15,12 @@
*/
package org.gephi.graph.api.types;
+import java.time.ZoneId;
import java.util.Arrays;
import org.gephi.graph.api.AttributeUtils;
import org.gephi.graph.api.Interval;
import org.gephi.graph.api.TimeFormat;
import org.gephi.graph.impl.FormattingAndParsingUtils;
-import org.joda.time.DateTimeZone;
/**
* Sorted set for intervals.
@@ -42,8 +42,8 @@ public IntervalSet() {
/**
* Constructor with capacity.
*
- * Using this constructor can improve performances if the number of
- * intervals is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of intervals is known in advance as it minimizes
+ * array resizes.
*
* @param capacity interval capacity
*/
@@ -65,6 +65,15 @@ public IntervalSet(double[] arr) {
size = arr.length / 2;
}
+ /**
+ * Copy constructor.
+ *
+ * @param source set to copy
+ */
+ public IntervalSet(IntervalSet source) {
+ this(source.array);
+ }
+
@Override
public boolean add(Interval interval) {
return addInner(interval.getLow(), interval.getHigh()) >= 0;
@@ -85,9 +94,40 @@ public boolean isEmpty() {
return size == 0;
}
+ @Override
+ public Interval getMax() {
+ if (size > 0) {
+ return new Interval(array[array.length - 2], array[array.length - 1]);
+ }
+ return null;
+ }
+
+ @Override
+ public Interval getMin() {
+ if (size > 0) {
+ return new Interval(array[0], array[1]);
+ }
+ return null;
+ }
+
+ @Override
+ public Double getMaxDouble() {
+ if (size > 0) {
+ return array[array.length - 1];
+ }
+ return null;
+ }
+
+ @Override
+ public Double getMinDouble() {
+ if (size > 0) {
+ return array[0];
+ }
+ return null;
+ }
+
/**
- * Returns true if this set contains an interval that starts or ends at
- *
- * The intervals are represented in a flat and sorted array (e.g.
- * {[1.0,2.0], [5.0,6.0]}) returns [1.0,2.0,5.0,6.0]).
+ * The intervals are represented in a flat and sorted array (e.g. {[1.0,2.0], [5.0,6.0]}) returns
+ * [1.0,2.0,5.0,6.0]).
*
- * This method may return a reference to the underlying array so clients
- * should make a copy if the array is written to.
+ * This method may return a reference to the underlying array so clients should make a copy if the array is written
+ * to.
*
* @return array of all intervals
*/
@@ -262,8 +302,8 @@ private int removeInner(double intervalStart, double intervalEnd) {
if (startValue == intervalStart && endValue > intervalEnd) {
return -1;
}
- if ((shift = (intervalEnd > endValue ? 2 : intervalEnd < endValue ? -2 : intervalStart > startValue ? 2
- : 0)) == 0) {
+ if ((shift = (intervalEnd > endValue ? 2
+ : intervalEnd < endValue ? -2 : intervalStart > startValue ? 2 : 0)) == 0) {
if (removeIndex == realSize - 2) {
size--;
} else {
@@ -319,7 +359,7 @@ public boolean equals(Object obj) {
}
@Override
- public String toString(TimeFormat timeFormat, DateTimeZone timeZone) {
+ public String toString(TimeFormat timeFormat, ZoneId timeZone) {
if (size == 0) {
return FormattingAndParsingUtils.EMPTY_VALUE;
}
diff --git a/store/src/main/java/org/gephi/graph/api/types/IntervalShortMap.java b/src/main/java/org/gephi/graph/api/types/IntervalShortMap.java
similarity index 91%
rename from store/src/main/java/org/gephi/graph/api/types/IntervalShortMap.java
rename to src/main/java/org/gephi/graph/api/types/IntervalShortMap.java
index 62c04daf..3a0dc642 100644
--- a/store/src/main/java/org/gephi/graph/api/types/IntervalShortMap.java
+++ b/src/main/java/org/gephi/graph/api/types/IntervalShortMap.java
@@ -38,8 +38,8 @@ public IntervalShortMap() {
/**
* Constructor with capacity.
*
- * Using this constructor can improve performances if the number of
- * timestamps is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of timestamps is known in advance as it minimizes
+ * array resizes.
*
* @param capacity timestamp capacity
*/
@@ -51,8 +51,7 @@ public IntervalShortMap(int capacity) {
/**
* Constructor with an initial interval map.
*
- * The
- * This method may return a reference to the underlying array so clients
- * should make a copy if the array is written to.
+ * This method may return a reference to the underlying array so clients should make a copy if the array is written
+ * to.
*
* @return array of all values
*/
diff --git a/store/src/main/java/org/gephi/graph/api/types/IntervalStringMap.java b/src/main/java/org/gephi/graph/api/types/IntervalStringMap.java
similarity index 88%
rename from store/src/main/java/org/gephi/graph/api/types/IntervalStringMap.java
rename to src/main/java/org/gephi/graph/api/types/IntervalStringMap.java
index cbbdd84a..3e03399e 100644
--- a/store/src/main/java/org/gephi/graph/api/types/IntervalStringMap.java
+++ b/src/main/java/org/gephi/graph/api/types/IntervalStringMap.java
@@ -37,8 +37,8 @@ public IntervalStringMap() {
/**
* Constructor with capacity.
*
- * Using this constructor can improve performances if the number of
- * timestamps is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of timestamps is known in advance as it minimizes
+ * array resizes.
*
* @param capacity timestamp capacity
*/
@@ -50,8 +50,7 @@ public IntervalStringMap(int capacity) {
/**
* Constructor with an initial interval map.
*
- * The
+ * Once a map is set on an element's dynamic column, the graph store maintains a time index over its keys. Calling
+ * {@link #put} or {@link #remove} on that instance bypasses the index and leaves it stale. Populate a map before
+ * setting it on an element, and go through the element's
- * The estimator is used to determine the way multiple interval values are
- * merged together (e.g average, first, median).
+ * The estimator is used to determine the way multiple interval values are merged together (e.g average, first,
+ * median).
*
* @param interval interval query
* @param estimator estimator used
@@ -137,8 +141,8 @@ public interface TimeMap
+ * Once a set is attached to an element, the graph store maintains a time index over its keys. Calling {@link #add} or
+ * {@link #remove} on that instance bypasses the index and leaves it stale. Populate a set before setting it on an
+ * element, and go through the element's
- * This method may return a reference to the underlying array so clients
- * should make a copy if the array is written to.
+ * This method may return a reference to the underlying array so clients should make a copy if the array is written
+ * to.
*
* @return array of all keys
*/
public K[] toArray();
/**
- * Returns the same result as {@link #toArray() } but in a primitive array if
- * the underlying storage is in a primtive form.
+ * Returns the same result as {@link #toArray() } but in a primitive array if the underlying storage is in a
+ * primitive form.
*
* @return array of all keys
*/
@@ -102,5 +134,5 @@ public interface TimeSet
- * Using this constructor can improve performances if the number of
- * timestamps is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of timestamps is known in advance as it minimizes
+ * array resizes.
*
* @param capacity timestamp capacity
*/
@@ -63,6 +63,15 @@ public TimestampBooleanMap(double[] keys, boolean[] vals) {
System.arraycopy(vals, 0, values, 0, vals.length);
}
+ /**
+ * Copy constructor.
+ *
+ * @param source the map to copy
+ */
+ public TimestampBooleanMap(TimestampBooleanMap source) {
+ this(source.array, source.values);
+ }
+
/**
* Get the value for the given timestamp.
*
@@ -157,8 +166,8 @@ public Class
- * This method may return a reference to the underlying array so clients
- * should make a copy if the array is written to.
+ * This method may return a reference to the underlying array so clients should make a copy if the array is written
+ * to.
*
* @return array of all values
*/
diff --git a/store/src/main/java/org/gephi/graph/api/types/TimestampByteMap.java b/src/main/java/org/gephi/graph/api/types/TimestampByteMap.java
similarity index 92%
rename from store/src/main/java/org/gephi/graph/api/types/TimestampByteMap.java
rename to src/main/java/org/gephi/graph/api/types/TimestampByteMap.java
index d0f41008..de11da08 100644
--- a/store/src/main/java/org/gephi/graph/api/types/TimestampByteMap.java
+++ b/src/main/java/org/gephi/graph/api/types/TimestampByteMap.java
@@ -38,8 +38,8 @@ public TimestampByteMap() {
/**
* Constructor with capacity.
*
- * Using this constructor can improve performances if the number of
- * timestamps is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of timestamps is known in advance as it minimizes
+ * array resizes.
*
* @param capacity timestamp capacity
*/
@@ -62,6 +62,15 @@ public TimestampByteMap(double[] keys, byte[] vals) {
System.arraycopy(vals, 0, values, 0, vals.length);
}
+ /**
+ * Copy constructor.
+ *
+ * @param source the map to copy
+ */
+ public TimestampByteMap(TimestampByteMap source) {
+ this(source.array, source.values);
+ }
+
/**
* Get the value for the given timestamp.
*
@@ -120,8 +129,8 @@ public Class
- * This method may return a reference to the underlying array so clients
- * should make a copy if the array is written to.
+ * This method may return a reference to the underlying array so clients should make a copy if the array is written
+ * to.
*
* @return array of all values
*/
diff --git a/store/src/main/java/org/gephi/graph/api/types/TimestampCharMap.java b/src/main/java/org/gephi/graph/api/types/TimestampCharMap.java
similarity index 93%
rename from store/src/main/java/org/gephi/graph/api/types/TimestampCharMap.java
rename to src/main/java/org/gephi/graph/api/types/TimestampCharMap.java
index ce3caa53..23685cfd 100644
--- a/store/src/main/java/org/gephi/graph/api/types/TimestampCharMap.java
+++ b/src/main/java/org/gephi/graph/api/types/TimestampCharMap.java
@@ -39,8 +39,8 @@ public TimestampCharMap() {
/**
* Constructor with capacity.
*
- * Using this constructor can improve performances if the number of
- * timestamps is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of timestamps is known in advance as it minimizes
+ * array resizes.
*
* @param capacity timestamp capacity
*/
@@ -63,6 +63,15 @@ public TimestampCharMap(double[] keys, char[] vals) {
System.arraycopy(vals, 0, values, 0, vals.length);
}
+ /**
+ * Copy constructor.
+ *
+ * @param source the map to copy
+ */
+ public TimestampCharMap(TimestampCharMap source) {
+ this(source.array, source.values);
+ }
+
/**
* Get the value for the given timestamp.
*
@@ -153,8 +162,8 @@ public Class
- * This method may return a reference to the underlying array so clients
- * should make a copy if the array is written to.
+ * This method may return a reference to the underlying array so clients should make a copy if the array is written
+ * to.
*
* @return array of all values
*/
diff --git a/store/src/main/java/org/gephi/graph/api/types/TimestampDoubleMap.java b/src/main/java/org/gephi/graph/api/types/TimestampDoubleMap.java
similarity index 91%
rename from store/src/main/java/org/gephi/graph/api/types/TimestampDoubleMap.java
rename to src/main/java/org/gephi/graph/api/types/TimestampDoubleMap.java
index f6e4f1f5..491cab98 100644
--- a/store/src/main/java/org/gephi/graph/api/types/TimestampDoubleMap.java
+++ b/src/main/java/org/gephi/graph/api/types/TimestampDoubleMap.java
@@ -37,8 +37,8 @@ public TimestampDoubleMap() {
/**
* Constructor with capacity.
*
- * Using this constructor can improve performances if the number of
- * timestamps is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of timestamps is known in advance as it minimizes
+ * array resizes.
*
* @param capacity timestamp capacity
*/
@@ -61,6 +61,15 @@ public TimestampDoubleMap(double[] keys, double[] vals) {
System.arraycopy(vals, 0, values, 0, vals.length);
}
+ /**
+ * Copy constructor.
+ *
+ * @param source the map to copy
+ */
+ public TimestampDoubleMap(TimestampDoubleMap source) {
+ this(source.array, source.values);
+ }
+
/**
* Get the value for the given timestamp index.
*
@@ -101,8 +110,8 @@ public Class
- * This method may return a reference to the underlying array so clients
- * should make a copy if the array is written to.
+ * This method may return a reference to the underlying array so clients should make a copy if the array is written
+ * to.
*
* @return array of all values
*/
diff --git a/store/src/main/java/org/gephi/graph/api/types/TimestampFloatMap.java b/src/main/java/org/gephi/graph/api/types/TimestampFloatMap.java
similarity index 92%
rename from store/src/main/java/org/gephi/graph/api/types/TimestampFloatMap.java
rename to src/main/java/org/gephi/graph/api/types/TimestampFloatMap.java
index a5215e11..c0522f3b 100644
--- a/store/src/main/java/org/gephi/graph/api/types/TimestampFloatMap.java
+++ b/src/main/java/org/gephi/graph/api/types/TimestampFloatMap.java
@@ -15,8 +15,8 @@
*/
package org.gephi.graph.api.types;
-import org.gephi.graph.api.Estimator;
import java.math.BigDecimal;
+import org.gephi.graph.api.Estimator;
import org.gephi.graph.api.Interval;
/**
@@ -39,8 +39,8 @@ public TimestampFloatMap() {
/**
* Constructor with capacity.
*
- * Using this constructor can improve performances if the number of
- * timestamps is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of timestamps is known in advance as it minimizes
+ * array resizes.
*
* @param capacity timestamp capacity
*/
@@ -63,6 +63,15 @@ public TimestampFloatMap(double[] keys, float[] vals) {
System.arraycopy(vals, 0, values, 0, vals.length);
}
+ /**
+ * Copy constructor.
+ *
+ * @param source the map to copy
+ */
+ public TimestampFloatMap(TimestampFloatMap source) {
+ this(source.array, source.values);
+ }
+
/**
* Get the value for the given timestamp.
*
@@ -121,8 +130,8 @@ public Class
- * This method may return a reference to the underlying array so clients
- * should make a copy if the array is written to.
+ * This method may return a reference to the underlying array so clients should make a copy if the array is written
+ * to.
*
* @return array of all values
*/
diff --git a/store/src/main/java/org/gephi/graph/api/types/TimestampIntegerMap.java b/src/main/java/org/gephi/graph/api/types/TimestampIntegerMap.java
similarity index 92%
rename from store/src/main/java/org/gephi/graph/api/types/TimestampIntegerMap.java
rename to src/main/java/org/gephi/graph/api/types/TimestampIntegerMap.java
index dbf90b45..404cb2ca 100644
--- a/store/src/main/java/org/gephi/graph/api/types/TimestampIntegerMap.java
+++ b/src/main/java/org/gephi/graph/api/types/TimestampIntegerMap.java
@@ -16,7 +16,6 @@
package org.gephi.graph.api.types;
import org.gephi.graph.api.Estimator;
-import java.math.BigDecimal;
import org.gephi.graph.api.Interval;
/**
@@ -39,8 +38,8 @@ public TimestampIntegerMap() {
/**
* Constructor with capacity.
*
- * Using this constructor can improve performances if the number of
- * timestamps is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of timestamps is known in advance as it minimizes
+ * array resizes.
*
* @param capacity timestamp capacity
*/
@@ -63,6 +62,15 @@ public TimestampIntegerMap(double[] keys, int[] vals) {
System.arraycopy(vals, 0, values, 0, vals.length);
}
+ /**
+ * Copy constructor.
+ *
+ * @param source the map to copy
+ */
+ public TimestampIntegerMap(TimestampIntegerMap source) {
+ this(source.array, source.values);
+ }
+
/**
* Get the value for the given timestamp.
*
@@ -115,8 +123,8 @@ public Class
- * This method may return a reference to the underlying array so clients
- * should make a copy if the array is written to.
+ * This method may return a reference to the underlying array so clients should make a copy if the array is written
+ * to.
*
* @return array of all values
*/
diff --git a/store/src/main/java/org/gephi/graph/api/types/TimestampLongMap.java b/src/main/java/org/gephi/graph/api/types/TimestampLongMap.java
similarity index 92%
rename from store/src/main/java/org/gephi/graph/api/types/TimestampLongMap.java
rename to src/main/java/org/gephi/graph/api/types/TimestampLongMap.java
index 660321e9..1f3905fd 100644
--- a/store/src/main/java/org/gephi/graph/api/types/TimestampLongMap.java
+++ b/src/main/java/org/gephi/graph/api/types/TimestampLongMap.java
@@ -16,7 +16,6 @@
package org.gephi.graph.api.types;
import org.gephi.graph.api.Estimator;
-import java.math.BigDecimal;
import org.gephi.graph.api.Interval;
/**
@@ -39,8 +38,8 @@ public TimestampLongMap() {
/**
* Constructor with capacity.
*
- * Using this constructor can improve performances if the number of
- * timestamps is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of timestamps is known in advance as it minimizes
+ * array resizes.
*
* @param capacity timestamp capacity
*/
@@ -63,6 +62,15 @@ public TimestampLongMap(double[] keys, long[] vals) {
System.arraycopy(vals, 0, values, 0, vals.length);
}
+ /**
+ * Copy constructor.
+ *
+ * @param source the map to copy
+ */
+ public TimestampLongMap(TimestampLongMap source) {
+ this(source.array, source.values);
+ }
+
/**
* Get the value for the given timestamp.
*
@@ -115,8 +123,8 @@ public Class
- * This method may return a reference to the underlying array so clients
- * should make a copy if the array is written to.
+ * This method may return a reference to the underlying array so clients should make a copy if the array is written
+ * to.
*
* @return array of all values
*/
diff --git a/store/src/main/java/org/gephi/graph/api/types/TimestampMap.java b/src/main/java/org/gephi/graph/api/types/TimestampMap.java
similarity index 96%
rename from store/src/main/java/org/gephi/graph/api/types/TimestampMap.java
rename to src/main/java/org/gephi/graph/api/types/TimestampMap.java
index f3f1b0f5..edbb5c98 100644
--- a/store/src/main/java/org/gephi/graph/api/types/TimestampMap.java
+++ b/src/main/java/org/gephi/graph/api/types/TimestampMap.java
@@ -16,22 +16,21 @@
package org.gephi.graph.api.types;
import java.lang.reflect.Array;
-import org.gephi.graph.api.Estimator;
import java.math.BigDecimal;
import java.math.RoundingMode;
+import java.time.ZoneId;
import java.util.Arrays;
import org.gephi.graph.api.AttributeUtils;
+import org.gephi.graph.api.Estimator;
import org.gephi.graph.api.Interval;
import org.gephi.graph.api.TimeFormat;
import org.gephi.graph.impl.FormattingAndParsingUtils;
-import org.joda.time.DateTimeZone;
/**
- * Abstract class that implement a sorted map between timestamp and attribute
- * values.
+ * Abstract class that implement a sorted map between timestamp and attribute values.
*
- * Implementations which extend this class customize the map for a unique type,
- * which is represented by the
- * Using this constructor can improve performances if the number of
- * timestamps is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of timestamps is known in advance as it minimizes
+ * array resizes.
*
* @param capacity timestamp capacity
*/
@@ -267,8 +266,8 @@ public boolean contains(Double timestamp) {
/**
* Returns an array of all timestamps in this map.
*
- * This method may return a reference to the underlying array so clients
- * should make a copy if the array is written to.
+ * This method may return a reference to the underlying array so clients should make a copy if the array is written
+ * to.
*
* @return array of all timestamps
*/
@@ -331,7 +330,8 @@ public boolean equals(Object obj) {
}
Object o1 = this.getValue(i);
Object o2 = other.getValue(i);
- if ((o1 == null && o2 != null) || (o1 != null && o2 == null) || (o1 != null && o2 != null && !o1.equals(o2))) {
+ if ((o1 == null && o2 != null) || (o1 != null && o2 == null) || (o1 != null && o2 != null && !o1
+ .equals(o2))) {
return false;
}
}
@@ -454,7 +454,7 @@ protected Double getAverageDouble(final Interval interval) {
}
@Override
- public String toString(TimeFormat timeFormat, DateTimeZone timeZone) {
+ public String toString(TimeFormat timeFormat, ZoneId zoneId) {
if (size == 0) {
return FormattingAndParsingUtils.EMPTY_VALUE;
}
@@ -465,11 +465,12 @@ public String toString(TimeFormat timeFormat, DateTimeZone timeZone) {
sb.append('<');
for (int i = 0; i < size; i++) {
sb.append('[');
- sb.append(AttributeUtils.printTimestampInFormat(array[i], timeFormat, timeZone));
+ sb.append(AttributeUtils.printTimestampInFormat(array[i], timeFormat, zoneId));
sb.append(", ");
String stringValue = values[i].toString();
- if (FormattingAndParsingUtils.containsDynamicSpecialCharacters(stringValue) || stringValue.trim().isEmpty()) {
+ if (FormattingAndParsingUtils.containsDynamicSpecialCharacters(stringValue) || stringValue.trim()
+ .isEmpty()) {
sb.append('"');
sb.append(stringValue.replace("\\", "\\\\").replace("\"", "\\\""));
sb.append('"');
diff --git a/store/src/main/java/org/gephi/graph/api/types/TimestampSet.java b/src/main/java/org/gephi/graph/api/types/TimestampSet.java
similarity index 88%
rename from store/src/main/java/org/gephi/graph/api/types/TimestampSet.java
rename to src/main/java/org/gephi/graph/api/types/TimestampSet.java
index 1c0074b4..281cf283 100644
--- a/store/src/main/java/org/gephi/graph/api/types/TimestampSet.java
+++ b/src/main/java/org/gephi/graph/api/types/TimestampSet.java
@@ -15,11 +15,11 @@
*/
package org.gephi.graph.api.types;
+import java.time.ZoneId;
import java.util.Arrays;
import org.gephi.graph.api.AttributeUtils;
import org.gephi.graph.api.TimeFormat;
import org.gephi.graph.impl.FormattingAndParsingUtils;
-import org.joda.time.DateTimeZone;
/**
* Sorted set for timestamps.
@@ -41,8 +41,8 @@ public TimestampSet() {
/**
* Constructor with capacity.
*
- * Using this constructor can improve performances if the number of
- * timestamps is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of timestamps is known in advance as it minimizes
+ * array resizes.
*
* @param capacity timestamp capacity
*/
@@ -64,6 +64,15 @@ public TimestampSet(double[] arr) {
size = arr.length;
}
+ /**
+ * Copy constructor.
+ *
+ * @param source the set to copy
+ */
+ public TimestampSet(TimestampSet source) {
+ this(source.array);
+ }
+
@Override
public boolean add(Double timestamp) {
return addInner(timestamp) >= 0;
@@ -84,6 +93,32 @@ public boolean isEmpty() {
return size == 0;
}
+ @Override
+ public Double getMax() {
+ if (size > 0) {
+ return array[array.length - 1];
+ }
+ return null;
+ }
+
+ @Override
+ public Double getMin() {
+ if (size > 0) {
+ return array[0];
+ }
+ return null;
+ }
+
+ @Override
+ public Double getMaxDouble() {
+ return getMax();
+ }
+
+ @Override
+ public Double getMinDouble() {
+ return getMin();
+ }
+
@Override
public boolean contains(Double timestamp) {
int index = Arrays.binarySearch(array, timestamp);
@@ -191,7 +226,7 @@ public boolean equals(Object obj) {
}
@Override
- public String toString(TimeFormat timeFormat, DateTimeZone timeZone) {
+ public String toString(TimeFormat timeFormat, ZoneId timeZone) {
if (size == 0) {
return FormattingAndParsingUtils.EMPTY_VALUE;
}
diff --git a/store/src/main/java/org/gephi/graph/api/types/TimestampShortMap.java b/src/main/java/org/gephi/graph/api/types/TimestampShortMap.java
similarity index 92%
rename from store/src/main/java/org/gephi/graph/api/types/TimestampShortMap.java
rename to src/main/java/org/gephi/graph/api/types/TimestampShortMap.java
index 94a77295..0c5b3a2e 100644
--- a/store/src/main/java/org/gephi/graph/api/types/TimestampShortMap.java
+++ b/src/main/java/org/gephi/graph/api/types/TimestampShortMap.java
@@ -16,7 +16,6 @@
package org.gephi.graph.api.types;
import org.gephi.graph.api.Estimator;
-import java.math.BigDecimal;
import org.gephi.graph.api.Interval;
/**
@@ -39,8 +38,8 @@ public TimestampShortMap() {
/**
* Constructor with capacity.
*
- * Using this constructor can improve performances if the number of
- * timestamps is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of timestamps is known in advance as it minimizes
+ * array resizes.
*
* @param capacity timestamp capacity
*/
@@ -63,6 +62,15 @@ public TimestampShortMap(double[] keys, short[] vals) {
System.arraycopy(vals, 0, values, 0, vals.length);
}
+ /**
+ * Copy constructor.
+ *
+ * @param source the map to copy
+ */
+ public TimestampShortMap(TimestampShortMap source) {
+ this(source.array, source.values);
+ }
+
/**
* Get the value for the given timestamp.
*
@@ -115,8 +123,8 @@ public Class
- * This method may return a reference to the underlying array so clients
- * should make a copy if the array is written to.
+ * This method may return a reference to the underlying array so clients should make a copy if the array is written
+ * to.
*
* @return array of all values
*/
diff --git a/store/src/main/java/org/gephi/graph/api/types/TimestampStringMap.java b/src/main/java/org/gephi/graph/api/types/TimestampStringMap.java
similarity index 89%
rename from store/src/main/java/org/gephi/graph/api/types/TimestampStringMap.java
rename to src/main/java/org/gephi/graph/api/types/TimestampStringMap.java
index 28bbfdb1..26988049 100644
--- a/store/src/main/java/org/gephi/graph/api/types/TimestampStringMap.java
+++ b/src/main/java/org/gephi/graph/api/types/TimestampStringMap.java
@@ -37,8 +37,8 @@ public TimestampStringMap() {
/**
* Constructor with capacity.
*
- * Using this constructor can improve performances if the number of
- * timestamps is known in advance as it minimizes array resizes.
+ * Using this constructor can improve performances if the number of timestamps is known in advance as it minimizes
+ * array resizes.
*
* @param capacity timestamp capacity
*/
@@ -61,6 +61,15 @@ public TimestampStringMap(double[] keys, String[] vals) {
System.arraycopy(vals, 0, values, 0, vals.length);
}
+ /**
+ * Copy constructor.
+ *
+ * @param source the map to copy
+ */
+ public TimestampStringMap(TimestampStringMap source) {
+ this(source.array, source.values);
+ }
+
@Override
public Class
@@ -82,8 +81,6 @@ public static Instant
+ * only
+ * @return an instance of the type class, or null if str is null or empty
*/
- public static Object parse(String str, Class typeClass, DateTimeZone timeZone) {
+ public static Object parse(String str, Class typeClass, ZoneId zoneId) {
if (str == null || str.isEmpty()) {
return null;
}
+ if (str.equalsIgnoreCase("null")) {
+ return null;
+ }
+
if (typeClass.isPrimitive()) {
typeClass = getStandardizedType(typeClass);// For primitives we can
// use auto-unboxing
@@ -360,17 +384,17 @@ public static Object parse(String str, Class typeClass, DateTimeZone timeZone) {
if (typeClass.equals(String.class)) {
return str;
} else if (typeClass.equals(Byte.class)) {
- return new Byte(str);
+ return Byte.valueOf(str);
} else if (typeClass.equals(Short.class)) {
- return new Short(str);
+ return Short.valueOf(str);
} else if (typeClass.equals(Integer.class)) {
- return new Integer(str);
+ return Integer.valueOf(str);
} else if (typeClass.equals(Long.class)) {
- return new Long(str);
+ return Long.valueOf(str);
} else if (typeClass.equals(Float.class)) {
- return new Float(str);
+ return Float.valueOf(str);
} else if (typeClass.equals(Double.class)) {
- return new Double(str);
+ return Double.valueOf(str);
} else if (typeClass.equals(BigInteger.class)) {
return new BigInteger(str);
} else if (typeClass.equals(BigDecimal.class)) {
@@ -391,50 +415,56 @@ public static Object parse(String str, Class typeClass, DateTimeZone timeZone) {
return str.charAt(0);
}
+ // Instant
+ if (typeClass.equals(Instant.class)) {
+ double milliseconds = FormattingAndParsingUtils.parseDateTimeOrTimestamp(str, zoneId);
+ return Instant.ofEpochMilli(Math.round(milliseconds));
+ }
+
// Interval types:
if (typeClass.equals(IntervalSet.class)) {
- return IntervalsParser.parseIntervalSet(str, timeZone);
+ return IntervalsParser.parseIntervalSet(str, zoneId);
} else if (typeClass.equals(IntervalStringMap.class)) {
- return IntervalsParser.parseIntervalMap(String.class, str, timeZone);
+ return IntervalsParser.parseIntervalMap(String.class, str, zoneId);
} else if (typeClass.equals(IntervalByteMap.class)) {
- return IntervalsParser.parseIntervalMap(Byte.class, str, timeZone);
+ return IntervalsParser.parseIntervalMap(Byte.class, str, zoneId);
} else if (typeClass.equals(IntervalShortMap.class)) {
- return IntervalsParser.parseIntervalMap(Short.class, str, timeZone);
+ return IntervalsParser.parseIntervalMap(Short.class, str, zoneId);
} else if (typeClass.equals(IntervalIntegerMap.class)) {
- return IntervalsParser.parseIntervalMap(Integer.class, str, timeZone);
+ return IntervalsParser.parseIntervalMap(Integer.class, str, zoneId);
} else if (typeClass.equals(IntervalLongMap.class)) {
- return IntervalsParser.parseIntervalMap(Long.class, str, timeZone);
+ return IntervalsParser.parseIntervalMap(Long.class, str, zoneId);
} else if (typeClass.equals(IntervalFloatMap.class)) {
- return IntervalsParser.parseIntervalMap(Float.class, str, timeZone);
+ return IntervalsParser.parseIntervalMap(Float.class, str, zoneId);
} else if (typeClass.equals(IntervalDoubleMap.class)) {
- return IntervalsParser.parseIntervalMap(Double.class, str, timeZone);
+ return IntervalsParser.parseIntervalMap(Double.class, str, zoneId);
} else if (typeClass.equals(IntervalBooleanMap.class)) {
- return IntervalsParser.parseIntervalMap(Boolean.class, str, timeZone);
+ return IntervalsParser.parseIntervalMap(Boolean.class, str, zoneId);
} else if (typeClass.equals(IntervalCharMap.class)) {
- return IntervalsParser.parseIntervalMap(Character.class, str, timeZone);
+ return IntervalsParser.parseIntervalMap(Character.class, str, zoneId);
}
// Timestamp types:
if (typeClass.equals(TimestampSet.class)) {
- return TimestampsParser.parseTimestampSet(str, timeZone);
+ return TimestampsParser.parseTimestampSet(str, zoneId);
} else if (typeClass.equals(TimestampStringMap.class)) {
- return TimestampsParser.parseTimestampMap(String.class, str, timeZone);
+ return TimestampsParser.parseTimestampMap(String.class, str, zoneId);
} else if (typeClass.equals(TimestampByteMap.class)) {
- return TimestampsParser.parseTimestampMap(Byte.class, str, timeZone);
+ return TimestampsParser.parseTimestampMap(Byte.class, str, zoneId);
} else if (typeClass.equals(TimestampShortMap.class)) {
- return TimestampsParser.parseTimestampMap(Short.class, str, timeZone);
+ return TimestampsParser.parseTimestampMap(Short.class, str, zoneId);
} else if (typeClass.equals(TimestampIntegerMap.class)) {
- return TimestampsParser.parseTimestampMap(Integer.class, str, timeZone);
+ return TimestampsParser.parseTimestampMap(Integer.class, str, zoneId);
} else if (typeClass.equals(TimestampLongMap.class)) {
- return TimestampsParser.parseTimestampMap(Long.class, str, timeZone);
+ return TimestampsParser.parseTimestampMap(Long.class, str, zoneId);
} else if (typeClass.equals(TimestampFloatMap.class)) {
- return TimestampsParser.parseTimestampMap(Float.class, str, timeZone);
+ return TimestampsParser.parseTimestampMap(Float.class, str, zoneId);
} else if (typeClass.equals(TimestampDoubleMap.class)) {
- return TimestampsParser.parseTimestampMap(Double.class, str, timeZone);
+ return TimestampsParser.parseTimestampMap(Double.class, str, zoneId);
} else if (typeClass.equals(TimestampBooleanMap.class)) {
- return TimestampsParser.parseTimestampMap(Boolean.class, str, timeZone);
+ return TimestampsParser.parseTimestampMap(Boolean.class, str, zoneId);
} else if (typeClass.equals(TimestampCharMap.class)) {
- return TimestampsParser.parseTimestampMap(Character.class, str, timeZone);
+ return TimestampsParser.parseTimestampMap(Character.class, str, zoneId);
}
// Array types:
@@ -455,25 +485,25 @@ public static Object parse(String str, Class typeClass, DateTimeZone timeZone) {
} else if (typeClass.equals(double[].class)) {
return ArraysParser.parseArrayAsPrimitiveArray(Double[].class, str);
} else if (typeClass.equals(Boolean[].class) || typeClass.equals(String[].class) || typeClass
- .equals(Character[].class) || typeClass.equals(Byte[].class) || typeClass.equals(Short[].class) || typeClass
- .equals(Integer[].class) || typeClass.equals(Long[].class) || typeClass.equals(Float[].class) || typeClass
- .equals(Double[].class) || typeClass.equals(BigInteger[].class) || typeClass.equals(BigDecimal[].class)) {
+ .equals(Character[].class) || typeClass.equals(Byte[].class) || typeClass
+ .equals(Short[].class) || typeClass.equals(Integer[].class) || typeClass
+ .equals(Long[].class) || typeClass.equals(Float[].class) || typeClass
+ .equals(Double[].class) || typeClass
+ .equals(BigInteger[].class) || typeClass.equals(BigDecimal[].class)) {
return ArraysParser.parseArray(typeClass, str);
}
- throw new IllegalArgumentException("Unsupported type " + typeClass.getClass().getCanonicalName());
+ throw new IllegalArgumentException("Unsupported type " + typeClass.getCanonicalName());
}
/**
- * Parses the given string using the type class provided and returns an
- * instance.
+ * Parses the given string using the type class provided and returns an instance.
*
* Default time zone is used (UTC) for dynamic types (timestamps/intervals).
*
* @param str string to parse
* @param typeClass class of the desired type
- * @return an instance of the type class, or null if str is null or
- * empty
+ * @return an instance of the type class, or null if str is null or empty
*/
public static Object parse(String str, Class typeClass) {
return parse(str, typeClass, null);
@@ -517,15 +547,15 @@ public static Class getPrimitiveType(Class type) {
*
* @param array wrapped primitive array instance
* @return primitive array instance
- * @throws IllegalArgumentException Thrown if any of the array values is
- * null
+ * @throws IllegalArgumentException Thrown if any of the array values is null
*/
public static Object getPrimitiveArray(Object[] array) {
if (!isSupported(array.getClass())) {
throw new IllegalArgumentException("Unsupported type " + array.getClass().getCanonicalName());
}
Class arrayClass = array.getClass().getComponentType();
- if (!arrayClass.isPrimitive() && (arrayClass == Double.class || arrayClass == Float.class || arrayClass == Long.class || arrayClass == Integer.class || arrayClass == Short.class || arrayClass == Character.class || arrayClass == Byte.class || arrayClass == Boolean.class)) {
+ if (!arrayClass
+ .isPrimitive() && (arrayClass == Double.class || arrayClass == Float.class || arrayClass == Long.class || arrayClass == Integer.class || arrayClass == Short.class || arrayClass == Character.class || arrayClass == Byte.class || arrayClass == Boolean.class)) {
Class primitiveClass = getPrimitiveType(arrayClass);
int arrayLength = array.length;
@@ -565,8 +595,7 @@ public static boolean isSupported(Class type) {
/**
* Returns the standardized type for the given type class.
* getStandardizedType(int.class) would return
- * Integer.class.
+ * For instance, getStandardizedType(int.class) would return Integer.class.
*
* @param type type to standardize
* @return standardized type
@@ -698,8 +727,7 @@ public static Class getStaticType(Class extends TimeMap> type) {
}
/**
- * Transform the given value instance in a standardized type if
- * necessary.
+ * Transform the given value instance in a standardized type if necessary.
* hasColumnChanged() method to check the status. Each call resets
- * the observer so if the method returns true and the table doesn't change after
- * that it will return false next time.
+ * Column observer users should periodically call the hasColumnChanged() method to check the status. Each
+ * call resets the observer so if the method returns true and the table doesn't change after that it will return false
+ * next time.
* Column.
+ * Observers should be destroyed when not needed anymore. A new observer can be obtained from the Column.
*
* @see Column
*/
diff --git a/src/main/java/org/gephi/graph/api/Configuration.java b/src/main/java/org/gephi/graph/api/Configuration.java
new file mode 100644
index 00000000..150ee2fd
--- /dev/null
+++ b/src/main/java/org/gephi/graph/api/Configuration.java
@@ -0,0 +1,673 @@
+/*
+ * Copyright 2012-2013 Gephi Consortium
+ *
+ * Licensed 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.gephi.graph.api;
+
+import org.gephi.graph.api.types.IntervalDoubleMap;
+import org.gephi.graph.api.types.TimestampDoubleMap;
+import org.gephi.graph.impl.ConfigurationImpl;
+
+/**
+ * Global configuration set at initialization.
+ *
+ * Configuration config = Configuration.builder().build();
+ *
+ * String.class and the time representation is
+ * TIMESTAMP.
+ * builder() method instead.
+ */
+ @Deprecated
+ public Configuration() {
+ this.delegate = new ConfigurationImpl();
+ }
+
+ protected Configuration(ConfigurationImpl delegate) {
+ this.delegate = delegate;
+ }
+
+ /**
+ * Creates a new builder.
+ *
+ * @return a new builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Configuration builder.
+ * String.class.
+ *
+ * @param nodeIdType node id type
+ * @return this builder
+ * @throws IllegalArgumentException if the type isn't supported
+ */
+ public Builder nodeIdType(final Class nodeIdType) {
+ checkSimpleType(nodeIdType);
+ this.configuration = new ConfigurationImpl(new Configuration(this.configuration) {
+ @Override
+ public Class getNodeIdType() {
+ return nodeIdType;
+ }
+ });
+ return this;
+ }
+
+ /**
+ * Sets the edge id type.
+ * String.class.
+ *
+ * @param edgeIdType edge id type
+ * @return this builder
+ * @throws IllegalArgumentException if the type isn't supported
+ */
+ public Builder edgeIdType(final Class edgeIdType) {
+ checkSimpleType(edgeIdType);
+ this.configuration = new ConfigurationImpl(new Configuration(this.configuration) {
+ @Override
+ public Class getEdgeIdType() {
+ return edgeIdType;
+ }
+ });
+ return this;
+ }
+
+ /**
+ * Sets the edge label type.
+ * String.class.
+ *
+ * @param edgeLabelType edge label type
+ * @return this builder
+ * @throws IllegalArgumentException if the type isn't supported
+ */
+ public Builder edgeLabelType(final Class edgeLabelType) {
+ checkSimpleType(edgeLabelType);
+ this.configuration = new ConfigurationImpl(new Configuration(this.configuration) {
+ @Override
+ public Class getEdgeLabelType() {
+ return edgeLabelType;
+ }
+ });
+ return this;
+ }
+
+ /**
+ * Sets the edge weight type.
+ * Double, IntervalDoubleMap and TimestampDoubleMap are supported.
+ * Double.class.
+ *
+ * @param edgeWeightType edge weight type
+ * @return this builder
+ * @throws IllegalArgumentException if the type isn't supported
+ */
+ public Builder edgeWeightType(final Class edgeWeightType) {
+ if (!(Double.class.equals(edgeWeightType) || TimestampDoubleMap.class
+ .equals(edgeWeightType) || IntervalDoubleMap.class.equals(edgeWeightType))) {
+ throw new IllegalArgumentException("Unsupported type " + edgeWeightType
+ .getCanonicalName() + ", should be Double, IntervalDoubleMap or TimestampDoubleMap");
+ }
+ this.configuration = new ConfigurationImpl(new Configuration(this.configuration) {
+ @Override
+ public Class getEdgeWeightType() {
+ return edgeWeightType;
+ }
+ });
+ return this;
+ }
+
+ /**
+ * Sets the time representation.
+ * TIMESTAMP.
+ *
+ * @param timeRepresentation time representation
+ * @return this builder
+ */
+ public Builder timeRepresentation(final TimeRepresentation timeRepresentation) {
+ if (timeRepresentation == null) {
+ throw new IllegalArgumentException("timeRepresentation cannot be null");
+ }
+ this.configuration = new ConfigurationImpl(new Configuration(this.configuration) {
+ @Override
+ public TimeRepresentation getTimeRepresentation() {
+ return timeRepresentation;
+ }
+ });
+ return this;
+ }
+
+ /**
+ * Sets whether to create an edge weight column.
+ * true.
+ *
+ * @param edgeWeightColumn edge weight column
+ * @return this builder
+ */
+ public Builder edgeWeightColumn(final boolean edgeWeightColumn) {
+ this.configuration = new ConfigurationImpl(new Configuration(this.configuration) {
+ @Override
+ public Boolean getEdgeWeightColumn() {
+ return edgeWeightColumn;
+ }
+ });
+ return this;
+ }
+
+ /**
+ * Sets whether to enable observers on tables and columns.
+ * true.
+ *
+ * @param enableObservers enable observers
+ * @return this builder
+ */
+ public Builder enableObservers(final boolean enableObservers) {
+ this.configuration = new ConfigurationImpl(new Configuration(this.configuration) {
+ @Override
+ public boolean isEnableObservers() {
+ return enableObservers;
+ }
+ });
+ return this;
+ }
+
+ /**
+ * Sets whether to enable auto edge type registration.
+ * true.
+ *
+ * @param enableAutoEdgeTypeRegistration enable auto edge type registration
+ * @return this builder
+ */
+ public Builder enableAutoEdgeTypeRegistration(final boolean enableAutoEdgeTypeRegistration) {
+ this.configuration = new ConfigurationImpl(new Configuration(this.configuration) {
+ @Override
+ public boolean isEnableAutoEdgeTypeRegistration() {
+ return enableAutoEdgeTypeRegistration;
+ }
+ });
+ return this;
+ }
+
+ /**
+ * Sets whether to enable node properties.
+ * true.
+ *
+ * @param enableNodeProperties enable node properties
+ * @return this builder
+ */
+ public Builder enableNodeProperties(final boolean enableNodeProperties) {
+ this.configuration = new ConfigurationImpl(new Configuration(this.configuration) {
+ @Override
+ public boolean isEnableNodeProperties() {
+ return enableNodeProperties;
+ }
+ });
+ return this;
+ }
+
+ /**
+ * Sets whether to enable edge properties.
+ * true.
+ *
+ * @param enableEdgeProperties enable edge properties
+ * @return this builder
+ */
+ public Builder enableEdgeProperties(final boolean enableEdgeProperties) {
+ this.configuration = new ConfigurationImpl(new Configuration(this.configuration) {
+ @Override
+ public boolean isEnableEdgeProperties() {
+ return enableEdgeProperties;
+ }
+ });
+ return this;
+ }
+
+ /**
+ * Sets whether to enable the {@link SpatialIndex}.
+ * false.
+ *
+ * @param enableSpatialIndex enable edge properties
+ * @return this builder
+ */
+ public Builder enableSpatialIndex(final boolean enableSpatialIndex) {
+ this.configuration = new ConfigurationImpl(new Configuration(this.configuration) {
+ @Override
+ public boolean isEnableSpatialIndex() {
+ return enableSpatialIndex;
+ }
+ });
+ return this;
+ }
+
+ /**
+ * Sets whether to enable the reverse indexing of node attributes.
+ * true.
+ *
+ * @param enableIndexNodes enable node attribute indexing
+ * @return this builder
+ */
+ public Builder enableIndexNodes(final boolean enableIndexNodes) {
+ this.configuration = new ConfigurationImpl(new Configuration(this.configuration) {
+ @Override
+ public boolean isEnableIndexNodes() {
+ return enableIndexNodes;
+ }
+ });
+ return this;
+ }
+
+ /**
+ * Sets whether to enable the reverse indexing of edge attributes.
+ * true.
+ *
+ * @param enableIndexEdges enable edge attribute indexing
+ * @return this builder
+ */
+ public Builder enableIndexEdges(final boolean enableIndexEdges) {
+ this.configuration = new ConfigurationImpl(new Configuration(this.configuration) {
+ @Override
+ public boolean isEnableIndexEdges() {
+ return enableIndexEdges;
+ }
+ });
+ return this;
+ }
+
+ /**
+ * Sets whether to enable the reverse indexing of timestamps and intervals.
+ * true.
+ *
+ * @param enableIndexTime enable time indexing
+ * @return this builder
+ */
+ public Builder enableIndexTime(final boolean enableIndexTime) {
+ this.configuration = new ConfigurationImpl(new Configuration(this.configuration) {
+ @Override
+ public boolean isEnableIndexTime() {
+ return enableIndexTime;
+ }
+ });
+ return this;
+ }
+
+ /**
+ * Sets whether to enable multiple edges of the same type between two nodes.
+ * false.
+ *
+ * @param enableParallelEdgesSameType enable parallel edges of the same type
+ * @return this builder
+ */
+ public Builder enableParallelEdgesSameType(final boolean enableParallelEdgesSameType) {
+ this.configuration = new ConfigurationImpl(new Configuration(this.configuration) {
+ @Override
+ public boolean isEnableParallelEdgesSameType() {
+ return enableParallelEdgesSameType;
+ }
+ });
+ return this;
+ }
+
+ /**
+ * Sets whether to enable auto locking when using read/write APIs.
+ * true.
+ *
+ * @param enableAutoLocking enable auto locking for read/write operations
+ * @see GraphLock
+ * @return this builder
+ */
+ public Builder enableAutoLocking(final boolean enableAutoLocking) {
+ this.configuration = new ConfigurationImpl(new Configuration(this.configuration) {
+ @Override
+ public boolean isEnableAutoLocking() {
+ return enableAutoLocking;
+ }
+ });
+ return this;
+ }
+
+ private static void checkSimpleType(Class type) {
+ if (!AttributeUtils.isSimpleType(type)) {
+ throw new IllegalArgumentException("Unsupported type " + type.getCanonicalName());
+ }
+ }
+ }
+
+ /**
+ * Returns the node id type.
+ *
+ * @return node id type
+ */
+ public Class getNodeIdType() {
+ return delegate.getNodeIdType();
+ }
+
+ /**
+ * Sets the node id type.
+ * setAttribute and removeAttribute methods that take
+ * a time instead.
*
* @param key column's key
* @return attribute value, or null
@@ -47,6 +52,11 @@ public interface Element extends ElementProperties {
/**
* Gets the attribute for the given column.
+ * setAttribute and removeAttribute methods that take
+ * a time instead.
*
* @param column column
* @return attribute value, or null
@@ -108,8 +118,7 @@ public interface Element extends ElementProperties {
public Object getAttribute(Column column, GraphView view);
/**
- * Returns an iterable over all the keys and values over time for the given
- * column.
+ * Returns an iterable over all the keys and values over time for the given (dynamic) column.
*
* @param column column
* @return time attribute iterable
@@ -319,6 +328,15 @@ public interface Element extends ElementProperties {
*/
public Interval[] getIntervals();
+ /**
+ * Gets the time bounds.
+ * estimators.
+ * Returns true if this estimator is any of the given estimators.
*
* @param estimators estimators to test equality
* @return true if estimators contains this estimator
diff --git a/store/src/main/java/org/gephi/graph/api/Graph.java b/src/main/java/org/gephi/graph/api/Graph.java
similarity index 87%
rename from store/src/main/java/org/gephi/graph/api/Graph.java
rename to src/main/java/org/gephi/graph/api/Graph.java
index 5209c1dc..217d0d49 100644
--- a/store/src/main/java/org/gephi/graph/api/Graph.java
+++ b/src/main/java/org/gephi/graph/api/Graph.java
@@ -89,6 +89,22 @@ public interface Graph {
*/
public boolean removeAllNodes(Collection extends Node> nodes);
+ /**
+ * Retains only nodes in this graph that are contained in the specified collection.
+ *
+ * @param nodes the node collection
+ * @return true if at least one node has been removed, false otherwise
+ */
+ public boolean retainNodes(Collection extends Node> nodes);
+
+ /**
+ * Retains only edges in this graph that are contained in the specified collection.
+ *
+ * @param edges the edge collection
+ * @return true if at least one edge has been removed, false otherwise
+ */
+ public boolean retainEdges(Collection extends Edge> edges);
+
/**
* Returns true if node is contained in this graph.
*
@@ -113,6 +129,14 @@ public interface Graph {
*/
public Node getNode(Object id);
+ /**
+ * Gets a node given its store id.
+ *
+ * @param storeId the store id
+ * @return the node, or null if not found
+ */
+ public Node getNodeByStoreId(int storeId);
+
/**
* Returns true if a node with id as identifier exists.
*
@@ -129,6 +153,14 @@ public interface Graph {
*/
public Edge getEdge(Object id);
+ /**
+ * Gets an edge given its store id.
+ *
+ * @param storeId the store id
+ * @return the edge, or null if not found
+ */
+ public Edge getEdgeByStoreId(int storeId);
+
/**
* Returns true if an edge with id as identifier exists.
*
@@ -197,6 +229,14 @@ public interface Graph {
*/
public EdgeIterable getEdges();
+ /**
+ * Gets all the edges of a particular type in the graph.
+ *
+ * @param type edge type
+ * @return an edge iterable over all edges of this type
+ */
+ public EdgeIterable getEdges(int type);
+
/**
* Gets all the self-loop edges in the graph.
*
@@ -303,14 +343,12 @@ public interface Graph {
public boolean isAdjacent(Node node1, Node node2);
/**
- * Returns true if node1 and node2 are adjacent with an edge of the given
- * type.
+ * Returns true if node1 and node2 are adjacent with an edge of the given type.
*
* @param node1 the first node
* @param node2 the second node
* @param type the edge type
- * @return true if node1 and node2 are adjacent with an edge og the given
- * type, false otherwise
+ * @return true if node1 and node2 are adjacent with an edge og the given type, false otherwise
*/
public boolean isAdjacent(Node node1, Node node2, int type);
@@ -453,6 +491,16 @@ public interface Graph {
*/
public GraphModel getModel();
+ /**
+ * Returns a version number for this graph.
+ * nodes typically belong to another graph store. If nodes
- * already exists in the current graph they will be ignored.
+ * The nodes typically belong to another graph store. If nodes already exists in the current graph they
+ * will be ignored.
* nodes will be copied as well if their
- * source and target exists in this graph store.
+ * All edges attached to nodes will be copied as well if their source and target exists in this graph
+ * store.
* ReentrantReadWriteLock that controls multi-thread access to the graph structure.
+ */
+public interface GraphLock {
+
+ /**
+ * Acquires the read lock. Acquires the read lock if the write lock is not held by another thread and returns
+ * immediately.
+ * GraphModel is the entry point for this API and provide methods
- * to create, access and modify graphs. It supports the most common graph
- * paradigms and a complete support for graphs over time as well.
+ * GraphModel is the entry point for this API and provide methods to create, access and modify graphs. It
+ * supports the most common graph paradigms and a complete support for graphs over time as well.
*
- *
*
* GraphModel model = GraphModel.Factory.newInstance();
*
- *
- * This API revolves around a set of simple concepts. A GraphModel
- * encapsulate all elements and metadata associated with a graph structure. In
- * other words its a single graph but it also contains configuration, indices,
+ *
+ * A Configuration object can be passed to the factory:
+ *
+ *
+ * Configuration configuration = Configuration.builder().build();
+ * GraphModel model = GraphModel.Factory.newInstance(configuration);
+ *
+ *
+ * This API revolves around a set of simple concepts. A GraphModel encapsulate all elements and metadata
+ * associated with a graph structure. In other words it's a single graph, but it also contains configuration, indices,
* views and other less important services such as observers.
* GraphModel gives access to the Graph
- * interface, which focuses only on the graph structure and provide methods to
- * add, remove, get and iterate nodes and edges.
+ * Then, GraphModel gives access to the Graph interface, which focuses only on the graph
+ * structure and provide methods to add, remove, get and iterate nodes and edges.
* Graph contains nodes and edges, which both implement the
- * Element interface. This Element interface gives
- * access to methods that manipulate the attributes associated to nodes and
- * edges.
+ * The Graph contains nodes and edges, which both implement the Element interface. This
+ * Element interface gives access to methods that manipulate the attributes associated to nodes and edges.
* Table and Column interfaces. A
- * GraphModel gives access by default to a node and edge table. A
- * Table is simply a list of columns, which each has a unique
- * identifier and a type (e.g. integer). Attribute values can only be associated
- * with elements for existing columns.
+ * Any number of attributes can be associated to elements but are managed through the Table and
+ * Column interfaces. A GraphModel gives access by default to a node and edge table. A
+ * Table is simply a list of columns, which each has a unique identifier and a type (e.g. integer).
+ * Attribute values can only be associated with elements for existing columns.
* Index
- * interface.
+ * Attributes are automatically indexed and information such as the number of elements with a particular value can be
+ * obtained from the Index interface.
* Subgraph for a
- * specific GraphView. Views can directly be created and destroyed
- * from this model.
+ * Finally, this API supports the concept of graph views. A view is a mask on the graph structure and represents a
+ * subgraph. The user controls the set of nodes and edges in the view by obtaining a Subgraph for a
+ * specific GraphView. Views can directly be created and destroyed from this model.
* null label, which is internally represented as zero.
+ * For performance reasons, edge labels are internally represented as integers and the mapping between arbitrary labels
+ * is managed through the {@link #addEdgeType(java.lang.Object) } and {@link #getEdgeType(java.lang.Object) } methods.
+ * By default, edges have a null label, which is internally represented as zero.
*
* @see Graph
+ * @see Configuration
* @see Element
* @see Table
* @see Column
@@ -102,7 +96,7 @@ public static class Factory {
*
* @return new instance
*/
- public static GraphModel newInstance() {
+ public static GraphModelImpl newInstance() {
return new GraphModelImpl();
}
@@ -112,7 +106,7 @@ public static GraphModel newInstance() {
* @param config configuration
* @return new instance
*/
- public static GraphModel newInstance(Configuration config) {
+ public static GraphModelImpl newInstance(Configuration config) {
return new GraphModelImpl(config);
}
}
@@ -139,10 +133,25 @@ public static GraphModel read(DataInput input) throws IOException {
}
/**
- * Read the input and return the read graph model without
- * an explicit version header in the input. To be used with old
- * graphstore serialized data prior to version 0.4 (first, that added
- * the version header).
+ * Read the input into the given graph model. The provided graph model should be empty and the
+ * configurations should match between the provided model and the one being read.
+ *
+ * @param input data input to read from
+ * @return the graphmodel passed as parameter
+ * @throws IOException if an io error occurs
+ */
+ public static GraphModel read(DataInput input, GraphModel graphModel) throws IOException {
+ try {
+ org.gephi.graph.impl.Serialization s = new org.gephi.graph.impl.Serialization();
+ return s.deserializeGraphModel(input, graphModel);
+ } catch (ClassNotFoundException e) {
+ throw new IOException(e);
+ }
+ }
+
+ /**
+ * Read the input and return the read graph model without an explicit version header in the input.
+ * To be used with old graphstore serialized data prior to version 0.4 (first, that added the version header).
*
* @param input data input to read from
* @param graphStoreVersion Forced version to use
@@ -171,6 +180,99 @@ public static void write(DataOutput output, GraphModel graphModel) throws IOExce
}
}
+ /**
+ * Default columns utility.
+ */
+ public static interface DefaultColumns {
+
+ /**
+ * Return node identifier column.
+ * GraphModel always has node and edge tables
- * by default.
+ * A GraphModel always has node and edge tables by default.
*
* @return node table, contains node columns
*/
public Table getNodeTable();
/**
- * Returns the edge table. Contains all the columns associated to
- * edge elements.
+ * Returns the edge table. Contains all the columns associated to edge elements.
* GraphModel always has node and edge tables
- * by default.
+ * A GraphModel always has node and edge tables by default.
*
* @return edge table, contains edge columns
*/
@@ -463,6 +595,23 @@ public static void write(DataOutput output, GraphModel graphModel) throws IOExce
*/
public IndexhasGraphChanged() method to check the status. Each call resets
- * the observer so if the method returns true and the graph doesn't change after
- * that it will return false next time.
+ * Graph observer users should periodically call the hasGraphChanged() method to check the status. Each
+ * call resets the observer so if the method returns true and the graph doesn't change after that it will return false
+ * next time.
* getDiff() method after calling
+ * In addition of a boolean flag whether the graph has changed, an observer can collect data about the differences such
+ * as nodes added or removed. Users should call the getDiff() method after calling
* hasGraphChanged() to obtain the diff.
* GraphModel.
+ * Observers should be destroyed when not needed anymore. A new observer can be obtained from the
+ * GraphModel.
* Subgraph
- * object from it. Users can call the
- * {@link GraphModel#getGraph(org.gephi.graph.api.GraphView) } method and obtain
- * a subgraph backed by the view. Update operations such as add or remove on
- * this graph are in-fact modifying the view rather than the model. Indeed,
- * adding a node to a view is enabling this node in the view. Similarly for
- * removal.
+ * The main benefits of views is the ability to obtain a Subgraph object from it. Users can call the
+ * {@link GraphModel#getGraph(org.gephi.graph.api.GraphView) } method and obtain a subgraph backed by the view. Update
+ * operations such as add or remove on this graph are in-fact modifying the view rather than the model. Indeed, adding a
+ * node to a view is enabling this node in the view. Similarly for removal.
*
*
*
* source .
+ *
+ * @param source the {@link Rect2D} to copy from
+ */
+ public Rect2D(Rect2D source) {
+ this.minX = source.minX;
+ this.minY = source.minY;
+ this.maxX = source.maxX;
+ this.maxY = source.maxY;
+ }
+
+ /**
+ * Create a new {@link Rect2D} with the given minimum and maximum corner coordinates.
+ *
+ * @param minX the x coordinate of the minimum corner
+ * @param minY the y coordinate of the minimum corner
+ * @param maxX the x coordinate of the maximum corner
+ * @param maxY the y coordinate of the maximum corner
+ */
+ public Rect2D(float minX, float minY, float maxX, float maxY) {
+ if (minX > maxX) {
+ throw new IllegalArgumentException("minX > maxX");
+ }
+
+ if (minY > maxY) {
+ throw new IllegalArgumentException("minX > maxX");
+ }
+
+ this.minX = minX;
+ this.minY = minY;
+ this.maxX = maxX;
+ this.maxY = maxY;
+ }
+
+ /**
+ * Return the rectangle's width.
+ *
+ * @return the rectangle's width
+ */
+ public float width() {
+ return maxX - minX;
+ }
+
+ /**
+ * Return the rectangle's height.
+ *
+ * @return the rectangle's height
+ */
+ public float height() {
+ return maxY - minY;
+ }
+
+ /**
+ * Return the rectangle's center, as an array where the first element is the x coordinate and the second element is
+ * the y coordinate.
+ *
+ * @return the rectangle's center
+ */
+ public float[] center() {
+ return new float[] { (maxX + minX) / 2, (maxY + minY) / 2 };
+ }
+
+ /**
+ * Return the rectangle's radius.
+ *
+ * @return the rectangle's radius
+ */
+ public float radius() {
+ float width = width();
+ float height = height();
+ return (float) Math.sqrt(width * width + height * height) / 2;
+ }
+
+ private static final DecimalFormat FORMAT = new DecimalFormat("0.###",
+ DecimalFormatSymbols.getInstance(Locale.ENGLISH));
+
+ @Override
+ public String toString() {
+ return toString(FORMAT);
+ }
+
+ private String toString(NumberFormat formatter) {
+ return "min(x:" + formatter.format(minX) + " y:" + formatter.format(minY) + ") < " + "max(x:" + formatter
+ .format(maxX) + " y:" + formatter.format(maxY) + ")";
+ }
+
+ /**
+ * Returns true if this rectangle contains the given rectangle.
+ *
+ * @param rect the rectangle to check
+ * @return true if this rectangle contains, false otherwise
+ */
+ public boolean contains(Rect2D rect) {
+ if (rect == this) {
+ return true;
+ }
+
+ return contains(rect.minX, rect.minY, rect.maxX, rect.maxY);
+ }
+
+ /**
+ * Returns true if this rectangle intersects the given rectangle.
+ *
+ * @param rect the rectangle to check
+ * @return true if this rectangle intersects, false otherwise
+ */
+ public boolean intersects(Rect2D rect) {
+ if (rect == this) {
+ return true;
+ }
+
+ return intersects(rect.minX, rect.minY, rect.maxX, rect.maxY);
+ }
+
+ /**
+ * Returns true if this rectangle contains the given rectangle.
+ *
+ * @param minX the x coordinate of the minimum corner
+ * @param minY the y coordinate of the minimum corner
+ * @param maxX the x coordinate of the maximum corner
+ * @param maxY the y coordinate of the maximum corner
+ *
+ * @return true if this rectangle contains, false otherwise
+ */
+ public boolean contains(float minX, float minY, float maxX, float maxY) {
+ return this.minX <= minX && this.minY <= minY && this.maxX >= maxX && this.maxY >= maxY;
+ }
+
+ /**
+ * Returns true if this rectangle intersects the given rectangle.
+ *
+ * @param minX the x coordinate of the minimum corner
+ * @param minY the y coordinate of the minimum corner
+ * @param maxX the x coordinate of the maximum corner
+ * @param maxY the y coordinate of the maximum corner
+ *
+ * @return true if this rectangle intersects, false otherwise
+ */
+ public boolean intersects(float minX, float minY, float maxX, float maxY) {
+ return this.minX <= maxX && minX <= this.maxX && this.maxY >= minY && maxY >= this.minY;
+ }
+
+ /**
+ * Returns true if this rectangle contains or intersects with the given rectangle. This is equivalent to checking
+ * {@code this.contains(rect) || this.intersects(rect)} but more efficient as it performs the check in a single
+ * operation.
+ *
+ * @param rect the rectangle to check
+ * @return true if this rectangle contains or intersects with the given rectangle, false otherwise
+ */
+ public boolean containsOrIntersects(Rect2D rect) {
+ if (rect == this) {
+ return true;
+ }
+
+ return containsOrIntersects(rect.minX, rect.minY, rect.maxX, rect.maxY);
+ }
+
+ /**
+ * Returns true if this rectangle contains or intersects with the given rectangle. This is equivalent to checking
+ * {@code this.contains(minX, minY, maxX, maxY) || this.intersects(minX, minY, maxX, maxY)} but more efficient as it
+ * performs the check in a single operation.
+ *
+ * @param minX the x coordinate of the minimum corner
+ * @param minY the y coordinate of the minimum corner
+ * @param maxX the x coordinate of the maximum corner
+ * @param maxY the y coordinate of the maximum corner
+ *
+ * @return true if this rectangle contains or intersects with the given rectangle, false otherwise
+ */
+ public boolean containsOrIntersects(float minX, float minY, float maxX, float maxY) {
+ // Two rectangles have overlap if they intersect - containment is a subset of
+ // intersection
+ return this.minX <= maxX && minX <= this.maxX && this.maxY >= minY && maxY >= this.minY;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ Rect2D rect2D = (Rect2D) obj;
+ return Float.compare(rect2D.minX, minX) == 0 && Float.compare(rect2D.minY, minY) == 0 && Float
+ .compare(rect2D.maxX, maxX) == 0 && Float.compare(rect2D.maxY, maxY) == 0;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = (minX != +0.0f ? Float.floatToIntBits(minX) : 0);
+ result = 31 * result + (minY != +0.0f ? Float.floatToIntBits(minY) : 0);
+ result = 31 * result + (maxX != +0.0f ? Float.floatToIntBits(maxX) : 0);
+ result = 31 * result + (maxY != +0.0f ? Float.floatToIntBits(maxY) : 0);
+ return result;
+ }
+}
diff --git a/src/main/java/org/gephi/graph/api/SpatialIndex.java b/src/main/java/org/gephi/graph/api/SpatialIndex.java
new file mode 100644
index 00000000..95bc3e6b
--- /dev/null
+++ b/src/main/java/org/gephi/graph/api/SpatialIndex.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2012-2013 Gephi Consortium
+ *
+ * Licensed 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.gephi.graph.api;
+
+import java.util.function.Predicate;
+
+/**
+ * Query the (quadtree-based) index based on the given rectangle area.
+ * @{@link Configuration.Builder#enableSpatialIndex(boolean)}.
+ * hasTableChanged() method to check the status. Each call resets
- * the observer so if the method returns true and the table doesn't change after
- * that it will return false next time.
+ * Table observer users should periodically call the hasTableChanged() method to check the status. Each
+ * call resets the observer so if the method returns true and the table doesn't change after that it will return false
+ * next time.
* Table instance.
+ * Observers should be destroyed when not needed anymore. A new observer can be obtained from the Table
+ * instance.
*
* @see Table
*/
diff --git a/store/src/main/java/org/gephi/graph/api/TextProperties.java b/src/main/java/org/gephi/graph/api/TextProperties.java
similarity index 100%
rename from store/src/main/java/org/gephi/graph/api/TextProperties.java
rename to src/main/java/org/gephi/graph/api/TextProperties.java
diff --git a/store/src/main/java/org/gephi/graph/api/TimeFormat.java b/src/main/java/org/gephi/graph/api/TimeFormat.java
similarity index 100%
rename from store/src/main/java/org/gephi/graph/api/TimeFormat.java
rename to src/main/java/org/gephi/graph/api/TimeFormat.java
diff --git a/store/src/main/java/org/gephi/graph/api/TimeIndex.java b/src/main/java/org/gephi/graph/api/TimeIndex.java
similarity index 100%
rename from store/src/main/java/org/gephi/graph/api/TimeIndex.java
rename to src/main/java/org/gephi/graph/api/TimeIndex.java
diff --git a/store/src/main/java/org/gephi/graph/api/TimeRepresentation.java b/src/main/java/org/gephi/graph/api/TimeRepresentation.java
similarity index 69%
rename from store/src/main/java/org/gephi/graph/api/TimeRepresentation.java
rename to src/main/java/org/gephi/graph/api/TimeRepresentation.java
index 280e8a04..af3a5b2e 100644
--- a/store/src/main/java/org/gephi/graph/api/TimeRepresentation.java
+++ b/src/main/java/org/gephi/graph/api/TimeRepresentation.java
@@ -18,15 +18,13 @@
/**
* Different time representations.
* GraphModel
+ is the entry point.
+
+
diff --git a/store/src/main/java/org/gephi/graph/api/types/IntervalBooleanMap.java b/src/main/java/org/gephi/graph/api/types/IntervalBooleanMap.java
similarity index 92%
rename from store/src/main/java/org/gephi/graph/api/types/IntervalBooleanMap.java
rename to src/main/java/org/gephi/graph/api/types/IntervalBooleanMap.java
index 7f962d52..3773b414 100644
--- a/store/src/main/java/org/gephi/graph/api/types/IntervalBooleanMap.java
+++ b/src/main/java/org/gephi/graph/api/types/IntervalBooleanMap.java
@@ -38,8 +38,8 @@ public IntervalBooleanMap() {
/**
* Constructor with capacity.
* keys array must be in the same format returned by
- * {@link #getIntervals() }.
+ * The keys array must be in the same format returned by {@link #getIntervals() }.
*
* @param keys initial keys content
* @param vals initial values content
@@ -63,6 +62,15 @@ public IntervalBooleanMap(double[] keys, boolean[] vals) {
System.arraycopy(vals, 0, values, 0, vals.length);
}
+ /**
+ * Copy constructor.
+ *
+ * @param source the map to copy
+ */
+ public IntervalBooleanMap(IntervalBooleanMap source) {
+ this(source.array, source.values);
+ }
+
/**
* Get the value for the given interval.
*
@@ -98,8 +106,8 @@ public boolean getBoolean(Interval interval, boolean defaultValue) {
/**
* Returns an array of all values in this map.
* keys array must be in the same format returned by
- * {@link #getIntervals() }.
+ * The keys array must be in the same format returned by {@link #getIntervals() }.
*
* @param keys initial keys content
* @param vals initial values content
@@ -63,6 +62,15 @@ public IntervalByteMap(double[] keys, byte[] vals) {
System.arraycopy(vals, 0, values, 0, vals.length);
}
+ /**
+ * Copy constructor.
+ *
+ * @param source the map to copy
+ */
+ public IntervalByteMap(IntervalByteMap source) {
+ this(source.array, source.values);
+ }
+
/**
* Get the value for the given interval.
*
@@ -98,8 +106,8 @@ public byte getByte(Interval interval, byte defaultValue) {
/**
* Returns an array of all values in this map.
* keys array must be in the same format returned by
- * {@link #getIntervals() }.
+ * The keys array must be in the same format returned by {@link #getIntervals() }.
*
* @param keys initial keys content
* @param vals initial values content
@@ -63,6 +62,15 @@ public IntervalCharMap(double[] keys, char[] vals) {
System.arraycopy(vals, 0, values, 0, vals.length);
}
+ /**
+ * Copy constructor.
+ *
+ * @param source the map to copy
+ */
+ public IntervalCharMap(IntervalCharMap source) {
+ this(source.array, source.values);
+ }
+
/**
* Get the value for the given interval.
*
@@ -98,8 +106,8 @@ public char getCharacter(Interval interval, char defaultValue) {
/**
* Returns an array of all values in this map.
* keys array must be in the same format returned by
- * {@link #getIntervals() }.
+ * The keys array must be in the same format returned by {@link #getIntervals() }.
*
* @param keys initial keys content
* @param vals initial values content
@@ -63,6 +62,15 @@ public IntervalDoubleMap(double[] keys, double[] vals) {
System.arraycopy(vals, 0, values, 0, vals.length);
}
+ /**
+ * Copy constructor.
+ *
+ * @param source the map to copy
+ */
+ public IntervalDoubleMap(IntervalDoubleMap source) {
+ this(source.array, source.values);
+ }
+
/**
* Get the value for the given interval.
*
@@ -98,8 +106,8 @@ public double getDouble(Interval interval, double defaultValue) {
/**
* Returns an array of all values in this map.
* keys array must be in the same format returned by
- * {@link #getIntervals() }.
+ * The keys array must be in the same format returned by {@link #getIntervals() }.
*
* @param keys initial keys content
* @param vals initial values content
@@ -64,6 +63,15 @@ public IntervalFloatMap(double[] keys, float[] vals) {
System.arraycopy(vals, 0, values, 0, vals.length);
}
+ /**
+ * Copy constructor.
+ *
+ * @param source the map to copy
+ */
+ public IntervalFloatMap(IntervalFloatMap source) {
+ this(source.array, source.values);
+ }
+
/**
* Get the value for the given interval.
*
@@ -99,8 +107,8 @@ public float getFloat(Interval interval, float defaultValue) {
/**
* Returns an array of all values in this map.
* keys array must be in the same format returned by
- * {@link #getIntervals() }.
+ * The keys array must be in the same format returned by {@link #getIntervals() }.
*
* @param keys initial keys content
* @param vals initial values content
@@ -63,6 +62,15 @@ public IntervalIntegerMap(double[] keys, int[] vals) {
System.arraycopy(vals, 0, values, 0, vals.length);
}
+ /**
+ * Copy constructor.
+ *
+ * @param source the map to copy
+ */
+ public IntervalIntegerMap(IntervalIntegerMap source) {
+ this(source.array, source.values);
+ }
+
/**
* Get the value for the given interval.
*
@@ -98,8 +106,8 @@ public int getInteger(Interval interval, int defaultValue) {
/**
* Returns an array of all values in this map.
* keys array must be in the same format returned by
- * {@link #getIntervals() }.
+ * The keys array must be in the same format returned by {@link #getIntervals() }.
*
* @param keys initial keys content
* @param vals initial values content
@@ -63,6 +62,15 @@ public IntervalLongMap(double[] keys, long[] vals) {
System.arraycopy(vals, 0, values, 0, vals.length);
}
+ /**
+ * Copy constructor.
+ *
+ * @param source the map to copy
+ */
+ public IntervalLongMap(IntervalLongMap source) {
+ this(source.array, source.values);
+ }
+
/**
* Get the value for the given interval.
*
@@ -98,8 +106,8 @@ public long getLong(Interval interval, long defaultValue) {
/**
* Returns an array of all values in this map.
* T parameter.
+ * Implementations which extend this class customize the map for a unique type, which is represented by the
+ * T parameter.
*
* @param timestamp.
+ * Returns true if this map contains an interval that starts or ends at timestamp.
*
* @param timestamp timestamp
* @return true if contains, false otherwise
@@ -337,8 +335,8 @@ protected int getIndex(double intervalStart, double intervalEnd) {
if (startValue == intervalStart && endValue > intervalEnd) {
return -1;
}
- if ((shift = (intervalEnd > endValue ? 2 : intervalEnd < endValue ? -2 : intervalStart > startValue ? 2
- : 0)) == 0) {
+ if ((shift = (intervalEnd > endValue ? 2
+ : intervalEnd < endValue ? -2 : intervalStart > startValue ? 2 : 0)) == 0) {
return foundIndex;
}
}
@@ -418,11 +416,11 @@ public Interval[] toKeysArray() {
/**
* Returns an array of all intervals in this set.
* timestamp.
+ * Returns true if this set contains an interval that starts or ends at timestamp.
*
* @param timestamp timestamp
* @return true if contains, false otherwise
@@ -114,8 +154,8 @@ public boolean contains(Interval interval) {
if (startValue == interval.getLow() && endValue > interval.getHigh()) {
return false;
}
- if ((shift = (interval.getHigh() > endValue ? 2 : interval.getHigh() < endValue ? -2 : interval
- .getLow() > startValue ? 2 : 0)) == 0) {
+ if ((shift = (interval.getHigh() > endValue ? 2
+ : interval.getHigh() < endValue ? -2 : interval.getLow() > startValue ? 2 : 0)) == 0) {
return true;
}
}
@@ -126,11 +166,11 @@ public boolean contains(Interval interval) {
/**
* Returns an array of all intervals in this set in a flat format.
* keys array must be in the same format returned by
- * {@link #getIntervals() }.
+ * The keys array must be in the same format returned by {@link #getIntervals() }.
*
* @param keys initial keys content
* @param vals initial values content
@@ -63,6 +62,15 @@ public IntervalShortMap(double[] keys, short[] vals) {
System.arraycopy(vals, 0, values, 0, vals.length);
}
+ /**
+ * Copy constructor.
+ *
+ * @param source the map to copy
+ */
+ public IntervalShortMap(IntervalShortMap source) {
+ this(source.array, source.values);
+ }
+
/**
* Get the value for the given interval.
*
@@ -98,8 +106,8 @@ public short getShort(Interval interval, short defaultValue) {
/**
* Returns an array of all values in this map.
* keys array must be in the same format returned by
- * {@link #getIntervals() }.
+ * The keys array must be in the same format returned by {@link #getIntervals() }.
*
* @param keys initial keys content
* @param vals initial values content
@@ -62,6 +61,15 @@ public IntervalStringMap(double[] keys, String[] vals) {
System.arraycopy(vals, 0, values, 0, vals.length);
}
+ /**
+ * Copy constructor.
+ *
+ * @param source the map to copy
+ */
+ public IntervalStringMap(IntervalStringMap source) {
+ this(source.array, source.values);
+ }
+
@Override
public ClasssetAttribute and removeAttribute
+ * methods afterwards.
*
* @param addTimestamp/addInterval and
+ * removeTimestamp/removeInterval methods afterwards.
*
* @param T parameter.
+ * Implementations which extend this class customize the map for a unique type, which is represented by the
+ * T parameter.
*
* @param