diff --git a/.github/workflows/check-dependencies.yml b/.github/workflows/check-dependencies.yml index 73ef769c67..db2ec66aa0 100644 --- a/.github/workflows/check-dependencies.yml +++ b/.github/workflows/check-dependencies.yml @@ -14,6 +14,7 @@ jobs: env: USE_STAGE: 'false' # Whether to include the stage repository. SCRIPT_DEPENDENCY: install-dist/scripts/dependency + PYTHONDONTWRITEBYTECODE: '1' # Keep generated Python caches out of source style checks. steps: - name: Checkout source uses: actions/checkout@v7 @@ -29,15 +30,27 @@ jobs: cp $HOME/.m2/settings.xml /tmp/settings.xml mv -vf .github/configs/settings.xml $HOME/.m2/settings.xml + - name: Test shared foundation checks + run: python3 -m unittest discover -s install-dist/scripts/shared-foundation -p 'test_*.py' + + - name: Test dependency inventory producer and checker + run: python3 -m unittest discover -s install-dist/scripts/dependency -p 'test_*.py' + - name: mvn install run: | mvn install -Dmaven.test.skip=true -ntp --fail-at-end + - name: Check shared foundation boundaries and shipped classes + run: | + REVISION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) + python3 install-dist/scripts/shared-foundation/check_shared_foundation.py --revision "$REVISION" + - name: generate current dependencies run: | - bash $SCRIPT_DEPENDENCY/regenerate_known_dependencies.sh current-dependencies.txt + bash $SCRIPT_DEPENDENCY/regenerate_known_dependencies.sh "$PWD/target/dependency/current-dependencies.txt" - name: check third dependencies run: | - bash $SCRIPT_DEPENDENCY/check_dependencies.sh + bash $SCRIPT_DEPENDENCY/check_dependencies.sh \ + "$SCRIPT_DEPENDENCY/known-dependencies.txt" "$PWD/target/dependency/current-dependencies.txt" dependency-review: runs-on: ubuntu-latest diff --git a/.github/workflows/pd-store-ci.yml b/.github/workflows/pd-store-ci.yml index 1a001a03bb..ccca9d878b 100644 --- a/.github/workflows/pd-store-ci.yml +++ b/.github/workflows/pd-store-ci.yml @@ -388,6 +388,13 @@ jobs: $TRAVIS_DIR/start-pd.sh $TRAVIS_DIR/start-store.sh + - name: Run historical Store ingress tests + run: | + mvn test -pl hugegraph-store/hg-store-node -am \ + -Dtest=StoredRowIngressTest -Dsurefire.failIfNoSpecifiedTests=false \ + -Djacoco.sessionId=store-node-test \ + -Djacoco.destFile="$PWD/hugegraph-store/hg-store-test/target/store-node-test.exec" + - name: Run common test run: | mvn test -pl hugegraph-store/hg-store-test -am \ @@ -431,6 +438,8 @@ jobs: "$TEST_REPORT_DIR/TEST-org.apache.hugegraph.store.raftcore.RaftSuiteTest.xml" \ --require-test-report \ "$TEST_REPORT_DIR/TEST-org.apache.hugegraph.store.core.CoreSuiteTest.xml" \ + --require-test-report \ + "hugegraph-store/hg-store-node/target/surefire-reports/TEST-org.apache.hugegraph.store.business.StoredRowIngressTest.xml" \ --require-covered-group hg-store-common \ --require-covered-group hg-store-client \ --require-covered-group hg-store-rocksdb \ @@ -440,6 +449,7 @@ jobs: --require-session store-rocksdb-test \ --require-session store-raftcore-test \ --require-session store-core-test \ + --require-session store-node-test \ "$REPORT_FILE" \ hg-store-grpc hg-store-common hg-store-client hg-store-rocksdb hg-store-core diff --git a/README.md b/README.md index 18a20d56e9..98413218c8 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,9 @@ See the [backend evolution guide](hugegraph-server/README.md#backend-evolution-a | [hugegraph-pd](hugegraph-pd/README.md) | Placement Driver for distributed mode - handles meta storage, partition management and cluster scheduling | | [hugegraph-store](hugegraph-store/README.md) | Distributed storage with Raft consensus for high availability and horizontal scaling | | [hugegraph-commons](hugegraph-commons) | Shared utilities, RPC framework and common components | +| [hugegraph-struct](hugegraph-struct/README.md) | Shared schema, IDs, base elements, queries and encoding used by Server and Store | + +See the [1.8.0 shared-foundation migration guide](docs/shared-foundation-migration.md) for Java API changes, module ownership and coordinated upgrade requirements.
📊 Click to view detailed architecture diagram (Mermaid) diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index af3fa2cd2d..32a1d0f87e 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -29,6 +29,11 @@ mvn editorconfig:format mvn clean compile -Dmaven.javadoc.skip=true ``` +The root POM and child modules flatten CI-friendly versions during `process-resources`, +so installed and deployed POMs use a concrete version instead of `${revision}`. Build the +reactor with `install` before building modules separately; keep Maven Resolver validation +enabled, including on Maven 3.10+. + Run the affected module tests and add regression coverage when behavior changes. A successful build with skipped tests does not validate behavior; Commons tests require `-DskipCommonsTests=false`. For documentation-only changes, verify links and paths and run @@ -50,6 +55,21 @@ and automatic cancellation and retries. Report what you actually validated and a Update the [dependency inventory](../install-dist/scripts/dependency/known-dependencies.txt) using [the regeneration script](../install-dist/scripts/dependency/regenerate_known_dependencies.sh). +Install/package the current reactor before regenerating the inventory: + +```bash +mvn install -DskipTests -Dmaven.javadoc.skip=true +bash install-dist/scripts/dependency/regenerate_known_dependencies.sh +``` + +The build must produce Server, PD and Store distributions for the same current revision. +It skips tests and is not validation evidence. The inventory combines Maven runtime +dependencies with flat and nested distribution jars, including Spring Boot `BOOT-INF/lib` +dependencies inserted by repackaging. Missing distributions fail collection; source or POM +inspection alone cannot establish the full shipped inventory. Review all additions and +removals and their license/NOTICE coverage. The dependency check compares the exact inventory; +repeat it for release platform/profile variants as needed. + ## Submit and review Use `type(scope): description` for commits; omit the scope when it is unclear. diff --git a/docs/shared-foundation-migration.md b/docs/shared-foundation-migration.md new file mode 100644 index 0000000000..037aa0d508 --- /dev/null +++ b/docs/shared-foundation-migration.md @@ -0,0 +1,219 @@ +# Shared foundations: preparing for the 1.8.0 migration + +The planned 1.8.0 consolidation changes Java imports and extension contracts, and requires a coordinated Server, PD and Store upgrade. Use this guide to identify affected code, check historical-data compatibility and prepare your deployment. + +Shared implementations move out of Server core so Server and Store can use the same types and codecs. This guide covers the planned 1.8.0 migration. + +## What do I need to change? + +| If you maintain… | Your next step | +|------------------|----------------| +| A REST client, Loader integration or client DTO | Check actual affected Java calls; REST use alone does not require replacing client DTOs with struct types. | +| Java code importing Server IDs, schema, queries or indexes | Update the imports and affected signatures below, then recompile against matching 1.8.0 artifacts. | +| A `HugeGraph` implementation, serializer or element subclass | Adapt the API/SPI contracts below; old compiled implementations are not binary-compatible. | +| Custom Gremlin scripts or `classImports` | Change the `IdGenerator` class name and verify it in the packaged Gremlin service. | +| Hubble, Toolchain or Computer | Apply the downstream exception/classpath changes and validate the built jars. Use matching downstream artifacts and check their packaged classpaths. | +| An HStore installation | Check OLAP writes, Store-rebuilt indexes and metadata namespaces before a coordinated upgrade. | +| PD or Store code | Use the shared owners without importing Server core; keep service-specific execution and resource lifecycle local. | + +## Why share these implementations? + +Before this change, Server core and struct carry separate implementations of several IDs, schema types, queries, elements and codecs. A fix to one copy can leave the other with different behavior. Consolidating them gives those fixes one owner and gives Server and Store a common implementation to test. + +```text +Before: Core and Struct each maintain shared types and codecs. + +After: +Server core --> Struct --> Common +Store core --> Struct +PD service -------------> Common +``` + +*Shared-foundation ownership, rather than the complete Maven dependency tree.* Server still needs PD/Store clients for HStore; Store still needs its network, PD client and storage libraries. Struct retains its shared index/analyzer and codec dependencies, including shaded Kryo where required. + +| Capability | Owner after migration | What remains with the caller | +|------------|-----------------------|------------------------------| +| IDs, schema metadata and type codes | struct | Import and use the shared types | +| Queries, base elements, byte/property codecs | struct | Adapt graph-engine and backend behavior | +| Index construction, analyzers and OLAP selection | struct | Supply schema candidates and result sinks; preserve configured analysis and index results | +| Transactions, traversal, tasks and schema mutation | Server core | Operate on shared metadata and elements | +| PD-backed schema access | Store | Manage `SchemaGraph`/`SchemaDriver`, listeners and cache lifecycle | +| JWT signing/verification and auth constants | common | Supply configuration and translate failures into service responses | +| RPC client/server configuration interfaces | common | Keep existing implementations and configuration values | + +`HugeGraphSupplier` lets shared code access schema, configuration and the clock without depending on the graph engine. Core and Store implement it. + +Core elements wrap shared base elements: property mutation, cloning, removal, expiration and loading state use that same state. `BaseVertex` owns adjacency; the engine caches edge wrappers by identity over the same base edges. Core serializers retain their engine/backend adapters and delegate shared encoding. Core also retains transaction writes, backend capability checks and index-update orchestration around shared index construction and OLAP selection. + +## Migrate Java code and extensions + +### Start with the imports + +For example, code that creates an ID changes its imports while keeping the factory call: + +**Before** + +```java +import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.backend.id.IdGenerator; + +Id id = IdGenerator.of("alice"); +``` + +**After** + +```java +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; + +Id id = IdGenerator.of("alice"); +``` + +| Previous entry | Shared entry or migration | +|----------------|---------------------------| +| `org.apache.hugegraph.backend.id.*` | `org.apache.hugegraph.id.*` | +| `org.apache.hugegraph.schema.*` metadata | `org.apache.hugegraph.struct.schema.*` | +| `org.apache.hugegraph.backend.query.*` | `org.apache.hugegraph.query.*` | +| `org.apache.hugegraph.backend.store.Shard` | `org.apache.hugegraph.backend.Shard` | +| `org.apache.hugegraph.backend.store.BackendEntry.BackendColumn` | `org.apache.hugegraph.backend.BackendColumn` | +| `org.apache.hugegraph.structure.HugeIndex` | `org.apache.hugegraph.structure.Index` | +| Shared bytes/encoding in backend serializers | `org.apache.hugegraph.serializer.*` | +| Core `HugeException` | `org.apache.hugegraph.exception.HugeException` | +| `org.apache.hugegraph.SchemaGraph` / `SchemaDriver` | `org.apache.hugegraph.store.schema.*` | + +The table applies to these shared types, not every class in a package. Schema mutation builders and backend-specific serializers remain in core. There is no general compatibility package for removed core classes. Relocated types also change method descriptors that expose IDs, schema, queries and indexes, so update implementations and call sites and recompile every affected integration against matching artifacts. Changing source imports does not make old binaries compatible. + +### Check API and SPI implementations + +| Integration point | Required change or preserved contract | +|-------------------|---------------------------------------| +| `HugeGraph.sameAs` | Change `sameAs(HugeGraph)` to `sameAs(HugeGraphSupplier)`. External overrides must accept the supplier, as `StandardHugeGraph` and `HugeGraphAuthProxy` now do. There is no old-signature overload. | +| Custom `HugeElement` subclasses | Provide shared `BaseElement` state through `element()` and adapt `BaseProperty` through `wrapProperty`. Removed protected engine state fields and a second adjacency store must not be restored. | +| `GraphSerializer.writeIndex` / `readIndex` | Accept/return `org.apache.hugegraph.structure.Index`; update SPI implementations and callers. No long-lived `HugeIndex` wrapper is retained. Hash-ID generation belongs to shared `Index`. | +| `RpcServiceConfig4Client` / `RpcServiceConfig4Server` | Both now belong to common, with the same `org.apache.hugegraph.rpc` names and signatures. Existing RPC implementations and values need no source migration. Duplicate core/commons-rpc definitions are removed without adding a dependency edge. | +| `TokenGenerator` | Use common's `org.apache.hugegraph.auth.TokenGenerator`; supply the signing secret and translate JWT failures locally. Common's JWT dependencies are optional, so direct JWT consumers must declare their required JWT libraries. | +| Engine vertices and edges | `HugeVertex` and `HugeEdge` remain engine adapters; Store uses base elements. | + +### Update downstream exceptions without changing their meaning + +Distinct downstream exception contracts need distinct class names on the shared classpath. Use these replacements with the matching Toolchain artifacts: + +| Previous downstream entry | Replacement and contract | +|---------------------------|--------------------------| +| Hubble `org.apache.hugegraph.exception.HugeException` | `org.apache.hugegraph.exception.HubbleException`: still a `RuntimeException` with its string constructor | +| Client `org.apache.hugegraph.exception.NotSupportException` | `org.apache.hugegraph.exception.ClientNotSupportException`: still a `ClientException`, with existing message/cause and message/arguments constructors | +| Hubble's copy of `org.apache.hugegraph.license.MachineInfo` | Keep the same import; use the implementation supplied by `hugegraph-common` | + +Update imports, constructor calls and handlers for these exceptions. Struct's `HugeException` and `NotSupportException` have different contracts and are not substitutes for those catches. Computer's `HgkvDirImpl` must also use `ClientNotSupportException`. + +Rebuild the affected Toolchain and Computer integrations and check their packaged classpaths before deployment. A source scan for duplicate names cannot rule out stale or transitive classes in built jars. Loader's REST boundary and independent client DTOs do not need wholesale conversion to struct. + +### Check configuration-only class names + +Replace `org.apache.hugegraph.backend.id.IdGenerator` with `org.apache.hugegraph.id.IdGenerator` in Gremlin `classImports` and scripts. The bundled default and Raft examples use the shared class. These strings are not checked by Java compilation, so test them in the packaged Gremlin service. + +## Understand data and runtime compatibility + +The migration preserves existing type codes, ID/property bytes, ordinary Server index keys, TTL formats, query semantics and configuration defaults. It introduces no general data-rewrite operation. The following cases need separate attention: + +| Area | Behavior after migration | Action or limit | +|------|--------------------------|-----------------| +| String ID comparison | Uses Java UTF-16 string order even before an ID loaded from UTF-8 bytes is decoded | Persisted bytes stay the same; supplementary Unicode characters no longer compare differently after lazy decoding. | +| Property values | Preserves schema-driven persisted rows and tagged Store shuffle/aggregation values | Readers choose the mode from the known producer/request plan, not by guessing from bytes. | +| SYSTEM-label index expiry | Preserves Store's stable key and 13-byte value envelope for positive expiry, and core's existing SYSTEM-label bytes | The bounded legacy envelope is read at the serializer boundary; no key TTL suffix or prefix-deletion change. | +| Store-rebuilt long-text indexes | Uses the complete value and hash expected by Server queries | Assess old Store rebuilds; shortened historical rows may require rebuilding from graph data. | +| HStore OLAP physical keys | New writes use `[property ID][vertex ID]` and readers retain a matching legacy-row fallback | Upgrade writers together. Previously overwritten properties cannot be recovered. | +| Schema map decoding | Retains ordered primary/sort keys and resolves endpoint metadata independent of map field order | Matching or legacy endpoint forms work; conflicting or malformed metadata is rejected. | +| Metadata namespace | Store uses `pd.cluster` (default `hg`) across schema, configuration, watches and TTL-cleaner metadata | Match the Server/graph namespace and preserve backend graph names. | +| Historical serialized Java names | Query/Kryo readers retain required legacy names and aliases | Type relocation does not authorize a new wire format. | + +### Store-rebuilt indexes + +The old Store `IndexBuilder` shortened long text to 20 characters, while Server queries used the complete value and its hash. The shared builder adopts the Server contract. Frozen producer/query fixtures describe that existing mismatch in the [compatibility README](../hugegraph-struct/src/test/resources/compatibility/2f827d6e8/README.md#existing-indexbuilderquery-mismatch). + +Old shortened rows remain decodable, but do not automatically match a query using the full value. Check whether your installation used Store-side index rebuilding and rebuild affected indexes from graph data where necessary. The migration neither rebuilds them automatically nor recovers missing historical entries. Ordinary Server-created index keys keep their existing contract. + +### HStore OLAP writes + +A vertex-only physical key allowed one OLAP property to overwrite another on the same vertex. The new `[property ID][vertex ID]` key lets those properties coexist. This is a behavior repair beyond package relocation; existing row values remain readable without rewriting them. + +Readers try the requested property's compound key first, then the legacy vertex-only key if its value contains the matching property ID. Deleting one property removes its compound row and a matching legacy row while preserving other properties. Values already overwritten by the old writer are lost. + +Mixed-version writes can produce stale reads: an old writer may update a legacy row while a new reader prefers an earlier compound row. Upgrade all Server and Store writers before resuming writes. + +### Match metadata namespaces + +In Store `application.yml`, the existing namespace setting is: + +```yaml +pd: + cluster: hg +``` + +The environment equivalent is `PD_CLUSTER`. Match Server's `cluster` when `usePD=true`, or the graph's `pd.cluster` when `usePD=false`. One Store process cannot reuse its schema driver across conflicting namespaces. + +Keep backend graph-name components such as `DEFAULT/hugegraph/g` (`graphspace/store/table`). The REST identity `DEFAULT-hugegraph` is not a metadata key. + +## Plan a coordinated upgrade + +```text +Prepare --> Adapt Java code --> Upgrade matching services --> Verify + +HStore OLAP keys: +Before: vertex ID +After: [property ID][vertex ID] +``` + +*Use matching Server, PD and Store artifacts; mixed-version rolling upgrades are outside this migration's supported upgrade contract.* + +1. **Prepare integrations.** Update Java APIs/SPIs and Gremlin class names, recompile affected callers and check downstream delivery. Assess Store-rebuilt long-text indexes and OLAP usage. +2. **Back up data and configuration.** Use the existing deployment procedure. Record metadata namespaces and backend graph names so they remain consistent. +3. **Stop writes and upgrade together.** Install the matching Server, PD and Store release artifacts. Upgrade all OLAP writers before allowing writes again. +4. **Verify the built deployment.** Start the packaged services, check Gremlin imports, authentication, schema access and relevant RocksDB/HStore paths. Validate historical data and the built classpath; compilation alone is not sufficient. +5. **Rebuild affected indexes and resume writes.** Where old Store rebuilds produced shortened text keys, rebuild from graph data as needed and verify full-value queries. Check OLAP properties and metadata routing before resuming. + +Validate the packaged deployment and affected integrations before resuming writes, using the compatibility checks below. + +## Compatibility reference for implementers + +### Codecs and schema + +Persisted property rows and transient tagged results share the scalar codec. Both must retain their historical samples. Ordinary schema index writers keep the Server key/name-TTL layout. `Index.hasTtl()` follows the engine's existing system-index contract; Store's expiry envelope stays at the serializer boundary. Unsupported index-only element reconstruction remains unsupported. + +Shared `Shard` preserves its GraphSON tag and fields, and query decoding retains its legacy fully qualified name. Toolchain's `org.apache.hugegraph.structure.graph.Shard` stays a separate REST DTO. `BackendColumn` retains mutable `name`/`value` byte arrays. Its hash now uses array contents consistently with equality instead of core's array-identity hash. Historical Kryo names require decoder aliases and fixture checks; the fields retain their bytes. Store's `RocksDBSession.BackendColumn` stays a backend adapter. + +Schema maps preserve wire field names and ID identity. Two decoder fixes accompany relocation: primary-key and edge sort-key lists retain order and duplicates rather than passing through a set, and redundant edge endpoints are resolved consistently regardless of map field order. Matching `links` and source/target fields are accepted; legacy source/target-only maps remain readable; conflicting or malformed endpoints are rejected. Ordered-schema and endpoint-map tests cover generated vertex/edge IDs and query values, but do not establish all distributed or packaged release gates. + +Query JSON still uses Java names for some relation values. Decoder mappings must read historical names, and historical values still require Kryo decoding where applicable. Replacing these Java names with value tags would require a separate wire-format compatibility policy. + +### System-vertex classification + +`BaseVertex.TypeContext` makes the existing engine/storage distinction explicit: + +| Context | `~variables` | `~server` / `~role_data` | `~task` / `~taskresult` | +|---------|--------------|------------------------|------------------------| +| `STORAGE` (standalone storage elements) | Task data | Ordinary vertex data | Task data | +| `ENGINE` (engine wrappers) | Ordinary vertex data | Server data | Task data | + +Engine wrappers must select `ENGINE`; standalone storage elements retain `STORAGE`. Selecting the correct context preserves existing table routing and readers for system vertices. + +### Review and release checks + +Review behavior alongside the package moves. The key entrypoints and invariants are: + +| Area | Main entrypoints | What to verify | +|------|------------------|----------------| +| Java API/SPI | `HugeGraphSupplier`, `HugeGraph.sameAs`, `GraphSerializer`, custom `HugeElement` | Caller recompilation and the documented migration | +| Element state | `BaseElement/BaseVertex/BaseEdge`, `HugeElement/HugeVertex/HugeEdge`, offheap properties | One state owner, callback order, clone/adjacency identity and virtual value reads | +| Historical codecs | `BytesBuffer`, `BinaryElementSerializer`, `BinarySerializer`, `LegacyClassNames`, `KryoUtil` | Producer-specific bytes and old enum ordinals, with canonical writers preserved | +| Queries, schema and indexes | `ConditionQuery`, `EdgeLabel.fromMap`, `IndexBuilder`, `Index` | Query behavior, ordered keys, endpoints, full-value hashes and TTL contracts | +| HStore and metadata | `HstoreTables`, `OlapStage`, `SchemaDriver`, `FilterIterator` | OLAP repair, exact owner reads, batch bounds, namespaces and watch closure | +| Delivery | Shared-foundation/inventory guards, packaged jars, Gremlin imports, downstream callers | Resolved/shipped dependencies, startup and paired documentation | + +Release evidence must include shared tests and frozen pre-migration byte/JSON fixtures for IDs, schema, properties, indexes, pagination, TTL/OLAP and supported Kryo data. It must also cover RocksDB/HStore execution, Store filtering and schema access, authentication, element state propagation and affected downstream tests. + +Check resolved dependencies and built distributions: PD/Store must not depend on Server core, struct must not depend on PD client/core, and packaged jars must not contain duplicate HugeGraph classes. Start the packaged services without a classpath-ordering workaround. Independent review and CI guards must prevent new duplicate owners or forbidden dependencies. + +Build/test commands and service prerequisites are in [BUILDING](BUILDING.md), module guidance and CI. Ensure tests actually run; `-DskipTests` is not compatibility evidence. + +Deploy matching Server, PD, Store and downstream artifacts. Validate both the Java integrations and the packaged services before adopting the migration. diff --git a/hugegraph-cluster-test/hugegraph-clustertest-dist/src/assembly/static/conf/rest-server.properties.template b/hugegraph-cluster-test/hugegraph-clustertest-dist/src/assembly/static/conf/rest-server.properties.template index a16f69fe36..f838fd2a8a 100644 --- a/hugegraph-cluster-test/hugegraph-clustertest-dist/src/assembly/static/conf/rest-server.properties.template +++ b/hugegraph-cluster-test/hugegraph-clustertest-dist/src/assembly/static/conf/rest-server.properties.template @@ -39,6 +39,7 @@ arthas.disabled_commands=jad auth.authenticator=org.apache.hugegraph.auth.StandardAuthenticator # true if using hstore mode usePD=true +cluster=hg pd.peers=$PD_PEERS_LIST$ # default password diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/GremlinServerConfig.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/GremlinServerConfig.java index eeba926cab..64950f83e3 100644 --- a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/GremlinServerConfig.java +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/GremlinServerConfig.java @@ -36,29 +36,29 @@ private GremlinServerConfig() { } public static void update(Path configPath, String host, int port) { - if (port < 0 || port > 65535) { + if (port <= 0 || port > 65535) { throw new IllegalArgumentException("Invalid Gremlin port: " + port); } try { List lines = Files.readAllLines(configPath, StandardCharsets.UTF_8); - boolean hostUpdated = false; - boolean portUpdated = false; + int hostSettings = 0; + int portSettings = 0; for (int i = 0; i < lines.size(); i++) { String line = lines.get(i); if (HOST_SETTING.matcher(line).matches()) { lines.set(i, "host: " + host); - hostUpdated = true; + hostSettings++; } else if (PORT_SETTING.matcher(line).matches()) { lines.set(i, "port: " + port); - portUpdated = true; + portSettings++; } } - if (!hostUpdated || !portUpdated) { + if (hostSettings != 1 || portSettings != 1) { throw new IllegalStateException( - "Missing host or port setting in " + configPath); + "Expected one top-level host and port in " + configPath); } Files.write(configPath, lines, StandardCharsets.UTF_8); } catch (IOException e) { diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/node/ServerNodeWrapper.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/node/ServerNodeWrapper.java index 332615b8e2..bc093cb801 100644 --- a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/node/ServerNodeWrapper.java +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/node/ServerNodeWrapper.java @@ -82,7 +82,7 @@ public ServerNodeWrapper(int clusterIndex, int index, int restPort, LOCALHOST, this.gremlinPort); } this.fileNames = new ArrayList<>(List.of(EMPTY_SAMPLE_GROOVY_FILE, EXAMPLE_GROOVY_FILE)); - this.startLine = "INFO: [HttpServer] Started."; + this.startLine = "Channel started at port "; createNodeDir(Paths.get(SERVER_PACKAGE_PATH), getNodePath()); createLogDir(); } diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/test/java/org/apache/hugegraph/ct/config/GremlinServerConfigTest.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/test/java/org/apache/hugegraph/ct/config/GremlinServerConfigTest.java index ae051b4d0a..ef3ffd6538 100644 --- a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/test/java/org/apache/hugegraph/ct/config/GremlinServerConfigTest.java +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/test/java/org/apache/hugegraph/ct/config/GremlinServerConfigTest.java @@ -49,4 +49,37 @@ public void testUpdateCommentedHostAndPort() throws Exception { Assert.assertTrue(updated.toString(), updated.contains("port: 12345")); Assert.assertFalse(updated.toString(), updated.contains("port: 8182")); } + + @Test + public void testRejectInvalidPortsWithoutChangingConfig() throws Exception { + File config = temporaryFolder.newFile("invalid-port.yaml"); + String content = "host: 127.0.0.1\nport: 8182\n"; + Files.writeString(config.toPath(), content, StandardCharsets.UTF_8); + + for (int port : new int[]{-1, 0, 65536}) { + Assert.assertThrows(IllegalArgumentException.class, () -> { + GremlinServerConfig.update(config.toPath(), "127.0.0.1", port); + }); + Assert.assertEquals(content, Files.readString(config.toPath(), + StandardCharsets.UTF_8)); + } + } + + @Test + public void testRequireOneTopLevelHostAndPort() throws Exception { + File config = temporaryFolder.newFile("ambiguous-endpoint.yaml"); + for (String content : new String[]{ + "host: 127.0.0.1\n", + "port: 8182\n", + "host: 127.0.0.1\n#host: 0.0.0.0\nport: 8182\n", + "host: 127.0.0.1\nport: 8182\n#port: 8183\n"}) { + Files.writeString(config.toPath(), content, StandardCharsets.UTF_8); + Assert.assertThrows(IllegalStateException.class, () -> { + GremlinServerConfig.update(config.toPath(), "127.0.0.1", 12345); + }); + Assert.assertEquals(content, Files.readString(config.toPath(), + StandardCharsets.UTF_8)); + } + } + } diff --git a/hugegraph-cluster-test/pom.xml b/hugegraph-cluster-test/pom.xml index fc176e21f8..cf51dfd1f3 100644 --- a/hugegraph-cluster-test/pom.xml +++ b/hugegraph-cluster-test/pom.xml @@ -45,6 +45,13 @@ + + + org.apache.hugegraph + hugegraph-common + ${revision} + diff --git a/hugegraph-commons/hugegraph-common/pom.xml b/hugegraph-commons/hugegraph-common/pom.xml index 318d9c22fa..25c10e139a 100644 --- a/hugegraph-commons/hugegraph-common/pom.xml +++ b/hugegraph-commons/hugegraph-common/pom.xml @@ -39,6 +39,7 @@ 4.10.0 + 0.11.5 @@ -72,6 +73,28 @@ ${log4j2.version} + + + io.jsonwebtoken + jjwt-api + ${jjwt.version} + true + + + io.jsonwebtoken + jjwt-impl + ${jjwt.version} + runtime + true + + + io.jsonwebtoken + jjwt-jackson + ${jjwt.version} + runtime + true + + org.glassfish diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/AuthConstant.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/auth/AuthConstant.java similarity index 88% rename from hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/AuthConstant.java rename to hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/auth/AuthConstant.java index 3c7c539363..089fb8aa59 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/AuthConstant.java +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/auth/AuthConstant.java @@ -24,4 +24,6 @@ public interface AuthConstant { */ String TOKEN_USER_NAME = "user_name"; String TOKEN_USER_ID = "user_id"; + // Retained for callers using the former struct constants; not emitted by login. + String TOKEN_USER_PASSWORD = "user_password"; } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/TokenGenerator.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/auth/TokenGenerator.java similarity index 64% rename from hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/TokenGenerator.java rename to hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/auth/TokenGenerator.java index 7c75c095b9..83fecb47e7 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/TokenGenerator.java +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/auth/TokenGenerator.java @@ -23,27 +23,16 @@ import javax.crypto.SecretKey; -import org.apache.hugegraph.config.AuthOptions; -import org.apache.hugegraph.config.HugeConfig; - import io.jsonwebtoken.Claims; -import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.Jws; -import io.jsonwebtoken.JwtException; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.security.Keys; -import jakarta.ws.rs.NotAuthorizedException; public class TokenGenerator { private final SecretKey key; - public TokenGenerator(HugeConfig config) { - String secretKey = config.get(AuthOptions.AUTH_TOKEN_SECRET); - this.key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8)); - } - public TokenGenerator(String secretKey) { this.key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8)); } @@ -56,17 +45,15 @@ public String create(Map payload, long expire) { .compact(); } + /** + * Verify a signed token. Callers translate JJWT failures into their own + * authentication or transport errors. + */ public Claims verify(String token) { - try { - Jws claimsJws = Jwts.parserBuilder() - .setSigningKey(key) - .build() - .parseClaimsJws(token); - return claimsJws.getBody(); - } catch (ExpiredJwtException e) { - throw new NotAuthorizedException("The token is expired", e); - } catch (JwtException e) { - throw new NotAuthorizedException("Invalid token", e); - } + Jws claimsJws = Jwts.parserBuilder() + .setSigningKey(this.key) + .build() + .parseClaimsJws(token); + return claimsJws.getBody(); } } diff --git a/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcServiceConfig4Client.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rpc/RpcServiceConfig4Client.java similarity index 100% rename from hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcServiceConfig4Client.java rename to hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rpc/RpcServiceConfig4Client.java diff --git a/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcServiceConfig4Server.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rpc/RpcServiceConfig4Server.java similarity index 100% rename from hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcServiceConfig4Server.java rename to hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rpc/RpcServiceConfig4Server.java diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/UnitTestSuite.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/UnitTestSuite.java index 4f5fd0728f..7705215e2d 100644 --- a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/UnitTestSuite.java +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/UnitTestSuite.java @@ -19,6 +19,7 @@ import org.apache.hugegraph.testutil.AssertTest; import org.apache.hugegraph.testutil.WhiteboxTest; +import org.apache.hugegraph.unit.auth.TokenGeneratorTest; import org.apache.hugegraph.unit.config.HugeConfigTest; import org.apache.hugegraph.unit.config.OptionSpaceTest; import org.apache.hugegraph.unit.event.EventHubTest; @@ -78,6 +79,7 @@ RowLockTest.class, PausableScheduledThreadPoolTest.class, + TokenGeneratorTest.class, HugeConfigTest.class, OptionSpaceTest.class, SafeDateFormatTest.class, diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/auth/TokenGeneratorTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/auth/TokenGeneratorTest.java new file mode 100644 index 0000000000..a047e00e68 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/auth/TokenGeneratorTest.java @@ -0,0 +1,100 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.unit.auth; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.apache.hugegraph.auth.AuthConstant; +import org.apache.hugegraph.auth.TokenGenerator; +import org.apache.hugegraph.testutil.Assert; +import org.junit.Test; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.JwtException; +import io.jsonwebtoken.security.WeakKeyException; + +public class TokenGeneratorTest { + + private static final String SECRET = "01234567890123456789012345678901"; + + @Test + public void testCreateAndVerifyClaims() { + TokenGenerator generator = new TokenGenerator(SECRET); + Map payload = new HashMap<>(); + payload.put(AuthConstant.TOKEN_USER_NAME, "alice"); + payload.put(AuthConstant.TOKEN_USER_ID, "1234"); + long before = System.currentTimeMillis(); + Claims claims = generator.verify(generator.create(payload, 60000L)); + long after = System.currentTimeMillis(); + + Assert.assertEquals("alice", claims.get(AuthConstant.TOKEN_USER_NAME)); + Assert.assertEquals("1234", claims.get(AuthConstant.TOKEN_USER_ID)); + Assert.assertFalse(claims.containsKey(AuthConstant.TOKEN_USER_PASSWORD)); + // JWT timestamps have second precision. + Assert.assertTrue(claims.getExpiration().getTime() >= before + 59000L); + Assert.assertTrue(claims.getExpiration().getTime() <= after + 60000L); + } + + @Test + public void testReadLegacyHs256Token() { + // Fixed claims and independent HMAC-SHA256 signature, not this class's writer. + String token = "eyJhbGciOiJIUzI1NiJ9." + + "eyJ1c2VyX25hbWUiOiJsZWdhY3ktdXNlciIsInVzZXJfaWQiOiIxMjM0IiwiZXhwIjo0MTAyNDQ0ODAwfQ." + + "t2b5xSruyIrZ8c45HOe6OhJt390rm_fdbvft1JLyRTs"; + Claims claims = new TokenGenerator(SECRET).verify(token); + Assert.assertEquals("legacy-user", claims.get(AuthConstant.TOKEN_USER_NAME)); + Assert.assertEquals("1234", claims.get(AuthConstant.TOKEN_USER_ID)); + Assert.assertEquals(4102444800000L, claims.getExpiration().getTime()); + } + + @Test + public void testRejectExpiredToken() { + TokenGenerator generator = new TokenGenerator(SECRET); + String token = generator.create(Collections.singletonMap("user_name", "alice"), + -60000L); + Assert.assertThrows(ExpiredJwtException.class, () -> generator.verify(token)); + } + + @Test + public void testRejectWrongKeyAndMalformedTokens() { + TokenGenerator generator = new TokenGenerator(SECRET); + String token = generator.create(Collections.singletonMap("user_name", "alice"), + 60000L); + TokenGenerator other = new TokenGenerator("abcdefghijklmnopqrstuvwxyz012345"); + Assert.assertThrows(JwtException.class, () -> other.verify(token)); + Assert.assertThrows(JwtException.class, () -> generator.verify("not-a-token")); + Assert.assertThrows(IllegalArgumentException.class, () -> generator.verify("")); + } + + @Test + public void testRejectUnsignedToken() { + TokenGenerator generator = new TokenGenerator(SECRET); + String token = generator.create(Collections.singletonMap("user_name", "alice"), + 60000L); + String unsigned = "eyJhbGciOiJub25lIn0." + token.split("\\.")[1] + "."; + Assert.assertThrows(JwtException.class, () -> generator.verify(unsigned)); + } + + @Test + public void testRejectWeakKey() { + Assert.assertThrows(WeakKeyException.class, () -> new TokenGenerator("short-key")); + } +} diff --git a/hugegraph-pd/hg-pd-service/pom.xml b/hugegraph-pd/hg-pd-service/pom.xml index 12b0933dd8..18f03dff2e 100644 --- a/hugegraph-pd/hg-pd-service/pom.xml +++ b/hugegraph-pd/hg-pd-service/pom.xml @@ -57,16 +57,29 @@ ${revision} + - org.apache.hugegraph - hg-store-common - ${revision} + org.apache.commons + commons-text + 1.10.0 - org.apache.hugegraph - hugegraph-core - ${revision} + io.jsonwebtoken + jjwt-api + 0.11.5 + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + runtime + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + runtime diff --git a/hugegraph-pd/hg-pd-test/pom.xml b/hugegraph-pd/hg-pd-test/pom.xml index d9c0ea325b..a248bcb87b 100644 --- a/hugegraph-pd/hg-pd-test/pom.xml +++ b/hugegraph-pd/hg-pd-test/pom.xml @@ -32,7 +32,6 @@ true - 2.0.0-RC.3 @@ -160,33 +159,6 @@ - - org.powermock - powermock-classloading-xstream - ${powermock.version} - - - org.powermock - powermock-module-junit4-rule - ${powermock.version} - - - org.powermock - powermock-api-support - ${powermock.version} - - - org.powermock - powermock-module-junit4 - 2.0.0-RC.3 - compile - - - org.powermock - powermock-api-mockito2 - 2.0.0-RC.3 - compile - diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/API.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/API.java index b50195b85d..b5653d5977 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/API.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/API.java @@ -24,7 +24,7 @@ import java.util.function.Consumer; import org.apache.commons.lang.mutable.MutableLong; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.define.Checkable; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/AccessAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/AccessAPI.java index 117da8e9ae..578685feb1 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/AccessAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/AccessAPI.java @@ -26,7 +26,7 @@ import org.apache.hugegraph.auth.HugeAccess; import org.apache.hugegraph.auth.HugePermission; import org.apache.hugegraph.auth.HugeTarget; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.define.Checkable; import org.apache.hugegraph.exception.NotFoundException; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/BelongAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/BelongAPI.java index d5e3f105bb..5f2d6d5663 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/BelongAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/BelongAPI.java @@ -24,7 +24,7 @@ import org.apache.hugegraph.api.filter.StatusFilter.Status; import org.apache.hugegraph.auth.AuthManager; import org.apache.hugegraph.auth.HugeBelong; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.define.Checkable; import org.apache.hugegraph.exception.NotFoundException; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/GraphSpaceGroupAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/GraphSpaceGroupAPI.java index d41de962e2..eb3b7c1ec2 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/GraphSpaceGroupAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/GraphSpaceGroupAPI.java @@ -29,7 +29,7 @@ import org.apache.hugegraph.auth.HugeGroup; import org.apache.hugegraph.auth.HugeUser; import org.apache.hugegraph.auth.StandardAuthManagerV2; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.define.Checkable; import org.apache.hugegraph.exception.NotFoundException; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/GroupAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/GroupAPI.java index ae13beb4a6..f19200c65a 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/GroupAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/GroupAPI.java @@ -22,7 +22,7 @@ import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.filter.StatusFilter.Status; import org.apache.hugegraph.auth.HugeGroup; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.define.Checkable; import org.apache.hugegraph.exception.NotFoundException; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/ProjectAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/ProjectAPI.java index 4380093ba0..322d434bff 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/ProjectAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/ProjectAPI.java @@ -27,7 +27,7 @@ import org.apache.hugegraph.api.filter.StatusFilter.Status; import org.apache.hugegraph.auth.AuthManager; import org.apache.hugegraph.auth.HugeProject; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.define.Checkable; import org.apache.hugegraph.exception.NotFoundException; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/UserAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/UserAPI.java index 7504ad7325..d5e5288f49 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/UserAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/UserAPI.java @@ -23,8 +23,8 @@ import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.filter.StatusFilter.Status; import org.apache.hugegraph.auth.HugeUser; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.define.Checkable; import org.apache.hugegraph.exception.NotFoundException; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/cypher/CypherClient.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/cypher/CypherClient.java index 85d98a25ce..ebe0c7bb3c 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/cypher/CypherClient.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/cypher/CypherClient.java @@ -32,7 +32,7 @@ import javax.annotation.concurrent.ThreadSafe; import org.apache.commons.configuration2.Configuration; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.util.E; import org.apache.hugegraph.util.Log; import org.apache.tinkerpop.gremlin.driver.Client; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/ExceptionFilter.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/ExceptionFilter.java index 20dc1808ab..e59c86d991 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/ExceptionFilter.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/ExceptionFilter.java @@ -26,7 +26,7 @@ import javax.json.JsonObjectBuilder; import org.apache.commons.lang3.StringUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.api.API; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.config.ServerOptions; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/graph/BatchAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/graph/BatchAPI.java index 85beb142db..fc0ff2cc98 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/graph/BatchAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/graph/BatchAPI.java @@ -21,7 +21,7 @@ import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicInteger; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.API; import org.apache.hugegraph.config.HugeConfig; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/graph/EdgeAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/graph/EdgeAPI.java index 1f229cd6b1..c9c741a657 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/graph/EdgeAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/graph/EdgeAPI.java @@ -29,17 +29,17 @@ import org.apache.hugegraph.api.filter.CompressInterceptor.Compress; import org.apache.hugegraph.api.filter.DecompressInterceptor.Decompress; import org.apache.hugegraph.api.filter.StatusFilter.Status; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.ConditionQuery; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.config.ServerOptions; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.define.UpdateStrategy; import org.apache.hugegraph.exception.NotFoundException; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.traversal.optimize.QueryHolder; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/graph/VertexAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/graph/VertexAPI.java index af1433ac46..31ab5c032b 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/graph/VertexAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/graph/VertexAPI.java @@ -30,16 +30,16 @@ import org.apache.hugegraph.api.filter.CompressInterceptor.Compress; import org.apache.hugegraph.api.filter.DecompressInterceptor.Decompress; import org.apache.hugegraph.api.filter.StatusFilter.Status; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.SplicingIdGenerator; -import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.SplicingIdGenerator; +import org.apache.hugegraph.query.ConditionQuery; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.config.ServerOptions; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.define.UpdateStrategy; import org.apache.hugegraph.exception.NotFoundException; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.traversal.optimize.QueryHolder; import org.apache.hugegraph.traversal.optimize.Text; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/AlgorithmAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/AlgorithmAPI.java index 6554d58072..95be404582 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/AlgorithmAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/AlgorithmAPI.java @@ -22,7 +22,7 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.filter.StatusFilter.Status; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.job.AlgorithmJob; import org.apache.hugegraph.job.JobBuilder; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/ComputerAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/ComputerAPI.java index 222ead7e55..478562566a 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/ComputerAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/ComputerAPI.java @@ -22,7 +22,7 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.filter.StatusFilter.Status; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.job.ComputerJob; import org.apache.hugegraph.job.JobBuilder; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/GremlinAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/GremlinAPI.java index c6abac4067..d727ebeb53 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/GremlinAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/GremlinAPI.java @@ -25,11 +25,11 @@ import java.util.HashMap; import java.util.Map; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.filter.StatusFilter.Status; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.define.Checkable; import org.apache.hugegraph.job.GremlinJob; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/RebuildAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/RebuildAPI.java index 6c103ca414..1508e9ff7f 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/RebuildAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/RebuildAPI.java @@ -22,7 +22,7 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.filter.StatusFilter.Status; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.util.Log; import org.slf4j.Logger; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/TaskAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/TaskAPI.java index 0accec132a..f3613434c1 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/TaskAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/TaskAPI.java @@ -27,8 +27,8 @@ import org.apache.groovy.util.Maps; import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.filter.StatusFilter.Status; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.page.PageInfo; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.task.HugeTask; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/profile/GraphsAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/profile/GraphsAPI.java index 94169e4a90..95505be80b 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/profile/GraphsAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/profile/GraphsAPI.java @@ -29,7 +29,7 @@ import java.util.Map; import java.util.Set; import org.apache.commons.lang3.StringUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.filter.StatusFilter; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/raft/RaftAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/raft/RaftAPI.java index fcc18c4c8c..f3987635f7 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/raft/RaftAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/raft/RaftAPI.java @@ -21,11 +21,11 @@ import java.util.List; import java.util.Map; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.filter.StatusFilter.Status; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.store.raft.RaftAddPeerJob; import org.apache.hugegraph.backend.store.raft.RaftGroupManager; import org.apache.hugegraph.backend.store.raft.RaftRemovePeerJob; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/schema/EdgeLabelAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/schema/EdgeLabelAPI.java index 3031b687d0..3a7db5f85c 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/schema/EdgeLabelAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/schema/EdgeLabelAPI.java @@ -27,11 +27,11 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.filter.StatusFilter.Status; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.define.Checkable; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.Userdata; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.Userdata; import org.apache.hugegraph.type.define.EdgeLabelType; import org.apache.hugegraph.type.define.Frequency; import org.apache.hugegraph.type.define.GraphMode; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/schema/IndexLabelAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/schema/IndexLabelAPI.java index 3bc769801d..bf66d3ea95 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/schema/IndexLabelAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/schema/IndexLabelAPI.java @@ -26,12 +26,12 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.filter.StatusFilter.Status; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.define.Checkable; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.schema.Userdata; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.Userdata; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.GraphMode; import org.apache.hugegraph.type.define.IndexType; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/schema/PropertyKeyAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/schema/PropertyKeyAPI.java index 1364b02fea..9cf19c819f 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/schema/PropertyKeyAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/schema/PropertyKeyAPI.java @@ -26,13 +26,13 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.filter.StatusFilter.Status; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.define.Checkable; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.schema.Userdata; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.Userdata; import org.apache.hugegraph.type.define.AggregateType; import org.apache.hugegraph.type.define.Cardinality; import org.apache.hugegraph.type.define.DataType; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/schema/VertexLabelAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/schema/VertexLabelAPI.java index 4001ce27f5..ff3320ae74 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/schema/VertexLabelAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/schema/VertexLabelAPI.java @@ -26,11 +26,11 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.filter.StatusFilter.Status; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.define.Checkable; -import org.apache.hugegraph.schema.Userdata; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.Userdata; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.type.define.GraphMode; import org.apache.hugegraph.type.define.IdStrategy; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/space/SchemaTemplateAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/space/SchemaTemplateAPI.java index cffca156cd..e1dab458f6 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/space/SchemaTemplateAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/space/SchemaTemplateAPI.java @@ -23,7 +23,7 @@ import java.util.function.Supplier; import org.apache.commons.lang3.StringUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.api.API; import org.apache.hugegraph.auth.AuthManager; import org.apache.hugegraph.api.filter.StatusFilter; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/AdamicAdarAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/AdamicAdarAPI.java index 6bf8bf3b82..11cdc3dec0 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/AdamicAdarAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/AdamicAdarAPI.java @@ -17,6 +17,8 @@ package org.apache.hugegraph.api.traversers; +import org.apache.hugegraph.util.TinkerPopUtil; + import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_ELEMENTS_LIMIT; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_MAX_DEGREE; @@ -24,7 +26,7 @@ import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.graph.EdgeAPI; import org.apache.hugegraph.api.graph.VertexAPI; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.traversal.algorithm.PredictionTraverser; import org.apache.hugegraph.type.define.Directions; @@ -77,7 +79,7 @@ public String get(@Context GraphManager manager, Id targetId = VertexAPI.checkAndParseVertexId(other); E.checkArgument(!current.equals(other), "The source and target vertex id can't be same"); - Directions dir = Directions.convert(EdgeAPI.parseDirection(direction)); + Directions dir = TinkerPopUtil.direction(EdgeAPI.parseDirection(direction)); HugeGraph g = graph(manager, graphSpace, graph); try (PredictionTraverser traverser = new PredictionTraverser(g)) { diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/AllShortestPathsAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/AllShortestPathsAPI.java index 3880b1239e..f02f116a1e 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/AllShortestPathsAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/AllShortestPathsAPI.java @@ -17,6 +17,8 @@ package org.apache.hugegraph.api.traversers; +import org.apache.hugegraph.util.TinkerPopUtil; + import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_CAPACITY; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_MAX_DEGREE; @@ -29,7 +31,7 @@ import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.graph.EdgeAPI; import org.apache.hugegraph.api.graph.VertexAPI; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.traversal.algorithm.HugeTraverser; import org.apache.hugegraph.traversal.algorithm.ShortestPathTraverser; @@ -103,7 +105,7 @@ public String get(@Context GraphManager manager, Id sourceId = VertexAPI.checkAndParseVertexId(source); Id targetId = VertexAPI.checkAndParseVertexId(target); - Directions dir = Directions.convert(EdgeAPI.parseDirection(direction)); + Directions dir = TinkerPopUtil.direction(EdgeAPI.parseDirection(direction)); HugeGraph g = graph(manager, graphSpace, graph); diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/CountAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/CountAPI.java index 7dd58dd892..9ac1bf69c3 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/CountAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/CountAPI.java @@ -27,7 +27,7 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.API; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.traversal.algorithm.CountTraverser; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/CrosspointsAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/CrosspointsAPI.java index de728b57dc..2d98c4d144 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/CrosspointsAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/CrosspointsAPI.java @@ -17,6 +17,8 @@ package org.apache.hugegraph.api.traversers; +import org.apache.hugegraph.util.TinkerPopUtil; + import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_CAPACITY; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_MAX_DEGREE; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_PATHS_LIMIT; @@ -25,7 +27,7 @@ import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.graph.EdgeAPI; import org.apache.hugegraph.api.graph.VertexAPI; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.traversal.algorithm.HugeTraverser; import org.apache.hugegraph.traversal.algorithm.PathsTraverser; @@ -78,7 +80,7 @@ public String get(@Context GraphManager manager, ApiMeasurer measure = new ApiMeasurer(); Id sourceId = VertexAPI.checkAndParseVertexId(source); Id targetId = VertexAPI.checkAndParseVertexId(target); - Directions dir = Directions.convert(EdgeAPI.parseDirection(direction)); + Directions dir = TinkerPopUtil.direction(EdgeAPI.parseDirection(direction)); HugeGraph g = graph(manager, graphSpace, graph); PathsTraverser traverser = new PathsTraverser(g); diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/CustomizedCrosspointsAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/CustomizedCrosspointsAPI.java index 6307ad332c..e9c5028da2 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/CustomizedCrosspointsAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/CustomizedCrosspointsAPI.java @@ -31,7 +31,7 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.API; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.traversal.algorithm.CustomizedCrosspointsTraverser; import org.apache.hugegraph.traversal.algorithm.HugeTraverser; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/CustomizedPathsAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/CustomizedPathsAPI.java index 4f3a783a3b..383fec6e5c 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/CustomizedPathsAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/CustomizedPathsAPI.java @@ -32,7 +32,7 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.API; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.traversal.algorithm.CustomizePathsTraverser; import org.apache.hugegraph.traversal.algorithm.HugeTraverser; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java index 388f40e6ef..154d031008 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java @@ -23,7 +23,7 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.graph.VertexAPI; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.traversal.algorithm.EdgeExistenceTraverser; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgesAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgesAPI.java index 807fcce92c..9ae331a02d 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgesAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgesAPI.java @@ -25,9 +25,9 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.filter.CompressInterceptor.Compress; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.store.Shard; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.backend.Shard; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.type.HugeType; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/FusiformSimilarityAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/FusiformSimilarityAPI.java index 2c0ea1ff33..6536fc22c3 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/FusiformSimilarityAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/FusiformSimilarityAPI.java @@ -27,7 +27,7 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.API; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.traversal.algorithm.FusiformSimilarityTraverser; import org.apache.hugegraph.traversal.algorithm.FusiformSimilarityTraverser.SimilarsMap; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/JaccardSimilarityAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/JaccardSimilarityAPI.java index 59f94f23e2..f410212bb2 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/JaccardSimilarityAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/JaccardSimilarityAPI.java @@ -17,6 +17,8 @@ package org.apache.hugegraph.api.traversers; +import org.apache.hugegraph.util.TinkerPopUtil; + import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_CAPACITY; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_LIMIT; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_MAX_DEGREE; @@ -26,7 +28,7 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.graph.EdgeAPI; import org.apache.hugegraph.api.graph.VertexAPI; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.traversal.algorithm.JaccardSimilarTraverser; @@ -79,7 +81,7 @@ public String get(@Context GraphManager manager, Id sourceId = VertexAPI.checkAndParseVertexId(vertex); Id targetId = VertexAPI.checkAndParseVertexId(other); - Directions dir = Directions.convert(EdgeAPI.parseDirection(direction)); + Directions dir = TinkerPopUtil.direction(EdgeAPI.parseDirection(direction)); HugeGraph g = graph(manager, graphSpace, graph); double similarity; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/KneighborAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/KneighborAPI.java index 83183d08c5..6351c03e44 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/KneighborAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/KneighborAPI.java @@ -17,6 +17,8 @@ package org.apache.hugegraph.api.traversers; +import org.apache.hugegraph.util.TinkerPopUtil; + import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_ELEMENTS_LIMIT; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_MAX_DEGREE; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.NO_LIMIT; @@ -30,7 +32,7 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.graph.EdgeAPI; import org.apache.hugegraph.api.graph.VertexAPI; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.structure.HugeVertex; @@ -104,7 +106,7 @@ public String get(@Context GraphManager manager, ApiMeasurer measure = new ApiMeasurer(); Id source = VertexAPI.checkAndParseVertexId(sourceV); - Directions dir = Directions.convert(EdgeAPI.parseDirection(direction)); + Directions dir = TinkerPopUtil.direction(EdgeAPI.parseDirection(direction)); HugeGraph g = graph(manager, graphSpace, graph); diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/KoutAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/KoutAPI.java index e784e38b40..38bb536e0d 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/KoutAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/KoutAPI.java @@ -17,6 +17,8 @@ package org.apache.hugegraph.api.traversers; +import org.apache.hugegraph.util.TinkerPopUtil; + import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_CAPACITY; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_ELEMENTS_LIMIT; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_MAX_DEGREE; @@ -31,7 +33,7 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.graph.EdgeAPI; import org.apache.hugegraph.api.graph.VertexAPI; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.structure.HugeVertex; @@ -110,7 +112,7 @@ public String get(@Context GraphManager manager, ApiMeasurer measure = new ApiMeasurer(); Id sourceId = VertexAPI.checkAndParseVertexId(source); - Directions dir = Directions.convert(EdgeAPI.parseDirection(direction)); + Directions dir = TinkerPopUtil.direction(EdgeAPI.parseDirection(direction)); HugeGraph g = graph(manager, graphSpace, graph); diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/MultiNodeShortestPathAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/MultiNodeShortestPathAPI.java index a2a7a4fd96..6b42350cf1 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/MultiNodeShortestPathAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/MultiNodeShortestPathAPI.java @@ -25,7 +25,7 @@ import java.util.Set; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.traversal.algorithm.HugeTraverser; import org.apache.hugegraph.traversal.algorithm.MultiNodeShortestPathTraverser; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/NeighborRankAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/NeighborRankAPI.java index 08396aa0b3..c5ec47b7da 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/NeighborRankAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/NeighborRankAPI.java @@ -28,7 +28,7 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.API; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.traversal.algorithm.NeighborRankTraverser; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/PathsAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/PathsAPI.java index 5c3a5c5d99..b4345b1d59 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/PathsAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/PathsAPI.java @@ -17,6 +17,8 @@ package org.apache.hugegraph.api.traversers; +import org.apache.hugegraph.util.TinkerPopUtil; + import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_CAPACITY; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_MAX_DEGREE; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_MAX_DEPTH; @@ -30,7 +32,7 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.graph.EdgeAPI; import org.apache.hugegraph.api.graph.VertexAPI; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.traversal.algorithm.CollectionPathsTraverser; import org.apache.hugegraph.traversal.algorithm.HugeTraverser; @@ -92,7 +94,7 @@ public String get(@Context GraphManager manager, Id sourceId = VertexAPI.checkAndParseVertexId(source); Id targetId = VertexAPI.checkAndParseVertexId(target); - Directions dir = Directions.convert(EdgeAPI.parseDirection(direction)); + Directions dir = TinkerPopUtil.direction(EdgeAPI.parseDirection(direction)); HugeGraph g = graph(manager, graphSpace, graph); PathsTraverser traverser = new PathsTraverser(g); diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/PersonalRankAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/PersonalRankAPI.java index 45393e2a2b..5367eed10b 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/PersonalRankAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/PersonalRankAPI.java @@ -26,7 +26,7 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.API; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.traversal.algorithm.HugeTraverser; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/RaysAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/RaysAPI.java index fda3d16369..aa3b20310c 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/RaysAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/RaysAPI.java @@ -17,6 +17,8 @@ package org.apache.hugegraph.api.traversers; +import org.apache.hugegraph.util.TinkerPopUtil; + import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_CAPACITY; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_MAX_DEGREE; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_PATHS_LIMIT; @@ -29,7 +31,7 @@ import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.graph.EdgeAPI; import org.apache.hugegraph.api.graph.VertexAPI; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.traversal.algorithm.HugeTraverser; import org.apache.hugegraph.traversal.algorithm.SubGraphTraverser; @@ -85,7 +87,7 @@ public String get(@Context GraphManager manager, ApiMeasurer measure = new ApiMeasurer(); Id source = VertexAPI.checkAndParseVertexId(sourceV); - Directions dir = Directions.convert(EdgeAPI.parseDirection(direction)); + Directions dir = TinkerPopUtil.direction(EdgeAPI.parseDirection(direction)); HugeGraph g = graph(manager, graphSpace, graph); diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/ResourceAllocationAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/ResourceAllocationAPI.java index d3ff2b4ae5..32b2d305f0 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/ResourceAllocationAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/ResourceAllocationAPI.java @@ -17,6 +17,8 @@ package org.apache.hugegraph.api.traversers; +import org.apache.hugegraph.util.TinkerPopUtil; + import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_ELEMENTS_LIMIT; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_MAX_DEGREE; @@ -24,7 +26,7 @@ import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.graph.EdgeAPI; import org.apache.hugegraph.api.graph.VertexAPI; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.traversal.algorithm.PredictionTraverser; import org.apache.hugegraph.type.define.Directions; @@ -77,7 +79,7 @@ public String create(@Context GraphManager manager, Id targetId = VertexAPI.checkAndParseVertexId(other); E.checkArgument(!current.equals(other), "The source and target vertex id can't be same"); - Directions dir = Directions.convert(EdgeAPI.parseDirection(direction)); + Directions dir = TinkerPopUtil.direction(EdgeAPI.parseDirection(direction)); HugeGraph g = graph(manager, graphSpace, graph); try (PredictionTraverser traverser = new PredictionTraverser(g)) { diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/RingsAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/RingsAPI.java index 62726fd2f9..5f2c76172b 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/RingsAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/RingsAPI.java @@ -17,6 +17,8 @@ package org.apache.hugegraph.api.traversers; +import org.apache.hugegraph.util.TinkerPopUtil; + import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_CAPACITY; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_MAX_DEGREE; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_PATHS_LIMIT; @@ -29,7 +31,7 @@ import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.graph.EdgeAPI; import org.apache.hugegraph.api.graph.VertexAPI; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.traversal.algorithm.HugeTraverser; import org.apache.hugegraph.traversal.algorithm.SubGraphTraverser; @@ -88,7 +90,7 @@ public String get(@Context GraphManager manager, ApiMeasurer measure = new ApiMeasurer(); Id source = VertexAPI.checkAndParseVertexId(sourceV); - Directions dir = Directions.convert(EdgeAPI.parseDirection(direction)); + Directions dir = TinkerPopUtil.direction(EdgeAPI.parseDirection(direction)); HugeGraph g = graph(manager, graphSpace, graph); diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/SameNeighborsAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/SameNeighborsAPI.java index a4e652629e..c89c53c44c 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/SameNeighborsAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/SameNeighborsAPI.java @@ -17,6 +17,8 @@ package org.apache.hugegraph.api.traversers; +import org.apache.hugegraph.util.TinkerPopUtil; + import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_ELEMENTS_LIMIT; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_MAX_DEGREE; @@ -30,7 +32,7 @@ import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.graph.EdgeAPI; import org.apache.hugegraph.api.graph.VertexAPI; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.traversal.algorithm.SameNeighborTraverser; @@ -83,7 +85,7 @@ public String get(@Context GraphManager manager, Id sourceId = VertexAPI.checkAndParseVertexId(vertex); Id targetId = VertexAPI.checkAndParseVertexId(other); - Directions dir = Directions.convert(EdgeAPI.parseDirection(direction)); + Directions dir = TinkerPopUtil.direction(EdgeAPI.parseDirection(direction)); HugeGraph g = graph(manager, graphSpace, graph); SameNeighborTraverser traverser = new SameNeighborTraverser(g); @@ -108,7 +110,7 @@ public String sameNeighbors(@Context GraphManager manager, ApiMeasurer measure = new ApiMeasurer(); - Directions dir = Directions.convert(EdgeAPI.parseDirection(request.direction)); + Directions dir = TinkerPopUtil.direction(EdgeAPI.parseDirection(request.direction)); HugeGraph g = graph(manager, graphSpace, graph); SameNeighborTraverser traverser = new SameNeighborTraverser(g); diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/ShortestPathAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/ShortestPathAPI.java index 6a6ecd2317..16a4b26cb8 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/ShortestPathAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/ShortestPathAPI.java @@ -17,6 +17,8 @@ package org.apache.hugegraph.api.traversers; +import org.apache.hugegraph.util.TinkerPopUtil; + import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_CAPACITY; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_MAX_DEGREE; @@ -28,7 +30,7 @@ import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.graph.EdgeAPI; import org.apache.hugegraph.api.graph.VertexAPI; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.traversal.algorithm.HugeTraverser; import org.apache.hugegraph.traversal.algorithm.ShortestPathTraverser; @@ -103,7 +105,7 @@ public String get(@Context GraphManager manager, Id sourceId = VertexAPI.checkAndParseVertexId(source); Id targetId = VertexAPI.checkAndParseVertexId(target); - Directions dir = Directions.convert(EdgeAPI.parseDirection(direction)); + Directions dir = TinkerPopUtil.direction(EdgeAPI.parseDirection(direction)); HugeGraph g = graph(manager, graphSpace, graph); diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/SingleSourceShortestPathAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/SingleSourceShortestPathAPI.java index 85e23d9b76..50fc31b154 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/SingleSourceShortestPathAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/SingleSourceShortestPathAPI.java @@ -17,6 +17,8 @@ package org.apache.hugegraph.api.traversers; +import org.apache.hugegraph.util.TinkerPopUtil; + import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_CAPACITY; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_MAX_DEGREE; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_PATHS_LIMIT; @@ -28,7 +30,7 @@ import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.graph.EdgeAPI; import org.apache.hugegraph.api.graph.VertexAPI; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.traversal.algorithm.HugeTraverser; import org.apache.hugegraph.traversal.algorithm.SingleSourceShortestPathTraverser; @@ -88,7 +90,7 @@ public String get(@Context GraphManager manager, ApiMeasurer measure = new ApiMeasurer(); Id sourceId = VertexAPI.checkAndParseVertexId(source); - Directions dir = Directions.convert(EdgeAPI.parseDirection(direction)); + Directions dir = TinkerPopUtil.direction(EdgeAPI.parseDirection(direction)); HugeGraph g = graph(manager, graphSpace, graph); SingleSourceShortestPathTraverser traverser = diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/TemplatePathsAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/TemplatePathsAPI.java index d264d6b3b2..84f963baa3 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/TemplatePathsAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/TemplatePathsAPI.java @@ -27,7 +27,7 @@ import java.util.Set; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.traversal.algorithm.HugeTraverser; import org.apache.hugegraph.traversal.algorithm.TemplatePathsTraverser; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/Vertices.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/Vertices.java index 3efee83ab2..874ab24791 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/Vertices.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/Vertices.java @@ -24,9 +24,9 @@ import java.util.Set; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.schema.SchemaLabel; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.struct.schema.SchemaLabel; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.traversal.optimize.TraversalUtil; import org.apache.hugegraph.type.HugeType; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/VerticesAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/VerticesAPI.java index 2f853ec352..0dc09256fe 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/VerticesAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/VerticesAPI.java @@ -26,9 +26,9 @@ import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.filter.CompressInterceptor.Compress; import org.apache.hugegraph.api.graph.VertexAPI; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.store.Shard; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.backend.Shard; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/WeightedShortestPathAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/WeightedShortestPathAPI.java index e705bfba09..a9bbcaf0d3 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/WeightedShortestPathAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/WeightedShortestPathAPI.java @@ -17,6 +17,8 @@ package org.apache.hugegraph.api.traversers; +import org.apache.hugegraph.util.TinkerPopUtil; + import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_CAPACITY; import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_MAX_DEGREE; @@ -28,7 +30,7 @@ import org.apache.hugegraph.api.API; import org.apache.hugegraph.api.graph.EdgeAPI; import org.apache.hugegraph.api.graph.VertexAPI; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.traversal.algorithm.HugeTraverser; @@ -101,7 +103,7 @@ public String get(@Context GraphManager manager, ApiMeasurer measure = new ApiMeasurer(); Id sourceId = VertexAPI.checkAndParseVertexId(source); Id targetId = VertexAPI.checkAndParseVertexId(target); - Directions dir = Directions.convert(EdgeAPI.parseDirection(direction)); + Directions dir = TinkerPopUtil.direction(EdgeAPI.parseDirection(direction)); E.checkArgumentNotNull(weight, "The weight property can't be null"); HugeGraph g = graph(manager, graphSpace, graph); diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/ContextGremlinServer.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/ContextGremlinServer.java index e859050132..6911b20302 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/ContextGremlinServer.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/ContextGremlinServer.java @@ -21,7 +21,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.ThreadFactory; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.auth.HugeGraphAuthProxy.Context; import org.apache.hugegraph.auth.HugeGraphAuthProxy.ContextThreadPoolExecutor; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/HugeAuthenticator.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/HugeAuthenticator.java index 243342b63f..e58a7eb5a9 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/HugeAuthenticator.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/HugeAuthenticator.java @@ -22,16 +22,16 @@ import java.util.Map; import java.util.regex.Pattern; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.auth.HugeGraphAuthProxy.Context; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.config.OptionSpace; import org.apache.hugegraph.config.ServerOptions; import org.apache.hugegraph.structure.HugeElement; -import org.apache.hugegraph.type.Nameable; +import org.apache.hugegraph.type.Namifiable; import org.apache.hugegraph.util.E; import org.apache.hugegraph.util.JsonUtil; import org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.CredentialGraphTokens; @@ -477,12 +477,12 @@ private boolean matchResource(HugePermission requiredAction, // check label String requiredLabel; if (requiredType.isSchema()) { - requiredLabel = ((Nameable) requiredResource.operated()).name(); + requiredLabel = ((Namifiable) requiredResource.operated()).name(); } else if (requiredType.isGraph()) { if (requiredResource.operated() instanceof HugeElement) { requiredLabel = ((HugeElement) requiredResource.operated()).label(); } else { - requiredLabel = ((Nameable) requiredResource.operated()).name(); + requiredLabel = ((Namifiable) requiredResource.operated()).name(); } } else { return true; @@ -651,7 +651,7 @@ public static RequiredPerm fromJson(String json) { } public ResourceObject resourceObject() { - Nameable elem = HugeResource.NameObject.ANY; + Namifiable elem = HugeResource.NameObject.ANY; return ResourceObject.of(this.graphSpace, this.owner, this.resource, elem); } } diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/HugeFactoryAuthProxy.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/HugeFactoryAuthProxy.java index bb954446db..78ef3d72d2 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/HugeFactoryAuthProxy.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/HugeFactoryAuthProxy.java @@ -27,7 +27,7 @@ import java.util.Set; import org.apache.commons.configuration2.Configuration; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeFactory; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.StandardHugeGraph; @@ -38,7 +38,7 @@ import org.apache.hugegraph.backend.tx.IndexableTransaction; import org.apache.hugegraph.concurrent.LockManager; import org.apache.hugegraph.metrics.ServerReporter; -import org.apache.hugegraph.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.SchemaElement; import org.apache.hugegraph.schema.SchemaManager; import org.apache.hugegraph.schema.builder.AbstractBuilder; import org.apache.hugegraph.schema.builder.EdgeLabelBuilder; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/HugeGraphAuthProxy.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/HugeGraphAuthProxy.java index 9ecda6b9f7..702abfe3b5 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/HugeGraphAuthProxy.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/HugeGraphAuthProxy.java @@ -41,14 +41,15 @@ import org.apache.commons.configuration2.Configuration; import org.apache.hugegraph.HugeGraph; +import org.apache.hugegraph.HugeGraphSupplier; import org.apache.hugegraph.auth.HugeAuthenticator.RolePerm; import org.apache.hugegraph.auth.HugeAuthenticator.User; import org.apache.hugegraph.auth.SchemaDefine.AuthElement; import org.apache.hugegraph.backend.cache.Cache; import org.apache.hugegraph.backend.cache.CacheManager; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.store.BackendFeatures; import org.apache.hugegraph.backend.store.BackendStoreInfo; import org.apache.hugegraph.backend.store.BackendStoreProvider; @@ -63,13 +64,13 @@ import org.apache.hugegraph.masterelection.GlobalMasterInfo; import org.apache.hugegraph.rpc.RpcServiceConfig4Client; import org.apache.hugegraph.rpc.RpcServiceConfig4Server; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.schema.SchemaLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.SchemaLabel; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeElement; import org.apache.hugegraph.structure.HugeFeatures; @@ -81,7 +82,7 @@ import org.apache.hugegraph.task.TaskStatus; import org.apache.hugegraph.traversal.optimize.HugeScriptTraversal; import org.apache.hugegraph.type.HugeType; -import org.apache.hugegraph.type.Nameable; +import org.apache.hugegraph.type.Namifiable; import org.apache.hugegraph.type.define.GraphMode; import org.apache.hugegraph.type.define.GraphReadMode; import org.apache.hugegraph.util.E; @@ -743,7 +744,7 @@ public void proxy(HugeGraph graph) { } @Override - public boolean sameAs(HugeGraph graph) { + public boolean sameAs(HugeGraphSupplier graph) { if (graph instanceof HugeGraphAuthProxy) { graph = ((HugeGraphAuthProxy) graph).hugegraph; } @@ -1053,7 +1054,7 @@ private void verifyPermission(HugePermission actionPerm, LOG.debug("Using requestGraphSpace: {}", graphSpace); } - Nameable elem = HugeResource.NameObject.ANY; + Namifiable elem = HugeResource.NameObject.ANY; return ResourceObject.of(graphSpace, graph, resType, elem); }); } @@ -1147,7 +1148,7 @@ private void verifyNamePermission(HugePermission actionPerm, ResourceType resType, String name) { verifyResPermission(actionPerm, true, () -> { String graph = this.hugegraph.name(); - Nameable elem = HugeResource.NameObject.of(name); + Namifiable elem = HugeResource.NameObject.of(name); // For global resources like USER_GROUP, use request graph space from HugeGraphAuthProxy // instead of the graph space where authManager is located @@ -1513,7 +1514,7 @@ private HugeTask verifyTaskPermission(HugePermission actionPerm, Object r = verifyResPermission(actionPerm, throwIfNoPerm, () -> { String graph = HugeGraphAuthProxy.this.hugegraph.name(); String name = task.id().toString(); - Nameable elem = HugeResource.NameObject.of(name); + Namifiable elem = HugeResource.NameObject.of(name); return ResourceObject.of(graphSpace(), graph, ResourceType.TASK, elem); }, () -> { return hasTaskPermission(task); diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/core/GraphManager.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/core/GraphManager.java index 62b588c911..1a8c1b5d1e 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/core/GraphManager.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/core/GraphManager.java @@ -48,7 +48,7 @@ import org.apache.commons.configuration2.MapConfiguration; import org.apache.commons.configuration2.PropertiesConfiguration; import org.apache.commons.lang3.StringUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeFactory; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.StandardHugeGraph; @@ -59,7 +59,7 @@ import org.apache.hugegraph.auth.HugeGraphAuthProxy; import org.apache.hugegraph.auth.HugeUser; import org.apache.hugegraph.auth.StandardAuthenticator; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.backend.cache.Cache; import org.apache.hugegraph.backend.cache.CacheManager; import org.apache.hugegraph.backend.store.AbstractBackendStoreProvider; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/kvstore/KvStoreImpl.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/kvstore/KvStoreImpl.java index 01f217d63b..c6c7f6eae2 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/kvstore/KvStoreImpl.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/kvstore/KvStoreImpl.java @@ -25,9 +25,9 @@ import java.util.Map; import java.util.Optional; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.store.Shard; +import org.apache.hugegraph.backend.Shard; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.variables.HugeVariables; import org.apache.tinkerpop.gremlin.structure.Vertex; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/serializer/JsonSerializer.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/serializer/JsonSerializer.java index 8d02dd6c8c..e7b5952d2d 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/serializer/JsonSerializer.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/serializer/JsonSerializer.java @@ -24,17 +24,17 @@ import java.util.List; import java.util.Map; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.api.API; import org.apache.hugegraph.auth.SchemaDefine.AuthElement; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.page.PageInfo; import org.apache.hugegraph.iterator.Metadatable; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.space.GraphSpace; import org.apache.hugegraph.space.SchemaTemplate; import org.apache.hugegraph.space.Service; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/serializer/Serializer.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/serializer/Serializer.java index 1585725b09..ddc2102f60 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/serializer/Serializer.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/serializer/Serializer.java @@ -23,12 +23,12 @@ import java.util.Map; import org.apache.hugegraph.auth.SchemaDefine.AuthElement; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.space.GraphSpace; import org.apache.hugegraph.space.SchemaTemplate; import org.apache.hugegraph.space.Service; diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/server/ApplicationConfig.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/server/ApplicationConfig.java index dd4a0f46e9..9bbed7f486 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/server/ApplicationConfig.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/server/ApplicationConfig.java @@ -17,11 +17,11 @@ package org.apache.hugegraph.server; -import org.apache.hugegraph.HugeException; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.define.WorkLoad; import org.apache.hugegraph.event.EventHub; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.util.E; import org.apache.hugegraph.version.CoreVersion; import org.apache.tinkerpop.gremlin.server.util.MetricManager; diff --git a/hugegraph-server/hugegraph-core/pom.xml b/hugegraph-server/hugegraph-core/pom.xml index 70b7a125af..88d89f6898 100644 --- a/hugegraph-server/hugegraph-core/pom.xml +++ b/hugegraph-server/hugegraph-core/pom.xml @@ -32,13 +32,6 @@ 0.7.4 5.12.1 1.8.1 - 1.10.0 - 2.6.2 - portable-1.8.3 - 5.1.6 - 8.11.2 - 1.0.2 - 2012_u6 1.21 11.1.0 8.5.9 @@ -206,58 +199,6 @@ ${lz4.version} - - - org.ansj - ansj_seg - ${ansj-seg.version} - - - com.hankcs - hanlp - ${hanlp.version} - - - org.apache.lucene - lucene-analyzers-smartcn - ${lucene.version} - - - org.apache.lucene - lucene-core - ${lucene.version} - - - com.huaban - jieba-analysis - ${jieba-analysis.version} - - - org.lionsoul - jcseg-core - ${jcseg.version} - - - com.chenlb.mmseg4j - mmseg4j-core - ${mmseg4j-core.version} - - - com.janeluo - ikanalyzer - ${ikanalyzer.version} - - - org.apache.lucene - lucene-core - - - org.apache.lucene - lucene-analyzers-common - - - - it.unimi.dsi @@ -295,7 +236,7 @@ org.apache.hugegraph - hg-store-common + hugegraph-struct ${revision} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/HugeException.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/HugeException.java deleted file mode 100644 index fec7bc1449..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/HugeException.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph; - -import java.io.InterruptedIOException; - -import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalInterruptedException; - -public class HugeException extends RuntimeException { - - private static final long serialVersionUID = -8711375282196157058L; - - public HugeException(String message) { - super(message); - } - - public HugeException(String message, Throwable cause) { - super(message, cause); - } - - public HugeException(String message, Object... args) { - super(String.format(message, args)); - } - - public HugeException(String message, Throwable cause, Object... args) { - super(String.format(message, args), cause); - } - - public Throwable rootCause() { - return rootCause(this); - } - - public static Throwable rootCause(Throwable e) { - Throwable cause = e; - while (cause.getCause() != null) { - cause = cause.getCause(); - } - return cause; - } - - public static boolean isInterrupted(Throwable e) { - Throwable rootCause = HugeException.rootCause(e); - return rootCause instanceof InterruptedException || - rootCause instanceof TraversalInterruptedException || - rootCause instanceof InterruptedIOException; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/HugeFactory.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/HugeFactory.java index f258cb5c7b..cac015b0f6 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/HugeFactory.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/HugeFactory.java @@ -17,6 +17,8 @@ package org.apache.hugegraph; +import org.apache.hugegraph.exception.HugeException; + import java.io.File; import java.net.URL; import java.util.HashMap; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/HugeGraph.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/HugeGraph.java index 927614488e..6cc903a64d 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/HugeGraph.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/HugeGraph.java @@ -27,8 +27,8 @@ import org.apache.commons.lang3.tuple.Pair; import org.apache.hugegraph.auth.AuthManager; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.store.BackendFeatures; import org.apache.hugegraph.backend.store.BackendStoreInfo; import org.apache.hugegraph.backend.store.BackendStoreProvider; @@ -39,13 +39,13 @@ import org.apache.hugegraph.masterelection.GlobalMasterInfo; import org.apache.hugegraph.rpc.RpcServiceConfig4Client; import org.apache.hugegraph.rpc.RpcServiceConfig4Server; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.schema.SchemaLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.SchemaLabel; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeFeatures; import org.apache.hugegraph.task.TaskScheduler; import org.apache.hugegraph.traversal.optimize.HugeConnectiveLabelStepStrategy; @@ -70,7 +70,7 @@ /** * Graph interface for Gremlin operations */ -public interface HugeGraph extends Graph { +public interface HugeGraph extends Graph, HugeGraphSupplier { HugeGraph hugegraph(); @@ -280,7 +280,7 @@ public interface HugeGraph extends Graph { void proxy(HugeGraph graph); - boolean sameAs(HugeGraph graph); + boolean sameAs(HugeGraphSupplier graph); long now(); @@ -307,15 +307,6 @@ default List mapVlId2Name(Collection ids) { return names; } - default List mapElId2Name(Collection ids) { - List names = new ArrayList<>(ids.size()); - for (Id id : ids) { - SchemaElement schema = this.edgeLabel(id); - names.add(schema.name()); - } - return names; - } - default List mapIlId2Name(Collection ids) { List names = new ArrayList<>(ids.size()); for (Id id : ids) { @@ -347,16 +338,6 @@ default Id[] mapElName2Id(String[] edgeLabels) { return ids; } - default Set> mapPairId2Name( - Set> pairs) { - Set> results = new HashSet<>(pairs.size()); - for (Pair pair : pairs) { - results.add(Pair.of(this.vertexLabel(pair.getLeft()).name(), - this.vertexLabel(pair.getRight()).name())); - } - return results; - } - default Id[] mapVlName2Id(String[] vertexLabels) { Id[] ids = new Id[vertexLabels.length]; for (int i = 0; i < vertexLabels.length; i++) { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/StandardHugeGraph.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/StandardHugeGraph.java index 7f79c93bb7..b55ad34e19 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/StandardHugeGraph.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/StandardHugeGraph.java @@ -17,6 +17,8 @@ package org.apache.hugegraph; +import org.apache.hugegraph.exception.HugeException; + import java.util.Arrays; import java.util.Collection; import java.util.Date; @@ -34,7 +36,7 @@ import org.apache.hugegraph.auth.AuthManager; import org.apache.hugegraph.auth.StandardAuthManager; import org.apache.hugegraph.auth.StandardAuthManagerV2; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.backend.LocalCounter; import org.apache.hugegraph.backend.cache.Cache; import org.apache.hugegraph.backend.cache.CacheNotifier; @@ -43,12 +45,12 @@ import org.apache.hugegraph.backend.cache.CachedGraphTransaction; import org.apache.hugegraph.backend.cache.CachedSchemaTransaction; import org.apache.hugegraph.backend.cache.CachedSchemaTransactionV2; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.id.SnowflakeIdGenerator; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.serializer.AbstractSerializer; -import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.backend.serializer.SerializerFactory; import org.apache.hugegraph.backend.store.BackendFeatures; import org.apache.hugegraph.backend.store.BackendProviderFactory; @@ -76,13 +78,13 @@ import org.apache.hugegraph.perf.PerfUtil.Watched; import org.apache.hugegraph.rpc.RpcServiceConfig4Client; import org.apache.hugegraph.rpc.RpcServiceConfig4Server; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.schema.SchemaLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.SchemaLabel; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeEdgeProperty; import org.apache.hugegraph.structure.HugeFeatures; @@ -1255,7 +1257,7 @@ public final void proxy(HugeGraph graph) { } @Override - public boolean sameAs(HugeGraph graph) { + public boolean sameAs(HugeGraphSupplier graph) { return this == graph; } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/AnalyzerFactory.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/AnalyzerFactory.java deleted file mode 100644 index 21dd157b11..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/AnalyzerFactory.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.analyzer; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.backend.serializer.SerializerFactory; - -public class AnalyzerFactory { - - private static final Map> ANALYZERS; - - static { - ANALYZERS = new ConcurrentHashMap<>(); - } - - public static Analyzer analyzer(String name, String mode) { - name = name.toLowerCase(); - switch (name) { - case "ansj": - return new AnsjAnalyzer(mode); - case "hanlp": - return new HanLPAnalyzer(mode); - case "smartcn": - return new SmartCNAnalyzer(mode); - case "jieba": - return new JiebaAnalyzer(mode); - case "jcseg": - return new JcsegAnalyzer(mode); - case "mmseg4j": - return new MMSeg4JAnalyzer(mode); - case "ikanalyzer": - return new IKAnalyzer(mode); - default: - return customizedAnalyzer(name, mode); - } - } - - private static Analyzer customizedAnalyzer(String name, String mode) { - Class clazz = ANALYZERS.get(name); - if (clazz == null) { - throw new HugeException("Not exists analyzer: %s", name); - } - - assert Analyzer.class.isAssignableFrom(clazz); - try { - return clazz.getConstructor(String.class).newInstance(mode); - } catch (Exception e) { - throw new HugeException( - "Failed to construct analyzer '%s' with mode '%s'", - e, name, mode); - } - } - - @SuppressWarnings({"rawtypes", "unchecked"}) - public static void register(String name, String classPath) { - ClassLoader classLoader = SerializerFactory.class.getClassLoader(); - Class clazz; - try { - clazz = classLoader.loadClass(classPath); - } catch (Exception e) { - throw new HugeException("Load class path '%s' failed", - e, classPath); - } - - // Check subclass - if (!Analyzer.class.isAssignableFrom(clazz)) { - throw new HugeException("Class '%s' is not a subclass of " + - "class Analyzer", classPath); - } - - // Check exists - if (ANALYZERS.containsKey(name)) { - throw new HugeException("Exists analyzer: %s(%s)", - name, ANALYZERS.get(name).getName()); - } - - // Register class - ANALYZERS.put(name, (Class) clazz); - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/AnsjAnalyzer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/AnsjAnalyzer.java deleted file mode 100644 index 2f857cd171..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/AnsjAnalyzer.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.analyzer; - -import java.util.List; -import java.util.Set; - -import org.ansj.domain.Result; -import org.ansj.domain.Term; -import org.ansj.splitWord.analysis.BaseAnalysis; -import org.ansj.splitWord.analysis.IndexAnalysis; -import org.ansj.splitWord.analysis.NlpAnalysis; -import org.ansj.splitWord.analysis.ToAnalysis; -import org.apache.hugegraph.config.ConfigException; -import org.apache.hugegraph.util.InsertionOrderUtil; - -import com.google.common.collect.ImmutableList; - -/** - * Reference from https://github.com/NLPchina/ansj_seg/wiki - */ -public class AnsjAnalyzer implements Analyzer { - - public static final List SUPPORT_MODES = ImmutableList.of( - "BaseAnalysis", - "IndexAnalysis", - "ToAnalysis", - "NlpAnalysis" - ); - - private final String analysis; - - public AnsjAnalyzer(String mode) { - if (!SUPPORT_MODES.contains(mode)) { - throw new ConfigException( - "Unsupported segment mode '%s' for ansj analyzer, " + - "the available values are %s", mode, SUPPORT_MODES); - } - this.analysis = mode; - } - - @Override - public Set segment(String text) { - Result terms; - switch (this.analysis) { - case "BaseAnalysis": - terms = BaseAnalysis.parse(text); - break; - case "ToAnalysis": - terms = ToAnalysis.parse(text); - break; - case "NlpAnalysis": - terms = NlpAnalysis.parse(text); - break; - case "IndexAnalysis": - terms = IndexAnalysis.parse(text); - break; - default: - throw new AssertionError(String.format( - "Unsupported segment mode '%s'", this.analysis)); - } - - assert terms != null; - Set result = InsertionOrderUtil.newSet(); - for (Term term : terms) { - result.add(term.getName()); - } - return result; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/HanLPAnalyzer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/HanLPAnalyzer.java deleted file mode 100644 index 8b5fa6aa0a..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/HanLPAnalyzer.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.analyzer; - -import java.util.List; -import java.util.Set; - -import org.apache.hugegraph.config.ConfigException; -import org.apache.hugegraph.util.InsertionOrderUtil; - -import com.google.common.collect.ImmutableList; -import com.hankcs.hanlp.seg.Dijkstra.DijkstraSegment; -import com.hankcs.hanlp.seg.NShort.NShortSegment; -import com.hankcs.hanlp.seg.Segment; -import com.hankcs.hanlp.seg.common.Term; -import com.hankcs.hanlp.tokenizer.IndexTokenizer; -import com.hankcs.hanlp.tokenizer.NLPTokenizer; -import com.hankcs.hanlp.tokenizer.SpeedTokenizer; -import com.hankcs.hanlp.tokenizer.StandardTokenizer; - -/** - * Reference from https://github.com/hankcs/HanLP/wiki - */ -public class HanLPAnalyzer implements Analyzer { - - public static final List SUPPORT_MODES = - ImmutableList.builder() - .add("standard") - .add("nlp") - .add("index") - .add("nShort") - .add("shortest") - .add("speed") - .build(); - - private static final Segment N_SHORT_SEGMENT = - new NShortSegment().enableCustomDictionary(false) - .enablePlaceRecognize(true) - .enableOrganizationRecognize(true); - private static final Segment DIJKSTRA_SEGMENT = - new DijkstraSegment().enableCustomDictionary(false) - .enablePlaceRecognize(true) - .enableOrganizationRecognize(true); - - private final String tokenizer; - - public HanLPAnalyzer(String mode) { - if (!SUPPORT_MODES.contains(mode)) { - throw new ConfigException( - "Unsupported segment mode '%s' for hanlp analyzer, " + - "the available values are %s", mode, SUPPORT_MODES); - } - this.tokenizer = mode; - } - - @Override - public Set segment(String text) { - List terms; - switch (this.tokenizer) { - case "standard": - terms = StandardTokenizer.segment(text); - break; - case "nlp": - terms = NLPTokenizer.segment(text); - break; - case "index": - terms = IndexTokenizer.segment(text); - break; - case "nShort": - terms = N_SHORT_SEGMENT.seg(text); - break; - case "shortest": - terms = DIJKSTRA_SEGMENT.seg(text); - break; - case "speed": - terms = SpeedTokenizer.segment(text); - break; - default: - throw new AssertionError(String.format( - "Unsupported segment mode '%s'", this.tokenizer)); - } - - assert terms != null; - Set result = InsertionOrderUtil.newSet(); - for (Term term : terms) { - result.add(term.word); - } - return result; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/IKAnalyzer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/IKAnalyzer.java deleted file mode 100644 index ab564f396f..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/IKAnalyzer.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.analyzer; - -import java.io.StringReader; -import java.util.List; -import java.util.Set; - -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.config.ConfigException; -import org.apache.hugegraph.util.InsertionOrderUtil; -import org.wltea.analyzer.core.IKSegmenter; -import org.wltea.analyzer.core.Lexeme; - -import com.google.common.collect.ImmutableList; - -/** - * Reference from https://github.com/yyn0210/IKAnalyzer - */ -public class IKAnalyzer implements Analyzer { - - public static final List SUPPORT_MODES = ImmutableList.of( - "smart", - "max_word" - ); - - private final boolean smartSegMode; - - public IKAnalyzer(String mode) { - if (!SUPPORT_MODES.contains(mode)) { - throw new ConfigException( - "Unsupported segment mode '%s' for ikanalyzer, " + - "the available values are %s", mode, SUPPORT_MODES); - } - this.smartSegMode = SUPPORT_MODES.get(0).equals(mode); - } - - @Override - public Set segment(String text) { - Set result = InsertionOrderUtil.newSet(); - IKSegmenter ik = new IKSegmenter(new StringReader(text), - this.smartSegMode); - try { - Lexeme word; - while ((word = ik.next()) != null) { - result.add(word.getLexemeText()); - } - } catch (Exception e) { - throw new HugeException("IKAnalyzer segment text '%s' failed", - e, text); - } - return result; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/JcsegAnalyzer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/JcsegAnalyzer.java deleted file mode 100644 index 3740e87b19..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/JcsegAnalyzer.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.analyzer; - -import java.io.StringReader; -import java.util.List; -import java.util.Set; - -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.config.ConfigException; -import org.apache.hugegraph.util.InsertionOrderUtil; -import org.lionsoul.jcseg.ISegment; -import org.lionsoul.jcseg.IWord; -import org.lionsoul.jcseg.dic.ADictionary; -import org.lionsoul.jcseg.dic.DictionaryFactory; -import org.lionsoul.jcseg.segmenter.SegmenterConfig; - -import com.google.common.collect.ImmutableList; - -/** - * Reference from https://github.com/lionsoul2014/jcseg - */ -public class JcsegAnalyzer implements Analyzer { - - public static final List SUPPORT_MODES = ImmutableList.of( - "Simple", - "Complex" - ); - - private static final SegmenterConfig CONFIG = new SegmenterConfig(); - private static final ADictionary DIC = DictionaryFactory.createDefaultDictionary(CONFIG); - - private final ISegment.Type type; - - public JcsegAnalyzer(String mode) { - if (!SUPPORT_MODES.contains(mode)) { - throw new ConfigException( - "Unsupported segment mode '%s' for jcseg analyzer, " + - "the available values are %s", mode, SUPPORT_MODES); - } - - if ("Simple".equals(mode)) { - this.type = ISegment.SIMPLE; - } else { - this.type = ISegment.COMPLEX; - } - } - - @Override - public Set segment(String text) { - Set result = InsertionOrderUtil.newSet(); - try { - ISegment segmentor = this.type.factory.create(CONFIG, DIC); - segmentor.reset(new StringReader(text)); - - IWord word; - while ((word = segmentor.next()) != null) { - result.add(word.getValue()); - } - } catch (Exception e) { - throw new HugeException("Jcseg segment text '%s' failed", e, text); - } - return result; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/JiebaAnalyzer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/JiebaAnalyzer.java deleted file mode 100644 index 7c280a50a1..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/JiebaAnalyzer.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.analyzer; - -import java.util.List; -import java.util.Set; - -import org.apache.hugegraph.config.ConfigException; -import org.apache.hugegraph.util.InsertionOrderUtil; - -import com.google.common.collect.ImmutableList; -import com.huaban.analysis.jieba.JiebaSegmenter; -import com.huaban.analysis.jieba.SegToken; - -/** - * Reference from https://github.com/huaban/jieba-analysis - */ -public class JiebaAnalyzer implements Analyzer { - - public static final List SUPPORT_MODES = ImmutableList.of( - "SEARCH", - "INDEX" - ); - - private static final JiebaSegmenter JIEBA_SEGMENTER = new JiebaSegmenter(); - - private final JiebaSegmenter.SegMode segMode; - - public JiebaAnalyzer(String mode) { - if (!SUPPORT_MODES.contains(mode)) { - throw new ConfigException( - "Unsupported segment mode '%s' for jieba analyzer, " + - "the available values are %s", mode, SUPPORT_MODES); - } - this.segMode = JiebaSegmenter.SegMode.valueOf(mode); - } - - @Override - public Set segment(String text) { - Set result = InsertionOrderUtil.newSet(); - for (SegToken token : JIEBA_SEGMENTER.process(text, this.segMode)) { - result.add(token.word); - } - return result; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/MMSeg4JAnalyzer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/MMSeg4JAnalyzer.java deleted file mode 100644 index 26e937a538..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/MMSeg4JAnalyzer.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.analyzer; - -import java.io.StringReader; -import java.util.List; -import java.util.Set; - -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.config.ConfigException; -import org.apache.hugegraph.util.InsertionOrderUtil; - -import com.chenlb.mmseg4j.ComplexSeg; -import com.chenlb.mmseg4j.Dictionary; -import com.chenlb.mmseg4j.MMSeg; -import com.chenlb.mmseg4j.MaxWordSeg; -import com.chenlb.mmseg4j.Seg; -import com.chenlb.mmseg4j.SimpleSeg; -import com.chenlb.mmseg4j.Word; -import com.google.common.collect.ImmutableList; - -/** - * Reference from https://github.com/chenlb/mmseg4j-core - */ -public class MMSeg4JAnalyzer implements Analyzer { - - public static final List SUPPORT_MODES = ImmutableList.of( - "Simple", - "Complex", - "MaxWord" - ); - - private static final Dictionary DIC = Dictionary.getInstance(); - - private final Seg seg; - - public MMSeg4JAnalyzer(String mode) { - if (!SUPPORT_MODES.contains(mode)) { - throw new ConfigException( - "Unsupported segment mode '%s' for mmseg4j analyzer, " + - "the available values are %s", mode, SUPPORT_MODES); - } - int index = SUPPORT_MODES.indexOf(mode); - switch (index) { - case 0: - this.seg = new SimpleSeg(DIC); - break; - case 1: - this.seg = new ComplexSeg(DIC); - break; - case 2: - this.seg = new MaxWordSeg(DIC); - break; - default: - throw new AssertionError(String.format( - "Unsupported segment mode '%s'", mode)); - } - } - - @Override - public Set segment(String text) { - Set result = InsertionOrderUtil.newSet(); - MMSeg mmSeg = new MMSeg(new StringReader(text), this.seg); - try { - Word word; - while ((word = mmSeg.next()) != null) { - result.add(word.getString()); - } - } catch (Exception e) { - throw new HugeException("MMSeg4j segment text '%s' failed", - e, text); - } - return result; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/SmartCNAnalyzer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/SmartCNAnalyzer.java deleted file mode 100644 index f265ade214..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/SmartCNAnalyzer.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.analyzer; - -import java.io.Reader; -import java.io.StringReader; -import java.util.Set; - -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.util.InsertionOrderUtil; -import org.apache.lucene.analysis.TokenStream; -import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer; -import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; - -/** - * Reference from https://lucene.apache.org/core/8_11_2/analyzers-smartcn/index.html - */ -public class SmartCNAnalyzer implements Analyzer { - - private static final SmartChineseAnalyzer ANALYZER = - new SmartChineseAnalyzer(); - - public SmartCNAnalyzer(String mode) { - // pass - } - - @Override - public Set segment(String text) { - Set result = InsertionOrderUtil.newSet(); - Reader reader = new StringReader(text); - try (TokenStream tokenStream = ANALYZER.tokenStream("text", reader)) { - tokenStream.reset(); - CharTermAttribute term; - while (tokenStream.incrementToken()) { - term = tokenStream.getAttribute(CharTermAttribute.class); - result.add(term.toString()); - } - } catch (Exception e) { - throw new HugeException("SmartCN segment text '%s' failed", - e, text); - } - return result; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/AuthManager.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/AuthManager.java index d1c8887238..09b08f3a00 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/AuthManager.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/AuthManager.java @@ -25,7 +25,7 @@ import javax.security.sasl.AuthenticationException; import org.apache.hugegraph.auth.SchemaDefine.AuthElement; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; public interface AuthManager { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/EntityManager.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/EntityManager.java index 4633625729..2a0b21ee62 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/EntityManager.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/EntityManager.java @@ -22,19 +22,19 @@ import java.util.Map; import java.util.function.Function; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.HugeGraphParams; import org.apache.hugegraph.auth.SchemaDefine.Entity; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.backend.tx.GraphTransaction; import org.apache.hugegraph.exception.NotFoundException; import org.apache.hugegraph.iterator.MapperIterator; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.HugeKeys; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeAccess.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeAccess.java index c40b67d57d..eef86c27b4 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeAccess.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeAccess.java @@ -27,9 +27,9 @@ import org.apache.commons.lang3.StringUtils; import org.apache.hugegraph.HugeGraphParams; import org.apache.hugegraph.auth.SchemaDefine.Relationship; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.schema.EdgeLabel; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.struct.schema.EdgeLabel; import org.apache.hugegraph.type.define.DataType; import org.apache.hugegraph.util.E; import org.apache.tinkerpop.gremlin.structure.Edge; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeBelong.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeBelong.java index 7d668f3c19..4d0353aec7 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeBelong.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeBelong.java @@ -24,9 +24,9 @@ import org.apache.hugegraph.HugeGraphParams; import org.apache.hugegraph.auth.SchemaDefine.Relationship; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.schema.EdgeLabel; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.struct.schema.EdgeLabel; import org.apache.tinkerpop.gremlin.structure.Edge; import org.apache.tinkerpop.gremlin.structure.Graph.Hidden; import org.apache.tinkerpop.gremlin.structure.T; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeGroup.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeGroup.java index defe5d130f..8e5ee9759e 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeGroup.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeGroup.java @@ -25,9 +25,9 @@ import org.apache.commons.lang3.StringUtils; import org.apache.hugegraph.HugeGraphParams; import org.apache.hugegraph.auth.SchemaDefine.Entity; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.util.E; import org.apache.tinkerpop.gremlin.structure.Graph.Hidden; import org.apache.tinkerpop.gremlin.structure.T; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeProject.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeProject.java index faafcddded..9b024bc57b 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeProject.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeProject.java @@ -27,9 +27,9 @@ import org.apache.commons.lang.StringUtils; import org.apache.hugegraph.HugeGraphParams; import org.apache.hugegraph.auth.SchemaDefine.Entity; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.type.define.Cardinality; import org.apache.hugegraph.type.define.DataType; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeResource.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeResource.java index 74577c258e..7dbd152d4e 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeResource.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeResource.java @@ -27,12 +27,12 @@ import java.util.Objects; import java.util.Set; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.auth.SchemaDefine.AuthElement; import org.apache.hugegraph.structure.HugeElement; import org.apache.hugegraph.traversal.optimize.TraversalUtil; -import org.apache.hugegraph.type.Nameable; -import org.apache.hugegraph.type.Typeable; +import org.apache.hugegraph.type.Namifiable; +import org.apache.hugegraph.type.Typifiable; import org.apache.hugegraph.util.JsonUtil; import org.apache.tinkerpop.gremlin.structure.Graph.Hidden; import org.apache.tinkerpop.gremlin.structure.Property; @@ -160,7 +160,7 @@ public boolean filter(ResourceObject resourceObject) { return this.filter((AuthElement) resourceObject.operated()); } if (resType.isSchema() || CHECK_NAME_RESS.contains(resType)) { - return this.filter((Nameable) resourceObject.operated()); + return this.filter((Namifiable) resourceObject.operated()); } } @@ -173,15 +173,15 @@ public boolean filter(ResourceObject resourceObject) { private boolean filter(AuthElement element) { assert this.type.match(element.type()); - if (element instanceof Nameable) { - return this.filter((Nameable) element); + if (element instanceof Namifiable) { + return this.filter((Namifiable) element); } return true; } - private boolean filter(Nameable element) { - assert !(element instanceof Typeable) || this.type.match( - ResourceType.from(((Typeable) element).type())); + private boolean filter(Namifiable element) { + assert !(element instanceof Typifiable) || this.type.match( + ResourceType.from(((Typifiable) element).type())); return this.matchLabel(element.name()); } @@ -288,7 +288,7 @@ public String toString() { public static boolean allowed(ResourceObject resourceObject) { // Allowed to access system(hidden) schema by anyone if (resourceObject.type().isSchema()) { - Nameable schema = (Nameable) resourceObject.operated(); + Namifiable schema = (Namifiable) resourceObject.operated(); return Hidden.isHidden(schema.name()); } @@ -302,7 +302,7 @@ public static HugeResource parseResource(String resource) { public boolean matchProperties(HugeResource other) { return matchProperties(other.properties); } - public static class NameObject implements Nameable { + public static class NameObject implements Namifiable { public static final NameObject ANY = new NameObject("*"); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeRole.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeRole.java index ee5955bbaf..78d1ff1197 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeRole.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeRole.java @@ -25,9 +25,9 @@ import org.apache.commons.lang3.StringUtils; import org.apache.hugegraph.HugeGraphParams; import org.apache.hugegraph.auth.SchemaDefine.Entity; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.util.E; import org.apache.tinkerpop.gremlin.structure.Graph.Hidden; import org.apache.tinkerpop.gremlin.structure.T; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeTarget.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeTarget.java index 34ff5aa87d..70fbb2803e 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeTarget.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeTarget.java @@ -23,12 +23,12 @@ import java.util.Map; import org.apache.commons.lang3.StringUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraphParams; import org.apache.hugegraph.auth.SchemaDefine.Entity; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.util.E; import org.apache.hugegraph.util.JsonUtil; import org.apache.tinkerpop.gremlin.structure.Graph.Hidden; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeUser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeUser.java index 8a90de0b17..c12946e7eb 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeUser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/HugeUser.java @@ -25,9 +25,9 @@ import org.apache.commons.lang3.StringUtils; import org.apache.hugegraph.HugeGraphParams; import org.apache.hugegraph.auth.SchemaDefine.Entity; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.util.E; import org.apache.tinkerpop.gremlin.structure.Graph.Hidden; import org.apache.tinkerpop.gremlin.structure.T; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/RelationshipManager.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/RelationshipManager.java index a1c440611e..fa7fd1299e 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/RelationshipManager.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/RelationshipManager.java @@ -22,20 +22,20 @@ import java.util.Map; import java.util.function.Function; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.HugeGraphParams; import org.apache.hugegraph.auth.SchemaDefine.Relationship; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.backend.tx.GraphTransaction; import org.apache.hugegraph.exception.NotFoundException; import org.apache.hugegraph.iterator.MapperIterator; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.type.HugeType; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/ResourceObject.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/ResourceObject.java index b745e07fe7..1bbf66d9b4 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/ResourceObject.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/ResourceObject.java @@ -18,9 +18,9 @@ package org.apache.hugegraph.auth; import org.apache.hugegraph.auth.SchemaDefine.AuthElement; -import org.apache.hugegraph.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.SchemaElement; import org.apache.hugegraph.structure.HugeElement; -import org.apache.hugegraph.type.Nameable; +import org.apache.hugegraph.type.Namifiable; import org.apache.hugegraph.util.E; public class ResourceObject { @@ -90,12 +90,12 @@ public static ResourceObject of(String graph, } public static ResourceObject of(String graphSpace, String graph, - ResourceType type, Nameable elem) { + ResourceType type, Namifiable elem) { return new ResourceObject<>(graphSpace, graph, type, elem); } public static ResourceObject of(String graph, ResourceType type, - Nameable elem) { + Namifiable elem) { return of("DEFAULT", graph, type, elem); } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/SchemaDefine.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/SchemaDefine.java index fe3556a59e..b5ea7331c7 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/SchemaDefine.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/SchemaDefine.java @@ -26,15 +26,15 @@ import java.util.Locale; import java.util.Map; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraphParams; import org.apache.hugegraph.auth.HugeTarget.P; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Cardinality; import org.apache.hugegraph.type.define.DataType; @@ -298,9 +298,9 @@ protected Object[] asArray(List list) { protected abstract Object[] asArray(); } - // NOTE: travis-ci fails if class Entity implements Nameable + // NOTE: travis-ci fails if class Entity implements Namifiable public abstract static class Entity extends AuthElement - implements org.apache.hugegraph.type.Nameable { + implements org.apache.hugegraph.type.Namifiable { private static final long serialVersionUID = 4113319546914811762L; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/StandardAuthManager.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/StandardAuthManager.java index 02f5e9b385..cc677ec7b1 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/StandardAuthManager.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/StandardAuthManager.java @@ -31,14 +31,14 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraphParams; import org.apache.hugegraph.auth.HugeUser.P; import org.apache.hugegraph.auth.SchemaDefine.AuthElement; import org.apache.hugegraph.backend.cache.Cache; import org.apache.hugegraph.backend.cache.CacheManager; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.config.AuthOptions; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.type.define.Directions; @@ -109,7 +109,7 @@ public StandardAuthManager(HugeGraphParams graph) { this.access = new RelationshipManager<>(this.graph, HugeAccess.P.ACCESS, HugeAccess::fromEdge); - this.tokenGenerator = new TokenGenerator(config); + this.tokenGenerator = new TokenGenerator(config.get(AuthOptions.AUTH_TOKEN_SECRET)); LOG.info("Randomly generate a JWT secret key now"); this.ipWhiteList = new HashSet<>(); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/StandardAuthManagerV2.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/StandardAuthManagerV2.java index 60e17f2b33..be019260bf 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/StandardAuthManagerV2.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/StandardAuthManagerV2.java @@ -35,13 +35,13 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraphParams; import org.apache.hugegraph.auth.SchemaDefine.AuthElement; import org.apache.hugegraph.backend.cache.Cache; import org.apache.hugegraph.backend.cache.CacheManager; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.config.AuthOptions; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.meta.MetaManager; @@ -159,7 +159,7 @@ public StandardAuthManagerV2(HugeGraphParams graph) { this.pwdCache = this.cache("users_pwd", capacity, expired); this.tokenCache = this.cache("token", capacity, expired); - this.tokenGenerator = new TokenGenerator(config); + this.tokenGenerator = new TokenGenerator(config.get(AuthOptions.AUTH_TOKEN_SECRET)); LOG.info("Randomly generate a JWT secret key now"); this.ipWhiteList = new HashSet<>(); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/UserWithRole.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/UserWithRole.java index a32517bfd5..8b822056a2 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/UserWithRole.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/UserWithRole.java @@ -17,7 +17,7 @@ package org.apache.hugegraph.auth; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; public class UserWithRole { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/BackendException.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/BackendException.java deleted file mode 100644 index a1f587866e..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/BackendException.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.backend; - -import org.apache.hugegraph.HugeException; - -public class BackendException extends HugeException { - - private static final long serialVersionUID = -1947589125372576298L; - - public BackendException(String message) { - super(message); - } - - public BackendException(String message, Throwable cause) { - super(message, cause); - } - - public BackendException(String message, Object... args) { - super(message, args); - } - - public BackendException(String message, Throwable cause, Object... args) { - super(message, cause, args); - } - - public BackendException(Throwable cause) { - this("Exception in backend", cause); - } - - public static final void check(boolean expression, String message, Object... args) - throws BackendException { - if (!expression) { - throw new BackendException(message, args); - } - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/LocalCounter.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/LocalCounter.java index 148703c072..6a166c7fbe 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/LocalCounter.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/LocalCounter.java @@ -21,8 +21,8 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.type.HugeType; public class LocalCounter { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/Transaction.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/Transaction.java index 1c7e18424d..4d93eb49be 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/Transaction.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/Transaction.java @@ -17,6 +17,8 @@ package org.apache.hugegraph.backend; +import org.apache.hugegraph.exception.BackendException; + public interface Transaction { void commit() throws BackendException; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CacheManager.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CacheManager.java index 30bffab814..67791483ff 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CacheManager.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CacheManager.java @@ -25,7 +25,7 @@ import java.util.concurrent.ConcurrentHashMap; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.util.E; import org.apache.hugegraph.util.Log; import org.slf4j.Logger; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CacheNotifier.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CacheNotifier.java index e470f1067a..947ad1100e 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CacheNotifier.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CacheNotifier.java @@ -17,7 +17,7 @@ package org.apache.hugegraph.backend.cache; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.type.HugeType; public interface CacheNotifier extends AutoCloseable { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedBackendStore.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedBackendStore.java index 3cc88bbf71..4a90745454 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedBackendStore.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedBackendStore.java @@ -22,10 +22,10 @@ import java.util.function.Function; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.ConditionQuery; import org.apache.hugegraph.backend.query.ConditionQueryFlatten; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.backend.store.BackendFeatures; import org.apache.hugegraph.backend.store.BackendMutation; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedGraphTransaction.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedGraphTransaction.java index a6085d32c4..e8e579e15e 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedGraphTransaction.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedGraphTransaction.java @@ -29,9 +29,9 @@ import org.apache.hugegraph.HugeGraphParams; import org.apache.hugegraph.backend.cache.CachedBackendStore.QueryId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.IdQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.IdQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.query.QueryBatch; import org.apache.hugegraph.backend.query.QueryResultContext; import org.apache.hugegraph.backend.query.QueryResults; @@ -48,7 +48,7 @@ import org.apache.hugegraph.iterator.ExtendableIterator; import org.apache.hugegraph.iterator.ListIterator; import org.apache.hugegraph.perf.PerfUtil.Watched; -import org.apache.hugegraph.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.type.HugeType; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedSchemaTransaction.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedSchemaTransaction.java index d393be7461..8e48218e30 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedSchemaTransaction.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedSchemaTransaction.java @@ -25,8 +25,8 @@ import java.util.function.Consumer; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.store.BackendStore; import org.apache.hugegraph.backend.store.ram.IntObjectMap; import org.apache.hugegraph.backend.tx.SchemaTransaction; @@ -34,7 +34,7 @@ import org.apache.hugegraph.event.EventHub; import org.apache.hugegraph.event.EventListener; import org.apache.hugegraph.perf.PerfUtil.Watched; -import org.apache.hugegraph.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.SchemaElement; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.util.E; import org.apache.hugegraph.util.Events; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedSchemaTransactionV2.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedSchemaTransactionV2.java index 74986b2e99..6ce6ae7db9 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedSchemaTransactionV2.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedSchemaTransactionV2.java @@ -27,8 +27,8 @@ import java.util.function.Consumer; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.store.ram.IntObjectMap; import org.apache.hugegraph.backend.tx.SchemaTransactionV2; import org.apache.hugegraph.config.CoreOptions; @@ -38,7 +38,7 @@ import org.apache.hugegraph.meta.MetaManager; import org.apache.hugegraph.meta.MetaManager.SchemaCacheClearEvent; import org.apache.hugegraph.perf.PerfUtil; -import org.apache.hugegraph.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.SchemaElement; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.util.E; import org.apache.hugegraph.util.Events; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/LevelCache.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/LevelCache.java index 7f3e971314..d0ee73fa73 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/LevelCache.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/LevelCache.java @@ -20,7 +20,7 @@ import java.util.Iterator; import java.util.function.Consumer; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.iterator.ExtendableIterator; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/OffheapCache.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/OffheapCache.java index 7ed4efcd66..fde018e183 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/OffheapCache.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/OffheapCache.java @@ -24,15 +24,15 @@ import java.util.List; import java.util.function.Consumer; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.serializer.AbstractSerializer; import org.apache.hugegraph.backend.serializer.BinaryBackendEntry; import org.apache.hugegraph.backend.serializer.BinarySerializer; -import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.backend.store.BackendEntry; -import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.type.HugeType; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/RamCache.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/RamCache.java index a5e8d162a8..b3364359dd 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/RamCache.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/RamCache.java @@ -25,7 +25,7 @@ import java.util.concurrent.locks.Lock; import java.util.function.Consumer; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.concurrent.KeyLock; import org.apache.hugegraph.perf.PerfUtil.Watched; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/EdgeId.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/EdgeId.java deleted file mode 100644 index 14116d8575..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/EdgeId.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.backend.id; - -import org.apache.hugegraph.exception.NotFoundException; -import org.apache.hugegraph.perf.PerfUtil.Watched; -import org.apache.hugegraph.structure.HugeVertex; -import org.apache.hugegraph.type.HugeType; -import org.apache.hugegraph.type.define.Directions; -import org.apache.hugegraph.type.define.HugeKeys; -import org.apache.hugegraph.util.E; -import org.apache.hugegraph.util.StringEncoding; - -/** - * Class used to format and parse id of edge, the edge id consists of: - * EdgeId = { source-vertex-id > direction > parentEdgeLabelId > subEdgeLabelId - * > sortKeys > target-vertex-id } - * NOTE: - *

1. for edges with edgeLabelType = NORMAL: edgeLabelId = parentEdgeLabelId = subEdgeLabelId; - * for edges with edgeLabelType = PARENT: edgeLabelId = subEdgeLabelId, parentEdgeLabelId = - * edgeLabelId.fatherId - *

2.if we use `entry.type()` which is IN or OUT as a part of id, - * an edge's id will be different due to different directions (belongs - * to 2 owner vertex) - */ -public class EdgeId implements Id { - - public static final HugeKeys[] KEYS = new HugeKeys[]{ - HugeKeys.OWNER_VERTEX, - HugeKeys.DIRECTION, - HugeKeys.LABEL, - HugeKeys.SUB_LABEL, - HugeKeys.SORT_VALUES, - HugeKeys.OTHER_VERTEX - }; - - protected final Id ownerVertexId; - protected final Id edgeLabelId; - protected final Id subLabelId; - protected final Id otherVertexId; - protected final Directions direction; - protected final boolean directed; - protected String sortValues; - protected String cache; - - public EdgeId(HugeVertex ownerVertex, Directions direction, - Id edgeLabelId, Id subLabelId, String sortValues, HugeVertex otherVertex) { - this(ownerVertex.id(), direction, edgeLabelId, subLabelId, - sortValues, otherVertex.id()); - } - - public EdgeId(Id ownerVertexId, Directions direction, Id edgeLabelId, Id subLabelId, - String sortValues, Id otherVertexId) { - this(ownerVertexId, direction, edgeLabelId, subLabelId, - sortValues, otherVertexId, false); - } - - public EdgeId(Id ownerVertexId, Directions direction, Id edgeLabelId, Id subLabelId, - String sortValues, Id otherVertexId, boolean directed) { - this.ownerVertexId = ownerVertexId; - this.direction = direction; - this.edgeLabelId = edgeLabelId; - this.subLabelId = subLabelId; - this.sortValues = sortValues; - this.otherVertexId = otherVertexId; - this.directed = directed; - this.cache = null; - } - - @Watched - public EdgeId switchDirection() { - Directions direction = this.direction.opposite(); - return new EdgeId(this.otherVertexId, direction, this.edgeLabelId, this.subLabelId, - this.sortValues, this.ownerVertexId, this.directed); - } - - public EdgeId directed(boolean directed) { - return new EdgeId(this.ownerVertexId, this.direction, this.edgeLabelId, this.subLabelId, - this.sortValues, this.otherVertexId, directed); - } - - private Id sourceVertexId() { - return this.direction == Directions.OUT ? - this.ownerVertexId : - this.otherVertexId; - } - - private Id targetVertexId() { - return this.direction == Directions.OUT ? - this.otherVertexId : - this.ownerVertexId; - } - - public Id ownerVertexId() { - return this.ownerVertexId; - } - - public Id edgeLabelId() { - return this.edgeLabelId; - } - - public Id subLabelId() { - return this.subLabelId; - } - - public Directions direction() { - return this.direction; - } - - public byte directionCode() { - return directionToCode(this.direction); - } - - public String sortValues() { - return this.sortValues; - } - - public Id otherVertexId() { - return this.otherVertexId; - } - - @Override - public Object asObject() { - return this.asString(); - } - - @Override - public String asString() { - if (this.cache != null) { - return this.cache; - } - if (this.directed) { - this.cache = SplicingIdGenerator.concat( - IdUtil.writeString(this.ownerVertexId), - this.direction.type().string(), - IdUtil.writeLong(this.edgeLabelId), - IdUtil.writeLong(this.subLabelId), - this.sortValues, - IdUtil.writeString(this.otherVertexId)); - } else { - this.cache = SplicingIdGenerator.concat( - IdUtil.writeString(this.sourceVertexId()), - IdUtil.writeLong(this.edgeLabelId), - IdUtil.writeLong(this.subLabelId), - this.sortValues, - IdUtil.writeString(this.targetVertexId())); - } - return this.cache; - } - - @Override - public long asLong() { - throw new UnsupportedOperationException(); - } - - @Override - public byte[] asBytes() { - return StringEncoding.encode(this.asString()); - } - - @Override - public int length() { - return this.asString().length(); - } - - @Override - public IdType type() { - return IdType.EDGE; - } - - @Override - public int compareTo(Id other) { - return this.asString().compareTo(other.asString()); - } - - @Override - public int hashCode() { - if (this.directed) { - return this.ownerVertexId.hashCode() ^ - this.direction.hashCode() ^ - this.edgeLabelId.hashCode() ^ - this.subLabelId.hashCode() ^ - this.sortValues.hashCode() ^ - this.otherVertexId.hashCode(); - } else { - return this.sourceVertexId().hashCode() ^ - this.edgeLabelId.hashCode() ^ - this.subLabelId.hashCode() ^ - this.sortValues.hashCode() ^ - this.targetVertexId().hashCode(); - } - } - - @Override - public boolean equals(Object object) { - if (!(object instanceof EdgeId)) { - return false; - } - EdgeId other = (EdgeId) object; - if (this.directed) { - return this.ownerVertexId.equals(other.ownerVertexId) && - this.direction == other.direction && - this.edgeLabelId.equals(other.edgeLabelId) && - this.subLabelId.equals(other.subLabelId) && - this.sortValues.equals(other.sortValues) && - this.otherVertexId.equals(other.otherVertexId); - } else { - return this.sourceVertexId().equals(other.sourceVertexId()) && - this.edgeLabelId.equals(other.edgeLabelId) && - this.subLabelId.equals(other.subLabelId) && - this.sortValues.equals(other.sortValues) && - this.targetVertexId().equals(other.targetVertexId()); - } - } - - @Override - public String toString() { - return this.asString(); - } - - public static byte directionToCode(Directions direction) { - return direction.type().code(); - } - - public static Directions directionFromCode(byte code) { - return Directions.convert(HugeType.fromCode(code)); - } - - public static boolean isOutDirectionFromCode(byte code) { - return code == HugeType.EDGE_OUT.code(); - } - - public static EdgeId parse(String id) throws NotFoundException { - return parse(id, false); - } - - public static EdgeId parse(String id, boolean returnNullIfError) - throws NotFoundException { - String[] idParts = SplicingIdGenerator.split(id); - if (!(idParts.length == 5 || idParts.length == 6)) { - if (returnNullIfError) { - return null; - } - throw new NotFoundException("Edge id must be formatted as 5~6 " + - "parts, but got %s parts: '%s'", - idParts.length, id); - } - try { - if (idParts.length == 5) { - Id ownerVertexId = IdUtil.readString(idParts[0]); - Id edgeLabelId = IdUtil.readLong(idParts[1]); - Id subLabelId = IdUtil.readLong(idParts[2]); - String sortValues = idParts[3]; - Id otherVertexId = IdUtil.readString(idParts[4]); - return new EdgeId(ownerVertexId, Directions.OUT, edgeLabelId, subLabelId, - sortValues, otherVertexId); - } else { - assert idParts.length == 6; - Id ownerVertexId = IdUtil.readString(idParts[0]); - HugeType direction = HugeType.fromString(idParts[1]); - Id edgeLabelId = IdUtil.readLong(idParts[2]); - Id subLabelId = IdUtil.readLong(idParts[3]); - String sortValues = idParts[4]; - Id otherVertexId = IdUtil.readString(idParts[5]); - return new EdgeId(ownerVertexId, Directions.convert(direction), - edgeLabelId, subLabelId, sortValues, otherVertexId); - } - } catch (Throwable e) { - if (returnNullIfError) { - return null; - } - throw new NotFoundException("Invalid format of edge id '%s'", - e, id); - } - } - - public static Id parseStoredString(String id) { - String[] idParts = split(id); - E.checkArgument(idParts.length == 5, "Invalid id format: %s", id); - Id ownerVertexId = IdUtil.readStoredString(idParts[0]); - Id edgeLabelId = IdGenerator.ofStoredString(idParts[1], IdType.LONG); - Id subLabelId = IdGenerator.ofStoredString(idParts[2], IdType.LONG); - String sortValues = idParts[3]; - Id otherVertexId = IdUtil.readStoredString(idParts[4]); - return new EdgeId(ownerVertexId, Directions.OUT, edgeLabelId, subLabelId, - sortValues, otherVertexId); - } - - public static String asStoredString(Id id) { - EdgeId eid = (EdgeId) id; - return SplicingIdGenerator.concat( - IdUtil.writeStoredString(eid.sourceVertexId()), - IdGenerator.asStoredString(eid.edgeLabelId()), - IdGenerator.asStoredString(eid.subLabelId()), - eid.sortValues(), - IdUtil.writeStoredString(eid.targetVertexId())); - } - - public static String concat(String... ids) { - return SplicingIdGenerator.concat(ids); - } - - public static String[] split(Id id) { - return EdgeId.split(id.asString()); - } - - public static String[] split(String id) { - return SplicingIdGenerator.split(id); - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/Id.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/Id.java deleted file mode 100644 index 077aa43dbb..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/Id.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.backend.id; - -import org.apache.hugegraph.util.E; - -public interface Id extends Comparable { - - int UUID_LENGTH = 16; - - Object asObject(); - - String asString(); - - long asLong(); - - byte[] asBytes(); - - int length(); - - IdType type(); - - default boolean number() { - return this.type() == IdType.LONG; - } - - default boolean uuid() { - return this.type() == IdType.UUID; - } - - default boolean string() { - return this.type() == IdType.STRING; - } - - default boolean edge() { - return this.type() == IdType.EDGE; - } - - enum IdType { - - UNKNOWN, - LONG, - UUID, - STRING, - EDGE; - - public char prefix() { - if (this == UNKNOWN) { - return 'N'; - } - return this.name().charAt(0); - } - - public static IdType valueOfPrefix(String id) { - E.checkArgument(id != null && !id.isEmpty(), "Invalid id '%s'", id); - switch (id.charAt(0)) { - case 'L': - return IdType.LONG; - case 'U': - return IdType.UUID; - case 'S': - return IdType.STRING; - case 'E': - return IdType.EDGE; - default: - return IdType.UNKNOWN; - } - } - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/IdGenerator.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/IdGenerator.java deleted file mode 100644 index 9f1bcc56fc..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/IdGenerator.java +++ /dev/null @@ -1,471 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.backend.id; - -import java.util.Objects; -import java.util.UUID; - -import org.apache.hugegraph.backend.id.Id.IdType; -import org.apache.hugegraph.backend.serializer.BytesBuffer; -import org.apache.hugegraph.structure.HugeVertex; -import org.apache.hugegraph.util.Bytes; -import org.apache.hugegraph.util.E; -import org.apache.hugegraph.util.LongEncoding; -import org.apache.hugegraph.util.NumericUtil; -import org.apache.hugegraph.util.StringEncoding; - -public abstract class IdGenerator { - - public static final Id ZERO = IdGenerator.of(0L); - - public abstract Id generate(HugeVertex vertex); - - public static Id of(String id) { - return new StringId(id); - } - - public static Id of(UUID id) { - return new UuidId(id); - } - - public static Id of(String id, boolean uuid) { - return uuid ? new UuidId(id) : new StringId(id); - } - - public static Id of(long id) { - return new LongId(id); - } - - public static Id of(Object id) { - if (id instanceof Id) { - return (Id) id; - } else if (id instanceof String) { - return of((String) id); - } else if (id instanceof Number) { - return of(((Number) id).longValue()); - } else if (id instanceof UUID) { - return of((UUID) id); - } - return new ObjectId(id); - } - - public static Id of(byte[] bytes, IdType type) { - switch (type) { - case LONG: - return new LongId(bytes); - case UUID: - return new UuidId(bytes); - case STRING: - return new StringId(bytes); - default: - throw new AssertionError("Invalid id type " + type); - } - } - - public static Id ofStoredString(String id, IdType type) { - switch (type) { - case LONG: - return of(LongEncoding.decodeSignedB64(id)); - case UUID: - byte[] bytes = StringEncoding.decodeBase64(id); - return of(bytes, IdType.UUID); - case STRING: - return of(id); - default: - throw new AssertionError("Invalid id type " + type); - } - } - - public static String asStoredString(Id id) { - switch (id.type()) { - case LONG: - return LongEncoding.encodeSignedB64(id.asLong()); - case UUID: - return StringEncoding.encodeBase64(id.asBytes()); - case STRING: - return id.asString(); - default: - throw new AssertionError("Invalid id type " + id.type()); - } - } - - public static IdType idType(Id id) { - if (id instanceof LongId) { - return IdType.LONG; - } - if (id instanceof UuidId) { - return IdType.UUID; - } - if (id instanceof StringId) { - return IdType.STRING; - } - if (id instanceof EdgeId) { - return IdType.EDGE; - } - return IdType.UNKNOWN; - } - - public static int compareType(Id id1, Id id2) { - return idType(id1).ordinal() - idType(id2).ordinal(); - } - - /****************************** id defines ******************************/ - - public static class StringId implements Id { - - protected String id; - protected byte[] bytes; - - public StringId(String id) { - E.checkArgument(id != null && !id.isEmpty(), - "The id can't be null or empty"); - this.id = id; - this.bytes = null; - } - - public StringId(byte[] bytes) { - E.checkArgument(bytes != null && bytes.length > 0, - "The id bytes can't be null or empty"); - this.bytes = bytes; - this.id = null; - } - - @Override - public IdType type() { - return IdType.STRING; - } - - @Override - public Object asObject() { - return this.asString(); - } - - @Override - public String asString() { - if (this.id == null) { - assert this.bytes != null; - this.id = StringEncoding.decode(this.bytes); - } - return this.id; - } - - @Override - public long asLong() { - return Long.parseLong(this.asString()); - } - - @Override - public byte[] asBytes() { - if (this.bytes == null) { - assert this.id != null; - this.bytes = StringEncoding.encode(this.id); - } - return this.bytes; - } - - @Override - public int length() { - return this.asString().length(); - } - - @Override - public int compareTo(Id other) { - int cmp = compareType(this, other); - if (cmp != 0) { - return cmp; - } - if (this.id != null) { - return this.id.compareTo(other.asString()); - } else { - return Bytes.compare(this.bytes, other.asBytes()); - } - } - - @Override - public int hashCode() { - return this.asString().hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof StringId)) { - return false; - } - StringId other = (StringId) obj; - if (this.id != null) { - return this.id.equals(other.asString()); - } else if (other.bytes == null) { - return this.asString().equals(other.asString()); - } else { - assert this.bytes != null; - return Bytes.equals(this.bytes, other.asBytes()); - } - } - - @Override - public String toString() { - return this.asString(); - } - } - - public static class LongId extends Number implements Id { - - private static final long serialVersionUID = -7732461469037400190L; - - protected Long id; - - public LongId(long id) { - this.id = id; - } - - public LongId(byte[] bytes) { - this.id = NumericUtil.bytesToLong(bytes); - } - - @Override - public IdType type() { - return IdType.LONG; - } - - @Override - public Object asObject() { - return this.id; - } - - @Override - public String asString() { - // TODO: encode with base64 - return Long.toString(this.id); - } - - @Override - public long asLong() { - return this.id; - } - - @Override - public byte[] asBytes() { - return NumericUtil.longToBytes(this.id); - } - - @Override - public int length() { - return Long.BYTES; - } - - @Override - public int compareTo(Id other) { - int cmp = compareType(this, other); - if (cmp != 0) { - return cmp; - } - return Long.compare(this.id, other.asLong()); - } - - @Override - public int hashCode() { - return Long.hashCode(this.id); - } - - @Override - public boolean equals(Object other) { - if (!(other instanceof Number)) { - return false; - } - return this.id == ((Number) other).longValue(); - } - - @Override - public String toString() { - return String.valueOf(this.id); - } - - @Override - public int intValue() { - return this.id.intValue(); - } - - @Override - public long longValue() { - return this.id; - } - - @Override - public float floatValue() { - return this.id; - } - - @Override - public double doubleValue() { - return this.id; - } - } - - public static class UuidId implements Id { - - protected UUID uuid; - - public UuidId(String string) { - this(StringEncoding.uuid(string)); - } - - public UuidId(byte[] bytes) { - this(fromBytes(bytes)); - } - - public UuidId(UUID uuid) { - E.checkArgument(uuid != null, "The uuid can't be null"); - this.uuid = uuid; - } - - @Override - public IdType type() { - return IdType.UUID; - } - - @Override - public Object asObject() { - return this.uuid; - } - - @Override - public String asString() { - return this.uuid.toString(); - } - - @Override - public long asLong() { - throw new UnsupportedOperationException(); - } - - @Override - public byte[] asBytes() { - BytesBuffer buffer = BytesBuffer.allocate(16); - buffer.writeLong(this.uuid.getMostSignificantBits()); - buffer.writeLong(this.uuid.getLeastSignificantBits()); - return buffer.bytes(); - } - - private static UUID fromBytes(byte[] bytes) { - E.checkArgument(bytes != null, "The UUID can't be null"); - BytesBuffer buffer = BytesBuffer.wrap(bytes); - long high = buffer.readLong(); - long low = buffer.readLong(); - return new UUID(high, low); - } - - @Override - public int length() { - return UUID_LENGTH; - } - - @Override - public int compareTo(Id other) { - E.checkNotNull(other, "compare id"); - int cmp = compareType(this, other); - if (cmp != 0) { - return cmp; - } - return this.uuid.compareTo(((UuidId) other).uuid); - } - - @Override - public int hashCode() { - return this.uuid.hashCode(); - } - - @Override - public boolean equals(Object other) { - if (!(other instanceof UuidId)) { - return false; - } - return this.uuid.equals(((UuidId) other).uuid); - } - - @Override - public String toString() { - return this.uuid.toString(); - } - } - - /** - * This class is just used by backend store for wrapper object as Id - */ - public static class ObjectId implements Id { - - protected Object object; - - public ObjectId(Object object) { - E.checkNotNull(object, "object"); - this.object = object; - } - - @Override - public IdType type() { - return IdType.UNKNOWN; - } - - @Override - public Object asObject() { - return this.object; - } - - @Override - public String asString() { - throw new UnsupportedOperationException(); - } - - @Override - public long asLong() { - throw new UnsupportedOperationException(); - } - - @Override - public byte[] asBytes() { - throw new UnsupportedOperationException(); - } - - @Override - public int length() { - throw new UnsupportedOperationException(); - } - - @Override - public int compareTo(Id o) { - throw new UnsupportedOperationException(); - } - - @Override - public int hashCode() { - return this.object.hashCode(); - } - - @Override - public boolean equals(Object other) { - if (!(other instanceof ObjectId)) { - return false; - } - return Objects.equals(this.object, ((ObjectId) other).object); - } - - @Override - public String toString() { - return this.object.toString(); - } - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/IdUtil.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/IdUtil.java deleted file mode 100644 index 90cd98d4b7..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/IdUtil.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.backend.id; - -import java.nio.ByteBuffer; - -import org.apache.commons.lang3.StringUtils; -import org.apache.hugegraph.backend.id.Id.IdType; -import org.apache.hugegraph.backend.serializer.BytesBuffer; - -public final class IdUtil { - - public static String writeStoredString(Id id) { - String idString; - switch (id.type()) { - case LONG: - case STRING: - case UUID: - idString = IdGenerator.asStoredString(id); - break; - case EDGE: - idString = EdgeId.asStoredString(id); - break; - default: - throw new AssertionError("Invalid id type " + id.type()); - } - return id.type().prefix() + idString; - } - - public static Id readStoredString(String id) { - IdType type = IdType.valueOfPrefix(id); - String idContent = id.substring(1); - switch (type) { - case LONG: - case STRING: - case UUID: - return IdGenerator.ofStoredString(idContent, type); - case EDGE: - return EdgeId.parseStoredString(idContent); - default: - throw new IllegalArgumentException("Invalid id: " + id); - } - } - - public static Object writeBinString(Id id) { - int len = id.edge() ? BytesBuffer.BUF_EDGE_ID : id.length() + 1; - BytesBuffer buffer = BytesBuffer.allocate(len).writeId(id); - buffer.forReadWritten(); - return buffer.asByteBuffer(); - } - - public static Id readBinString(Object id) { - BytesBuffer buffer = BytesBuffer.wrap((ByteBuffer) id); - return buffer.readId(); - } - - public static String writeString(Id id) { - String idString = id.asString(); - return id.type().prefix() + idString; - } - - public static Id readString(String id) { - IdType type = IdType.valueOfPrefix(id); - String idContent = id.substring(1); - switch (type) { - case LONG: - return IdGenerator.of(Long.parseLong(idContent)); - case STRING: - case UUID: - return IdGenerator.of(idContent, type == IdType.UUID); - case EDGE: - return EdgeId.parse(idContent); - default: - throw new IllegalArgumentException("Invalid id: " + id); - } - } - - public static String writeLong(Id id) { - return String.valueOf(id.asLong()); - } - - public static Id readLong(String id) { - return IdGenerator.of(Long.parseLong(id)); - } - - public static String escape(char splitor, char escape, String... values) { - int length = values.length + 4; - for (String value : values) { - length += value.length(); - } - StringBuilder escaped = new StringBuilder(length); - // Do escape for every item in values - for (String value : values) { - if (escaped.length() > 0) { - escaped.append(splitor); - } - - if (value.indexOf(splitor) == -1) { - escaped.append(value); - continue; - } - - // Do escape for current item - for (int i = 0, n = value.length(); i < n; i++) { - char ch = value.charAt(i); - if (ch == splitor) { - escaped.append(escape); - } - escaped.append(ch); - } - } - return escaped.toString(); - } - - public static String[] unescape(String id, String splitor, String escape) { - /* - * Note that the `splitter`/`escape` maybe special characters in regular - * expressions, but this is a frequently called method, for faster - * execution, we forbid the use of special characters as delimiter - * or escape sign. - * - * The `limit` param -1 in split method can ensure empty string be - * split to a part. - */ - String[] parts = id.split("(?'; - private static final char ID_SPLITOR = ':'; - private static final char NAME_SPLITOR = '!'; - - public static final String ESCAPE_STR = String.valueOf(ESCAPE); - public static final String IDS_SPLITOR_STR = String.valueOf(IDS_SPLITOR); - public static final String ID_SPLITOR_STR = String.valueOf(ID_SPLITOR); - - /****************************** id generate ******************************/ - - /** - * Generate a string id of HugeVertex from Vertex name - */ - @Override - public Id generate(HugeVertex vertex) { - /* - * Hash for row-key which will be evenly distributed. - * We can also use LongEncoding.encode() to encode the int/long hash - * if needed. - * id = String.format("%s%s%s", HashUtil.hash(id), ID_SPLITOR, id); - */ - // TODO: use binary Id with binary fields instead of string id - return splicing(vertex.schemaLabel().id().asString(), vertex.name()); - } - - /** - * Concat multiple ids into one composite id with IDS_SPLITOR - * - * @param ids the string id values to be concatted - * @return concatted string value - */ - public static String concat(String... ids) { - // NOTE: must support string id when using this method - return IdUtil.escape(IDS_SPLITOR, ESCAPE, ids); - } - - /** - * Split a composite id into multiple ids with IDS_SPLITOR - * - * @param ids the string id value to be splitted - * @return splitted string values - */ - public static String[] split(String ids) { - return IdUtil.unescape(ids, IDS_SPLITOR_STR, ESCAPE_STR); - } - - /** - * Concat property values with NAME_SPLITOR - * - * @param values the property values to be concatted - * @return concatted string value - */ - public static String concatValues(List values) { - // Convert the object list to string array - int valuesSize = values.size(); - String[] parts = new String[valuesSize]; - for (int i = 0; i < valuesSize; i++) { - parts[i] = values.get(i).toString(); - } - return IdUtil.escape(NAME_SPLITOR, ESCAPE, parts); - } - - /** - * Concat property values with NAME_SPLITOR - * - * @param values the property values to be concatted - * @return concatted string value - */ - public static String concatValues(Object... values) { - return concatValues(Arrays.asList(values)); - } - - /** - * Concat multiple parts into a single id with ID_SPLITOR - * - * @param parts the string id values to be spliced - * @return spliced id object - */ - public static Id splicing(String... parts) { - String escaped = IdUtil.escape(ID_SPLITOR, ESCAPE, parts); - return IdGenerator.of(escaped); - } - - /** - * Parse a single id into multiple parts with ID_SPLITOR - * - * @param id the id object to be parsed - * @return parsed string id parts - */ - public static String[] parse(Id id) { - return IdUtil.unescape(id.asString(), ID_SPLITOR_STR, ESCAPE_STR); - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/IdHolder.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/IdHolder.java index ab64959a01..e6fd34ed64 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/IdHolder.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/IdHolder.java @@ -23,9 +23,9 @@ import java.util.function.Function; import org.apache.commons.lang.NotImplementedException; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.iterator.CIter; import org.apache.hugegraph.iterator.Metadatable; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/PageEntryIterator.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/PageEntryIterator.java index 17996bae9e..832754afb8 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/PageEntryIterator.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/PageEntryIterator.java @@ -19,7 +19,7 @@ import java.util.Iterator; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.query.QueryBatch; import org.apache.hugegraph.backend.query.QueryBatch.BatchIterator; import org.apache.hugegraph.exception.NotSupportException; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/PageIds.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/PageIds.java index 879821f3db..e0e23c5668 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/PageIds.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/PageIds.java @@ -19,7 +19,7 @@ import java.util.Set; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import com.google.common.collect.ImmutableSet; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/PageInfo.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/PageInfo.java index 3662b6e660..2a913e32ab 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/PageInfo.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/PageInfo.java @@ -19,8 +19,8 @@ import java.util.Iterator; -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.exception.HugeException; +import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.iterator.Metadatable; import org.apache.hugegraph.util.Bytes; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/PageState.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/PageState.java index d0cdf74bce..4f08e87dbc 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/PageState.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/PageState.java @@ -17,8 +17,8 @@ package org.apache.hugegraph.backend.page; -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.exception.BackendException; +import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.util.Bytes; import org.apache.hugegraph.util.E; import org.apache.hugegraph.util.StringEncoding; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/QueryList.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/QueryList.java index d3d8e6960f..7609196982 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/QueryList.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/QueryList.java @@ -22,13 +22,13 @@ import java.util.List; import java.util.Set; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.page.IdHolder.BatchIdHolder; import org.apache.hugegraph.backend.page.IdHolder.FixedIdHolder; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.ConditionQuery.OptimizedType; -import org.apache.hugegraph.backend.query.IdQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.ConditionQuery.OptimizedType; +import org.apache.hugegraph.query.IdQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.query.QueryBatch; import org.apache.hugegraph.backend.query.QueryBatch.BatchIterator; import org.apache.hugegraph.backend.query.QueryResults; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/SortByCountIdHolderList.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/SortByCountIdHolderList.java index eeac978672..e9b85bd257 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/SortByCountIdHolderList.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/page/SortByCountIdHolderList.java @@ -22,9 +22,9 @@ import java.util.Map; import java.util.Set; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.page.IdHolder.FixedIdHolder; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.util.CollectionUtil; import org.apache.hugegraph.util.InsertionOrderUtil; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/Aggregate.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/Aggregate.java deleted file mode 100644 index e81f0a9d73..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/Aggregate.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.backend.query; - -import java.util.Iterator; -import java.util.function.BiFunction; - -import org.apache.tinkerpop.gremlin.util.NumberHelper; - -public class Aggregate { - - private final AggregateFunc func; - private final String column; - - public Aggregate(AggregateFunc func, String column) { - this.func = func; - this.column = column; - } - - public AggregateFunc func() { - return this.func; - } - - public String column() { - return this.column; - } - - public boolean countAll() { - return this.func == AggregateFunc.COUNT && this.column == null; - } - - public Number reduce(Iterator results) { - return this.func.reduce(results); - } - - public Number defaultValue() { - return this.func.defaultValue(); - } - - @Override - public String toString() { - return String.format("%s(%s)", this.func.string(), - this.column == null ? "*" : this.column); - } - - public enum AggregateFunc { - - COUNT("count", 0L, NumberHelper::add), - MAX("max", -Double.MAX_VALUE, NumberHelper::max), - MIN("min", Double.MAX_VALUE, NumberHelper::min), - AVG("avg", 0D, NumberHelper::add), - SUM("sum", 0L, NumberHelper::add); - - private final String name; - private final Number defaultValue; - private final BiFunction merger; - - AggregateFunc(String name, Number defaultValue, - BiFunction merger) { - this.name = name; - this.defaultValue = defaultValue; - this.merger = merger; - } - - public String string() { - return this.name; - } - - public Number defaultValue() { - return this.defaultValue; - } - - public Number reduce(Iterator results) { - Number number; - long count = 0L; - if (results.hasNext()) { - number = results.next(); - count++; - } else { - return this.defaultValue; - } - while (results.hasNext()) { - number = this.merger.apply(number, results.next()); - count++; - } - if (this == AVG) { - number = NumberHelper.div(number, count); - } - return number; - } - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/Condition.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/Condition.java deleted file mode 100644 index d956a8ace7..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/Condition.java +++ /dev/null @@ -1,917 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.backend.query; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.function.BiFunction; - -import org.apache.commons.lang.ArrayUtils; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.store.Shard; -import org.apache.hugegraph.structure.HugeElement; -import org.apache.hugegraph.structure.HugeProperty; -import org.apache.hugegraph.type.define.HugeKeys; -import org.apache.hugegraph.util.Bytes; -import org.apache.hugegraph.util.DateUtil; -import org.apache.hugegraph.util.E; -import org.apache.hugegraph.util.NumericUtil; -import org.apache.tinkerpop.gremlin.process.traversal.PBiPredicate; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; - -public abstract class Condition { - - public enum ConditionType { - NONE, - RELATION, - AND, - OR, - NOT - } - - public enum RelationType implements PBiPredicate { - - EQ("==", RelationType::equals), - - GT(">", (v1, v2) -> { - return compare(v1, v2) > 0; - }), - - GTE(">=", (v1, v2) -> { - return compare(v1, v2) >= 0; - }), - - LT("<", (v1, v2) -> { - return compare(v1, v2) < 0; - }), - - LTE("<=", (v1, v2) -> { - return compare(v1, v2) <= 0; - }), - - NEQ("!=", (v1, v2) -> { - return compare(v1, v2) != 0; - }), - - IN("in", null, Collection.class, (v1, v2) -> { - assert v2 != null; - return ((Collection) v2).contains(v1); - }), - - NOT_IN("notin", null, Collection.class, (v1, v2) -> { - assert v2 != null; - return !((Collection) v2).contains(v1); - }), - - PREFIX("prefix", Id.class, Id.class, (v1, v2) -> { - assert v2 != null; - return v1 != null && Bytes.prefixWith(((Id) v2).asBytes(), - ((Id) v1).asBytes()); - }), - - TEXT_CONTAINS("textcontains", String.class, String.class, (v1, v2) -> { - // TODO: support collection-property textcontains - return v1 != null && ((String) v1).contains((String) v2); - }), - - TEXT_CONTAINS_ANY("textcontainsany", String.class, Collection.class, (v1, v2) -> { - assert v2 != null; - if (v1 == null) { - return false; - } - - @SuppressWarnings("unchecked") - Collection words = (Collection) v2; - - for (String word : words) { - if (((String) v1).contains(word)) { - return true; - } - } - return false; - }), - - CONTAINS("contains", Collection.class, null, (v1, v2) -> { - assert v2 != null; - return v1 != null && ((Collection) v1).contains(v2); - }), - - CONTAINS_VALUE("containsv", Map.class, null, (v1, v2) -> { - assert v2 != null; - return v1 != null && ((Map) v1).containsValue(v2); - }), - - CONTAINS_KEY("containsk", Map.class, null, (v1, v2) -> { - assert v2 != null; - return v1 != null && ((Map) v1).containsKey(v2); - }), - - SCAN("scan", (v1, v2) -> { - assert v2 != null; - /* - * TODO: we still have no way to determine accurately for all - * backend scan implementations. - */ - return true; - }); - - private static final Set RANGE_TYPES = - ImmutableSet.of(GT, GTE, LT, LTE); - - private static final Set UNFLATTEN_TYPES = - ImmutableSet.of(IN, NOT_IN, TEXT_CONTAINS_ANY); - - private final String operator; - private final BiFunction tester; - private final Class v1Class; - private final Class v2Class; - - RelationType(String op, - BiFunction tester) { - this(op, null, null, tester); - } - - RelationType(String op, Class v1Class, Class v2Class, - BiFunction tester) { - this.operator = op; - this.tester = tester; - this.v1Class = v1Class; - this.v2Class = v2Class; - } - - public String string() { - return this.operator; - } - - @Override - public String getPredicateName() { - return this.operator; - } - - /** - * Determine two values of any type equal - * - * @param first is actual value - * @param second is value in query condition - * @return true if equal, otherwise false - */ - private static boolean equals(final Object first, - final Object second) { - assert second != null; - if (first instanceof Id) { - if (second instanceof String) { - return second.equals(((Id) first).asString()); - } else if (second instanceof Long) { - return second.equals(((Id) first).asLong()); - } - } else if (second instanceof Number) { - return compare(first, second) == 0; - } else if (second.getClass().isArray()) { - return ArrayUtils.isEquals(first, second); - } - - return Objects.equals(first, second); - } - - /** - * Determine two numbers equal - * - * @param first is actual value, might be Number/Date or String, It is - * probably that the `first` is serialized to String. - * @param second is value in query condition, must be Number/Date/Boolean - * @return the value 0 if first is numerically equal to second; - * a value less than 0 if first is numerically less than - * second; and a value greater than 0 if first is - * numerically greater than second. - */ - private static int compare(final Object first, final Object second) { - assert second != null; - if (second instanceof Number) { - return NumericUtil.compareNumber(first == null ? 0 : first, - (Number) second); - } else if (second instanceof Date) { - return compareDate(first, (Date) second); - } else if (second instanceof Boolean) { - return compareBoolean(first, (Boolean) second); - } - - throw new IllegalArgumentException(String.format( - "Can't compare between %s(%s) and %s(%s)", first, - first == null ? null : first.getClass().getSimpleName(), - second, second.getClass().getSimpleName())); - } - - private static int compareDate(Object first, Date second) { - if (first == null) { - first = DateUtil.DATE_ZERO; - } - if (first instanceof Date) { - return ((Date) first).compareTo(second); - } - - throw new IllegalArgumentException(String.format( - "Can't compare between %s(%s) and %s(%s)", - first, first.getClass().getSimpleName(), - second, second.getClass().getSimpleName())); - } - - private static int compareBoolean(Object first, Boolean second) { - if (first instanceof Boolean) { - return Boolean.compare((Boolean) first, second); - } - - throw new IllegalArgumentException(String.format( - "Can't compare between %s(%s) and %s(%s)", - first, first == null ? null : - first.getClass().getSimpleName(), - second, second.getClass().getSimpleName())); - } - - private void checkBaseType(Object value, Class clazz) { - if (!clazz.isInstance(value)) { - String valueClass = value == null ? "null" : - value.getClass().getSimpleName(); - E.checkArgument(false, - "Can't execute `%s` on type %s, expect %s", - this.operator, valueClass, - clazz.getSimpleName()); - } - } - - private void checkValueType(Object value, Class clazz) { - if (!clazz.isInstance(value)) { - String valueClass = value == null ? "null" : - value.getClass().getSimpleName(); - E.checkArgument(false, - "Can't test '%s'(%s) for `%s`, expect %s", - value, valueClass, this.operator, - clazz.getSimpleName()); - } - } - - @Override - public boolean test(Object first, Object second) { - E.checkState(this.tester != null, "Can't test %s", this.name()); - E.checkArgument(second != null, - "Can't test null value for `%s`", this.operator); - if (this.v1Class != null) { - this.checkBaseType(first, this.v1Class); - } - if (this.v2Class != null) { - this.checkValueType(second, this.v2Class); - } - return this.tester.apply(first, second); - } - - public boolean isRangeType() { - return RANGE_TYPES.contains(this); - } - - public boolean isSearchType() { - return this == TEXT_CONTAINS || this == TEXT_CONTAINS_ANY; - } - - public boolean isSecondaryType() { - return this == EQ; - } - } - - public abstract ConditionType type(); - - public abstract boolean isSysprop(); - - public abstract List relations(); - - public abstract boolean test(Object value); - - public abstract boolean test(HugeElement element); - - public abstract Condition copy(); - - public abstract Condition replace(Relation from, Relation to); - - public Condition and(Condition other) { - return new And(this, other); - } - - public Condition or(Condition other) { - return new Or(this, other); - } - - public boolean isRelation() { - return this.type() == ConditionType.RELATION; - } - - public boolean isLogic() { - return this.type() == ConditionType.AND || - this.type() == ConditionType.OR || - this.type() == ConditionType.NOT; - } - - public boolean isFlattened() { - return this.isRelation(); - } - - public static Condition and(Condition left, Condition right) { - return new And(left, right); - } - - public static Condition or(Condition left, Condition right) { - return new Or(left, right); - } - - public static Condition not(Condition condition) { - return new Not(condition); - } - - public static Relation eq(HugeKeys key, Object value) { - return new SyspropRelation(key, RelationType.EQ, value); - } - - public static Relation gt(HugeKeys key, Object value) { - return new SyspropRelation(key, RelationType.GT, value); - } - - public static Relation gte(HugeKeys key, Object value) { - return new SyspropRelation(key, RelationType.GTE, value); - } - - public static Relation lt(HugeKeys key, Object value) { - return new SyspropRelation(key, RelationType.LT, value); - } - - public static Relation lte(HugeKeys key, Object value) { - return new SyspropRelation(key, RelationType.LTE, value); - } - - public static Relation neq(HugeKeys key, Object value) { - return new SyspropRelation(key, RelationType.NEQ, value); - } - - public static Condition in(HugeKeys key, List value) { - return new SyspropRelation(key, RelationType.IN, value); - } - - public static Condition nin(HugeKeys key, List value) { - return new SyspropRelation(key, RelationType.NOT_IN, value); - } - - public static Condition prefix(HugeKeys key, Id value) { - return new SyspropRelation(key, RelationType.PREFIX, value); - } - - public static Condition containsValue(HugeKeys key, Object value) { - return new SyspropRelation(key, RelationType.CONTAINS_VALUE, value); - } - - public static Condition containsKey(HugeKeys key, Object value) { - return new SyspropRelation(key, RelationType.CONTAINS_KEY, value); - } - - public static Condition contains(HugeKeys key, Object value) { - return new SyspropRelation(key, RelationType.CONTAINS, value); - } - - public static Condition scan(String start, String end) { - Shard value = new Shard(start, end, 0); - return new SyspropRelation(HugeKeys.ID, RelationType.SCAN, value); - } - - public static Relation eq(Id key, Object value) { - return new UserpropRelation(key, RelationType.EQ, value); - } - - public static Relation gt(Id key, Object value) { - return new UserpropRelation(key, RelationType.GT, value); - } - - public static Relation gte(Id key, Object value) { - return new UserpropRelation(key, RelationType.GTE, value); - } - - public static Relation lt(Id key, Object value) { - return new UserpropRelation(key, RelationType.LT, value); - } - - public static Relation lte(Id key, Object value) { - return new UserpropRelation(key, RelationType.LTE, value); - } - - public static Relation neq(Id key, Object value) { - return new UserpropRelation(key, RelationType.NEQ, value); - } - - public static Relation in(Id key, List value) { - return new UserpropRelation(key, RelationType.IN, value); - } - - public static Relation nin(Id key, List value) { - return new UserpropRelation(key, RelationType.NOT_IN, value); - } - - public static Relation textContains(Id key, String word) { - return new UserpropRelation(key, RelationType.TEXT_CONTAINS, word); - } - - public static Relation textContainsAny(Id key, Set words) { - return new UserpropRelation(key, RelationType.TEXT_CONTAINS_ANY, words); - } - - public static Condition contains(Id key, Object value) { - return new UserpropRelation(key, RelationType.CONTAINS, value); - } - - /** - * Condition defines - */ - public abstract static class BinCondition extends Condition { - - private Condition left; - private Condition right; - - public BinCondition(Condition left, Condition right) { - E.checkNotNull(left, "left condition"); - E.checkNotNull(right, "right condition"); - this.left = left; - this.right = right; - } - - public Condition left() { - return this.left; - } - - public Condition right() { - return this.right; - } - - @Override - public boolean isSysprop() { - return this.left.isSysprop() && this.right.isSysprop(); - } - - @Override - public List relations() { - List list = new ArrayList<>(this.left.relations()); - list.addAll(this.right.relations()); - return list; - } - - @Override - public Condition replace(Relation from, Relation to) { - this.left = this.left.replace(from, to); - this.right = this.right.replace(from, to); - return this; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(64); - sb.append(this.left).append(' '); - sb.append(this.type().name()).append(' '); - sb.append(this.right); - return sb.toString(); - } - - @Override - public boolean equals(Object object) { - if (!(object instanceof BinCondition)) { - return false; - } - BinCondition other = (BinCondition) object; - return this.type().equals(other.type()) && - this.left().equals(other.left()) && - this.right().equals(other.right()); - } - - @Override - public int hashCode() { - return this.type().hashCode() ^ - this.left().hashCode() ^ - this.right().hashCode(); - } - } - - public static class And extends BinCondition { - - public And(Condition left, Condition right) { - super(left, right); - } - - @Override - public ConditionType type() { - return ConditionType.AND; - } - - @Override - public boolean test(Object value) { - return this.left().test(value) && this.right().test(value); - } - - @Override - public boolean test(HugeElement element) { - return this.left().test(element) && this.right().test(element); - } - - @Override - public Condition copy() { - return new And(this.left().copy(), this.right().copy()); - } - } - - public static class Or extends BinCondition { - - public Or(Condition left, Condition right) { - super(left, right); - } - - @Override - public ConditionType type() { - return ConditionType.OR; - } - - @Override - public boolean test(Object value) { - return this.left().test(value) || this.right().test(value); - } - - @Override - public boolean test(HugeElement element) { - return this.left().test(element) || this.right().test(element); - } - - @Override - public Condition copy() { - return new Or(this.left().copy(), this.right().copy()); - } - } - - public static class Not extends Condition { - - Condition condition; - - public Not(Condition condition) { - super(); - this.condition = condition; - } - - public Condition condition() { - return condition; - } - - @Override - public ConditionType type() { - return ConditionType.NOT; - } - - @Override - public boolean test(Object value) { - return !this.condition.test(value); - } - - @Override - public boolean test(HugeElement element) { - return !this.condition.test(element); - } - - @Override - public Condition copy() { - return new Not(this.condition.copy()); - } - - @Override - public boolean isSysprop() { - return this.condition.isSysprop(); - } - - @Override - public List relations() { - return new ArrayList(this.condition.relations()); - } - - @Override - public Condition replace(Relation from, Relation to) { - this.condition = this.condition.replace(from, to); - return this; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(64); - sb.append(this.type().name()).append(' '); - sb.append(this.condition); - return sb.toString(); - } - - @Override - public boolean equals(Object object) { - if (!(object instanceof Not)) { - return false; - } - Not other = (Not) object; - return this.type().equals(other.type()) && - this.condition.equals(other.condition()); - } - - @Override - public int hashCode() { - return this.type().hashCode() ^ - this.condition.hashCode(); - } - } - - public abstract static class Relation extends Condition { - - // Relational operator (like: =, >, <, in, ...) - protected RelationType relation; - // Single-type value or a list of single-type value - protected Object value; - - // The key serialized(code/string) by backend store. - protected Object serialKey; - // The value serialized(code/string) by backend store. - protected Object serialValue; - - @Override - public ConditionType type() { - return ConditionType.RELATION; - } - - public RelationType relation() { - return this.relation; - } - - public Object value() { - return this.value; - } - - public void value(Object value) { - this.value = value; - } - - public void serialKey(Object key) { - this.serialKey = key; - } - - public Object serialKey() { - return this.serialKey != null ? this.serialKey : this.key(); - } - - public void serialValue(Object value) { - this.serialValue = value; - } - - public Object serialValue() { - return this.serialValue != null ? this.serialValue : this.value(); - } - - @Override - public boolean test(Object value) { - return this.relation.test(value, this.value()); - } - - @Override - public boolean isFlattened() { - return !RelationType.UNFLATTEN_TYPES.contains(this.relation); - } - - @Override - public List relations() { - return ImmutableList.of(this); - } - - @Override - public Condition replace(Relation from, Relation to) { - if (this == from) { - return to; - } else { - return this; - } - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(64); - sb.append(this.key()).append(' '); - sb.append(this.relation.string()).append(' '); - sb.append(this.value); - return sb.toString(); - } - - @Override - public boolean equals(Object object) { - if (!(object instanceof Relation)) { - return false; - } - Relation other = (Relation) object; - return this.relation().equals(other.relation()) && - this.key().equals(other.key()) && - this.value().equals(other.value()); - } - - @Override - public int hashCode() { - return this.type().hashCode() ^ - this.relation().hashCode() ^ - this.key().hashCode() ^ - this.value().hashCode(); - } - - @Override - public abstract boolean isSysprop(); - - public abstract Object key(); - - @Override - public abstract Relation copy(); - } - - public static class SyspropRelation extends Relation { - - private final HugeKeys key; - - public SyspropRelation(HugeKeys key, Object value) { - this(key, RelationType.EQ, value); - } - - public SyspropRelation(HugeKeys key, RelationType op, Object value) { - E.checkNotNull(op, "relation type"); - this.key = key; - this.relation = op; - this.value = value; - } - - @Override - public HugeKeys key() { - return this.key; - } - - @Override - public boolean isSysprop() { - return true; - } - - @Override - public boolean test(HugeElement element) { - E.checkNotNull(element, "element"); - Object value = element.sysprop(this.key); - return this.relation.test(value, this.value()); - } - - @Override - public Relation copy() { - Relation clone = new SyspropRelation(this.key, this.relation(), - this.value); - clone.serialKey(this.serialKey); - clone.serialValue(this.serialValue); - return clone; - } - } - - public static class FlattenSyspropRelation extends SyspropRelation { - - public FlattenSyspropRelation(SyspropRelation relation) { - super(relation.key(), relation.relation(), relation.value()); - } - - @Override - public boolean isFlattened() { - return true; - } - } - - public static class UserpropRelation extends Relation { - - // Id of property key - private final Id key; - - public UserpropRelation(Id key, Object value) { - this(key, RelationType.EQ, value); - } - - public UserpropRelation(Id key, RelationType op, Object value) { - E.checkNotNull(op, "relation type"); - this.key = key; - this.relation = op; - this.value = value; - } - - @Override - public Id key() { - return this.key; - } - - @Override - public boolean isSysprop() { - return false; - } - - @Override - public boolean test(HugeElement element) { - HugeProperty prop = element.getProperty(this.key); - Object value = prop != null ? prop.value() : null; - if (value == null) { - /* - * Fix #611 - * TODO: It's possible some scenes can't be returned false - * directly, such as: EQ with p1 == null, it should be returned - * true, but the query has(p, null) is not allowed by - * TraversalUtil.validPredicateValue(). - */ - return false; - } - return this.relation.test(value, this.value()); - } - - @Override - public Relation copy() { - Relation clone = new UserpropRelation(this.key, this.relation(), - this.value); - clone.serialKey(this.serialKey); - clone.serialValue(this.serialValue); - return clone; - } - } - - public static class RangeConditions { - - private Object keyEq = null; - private Object keyMin = null; - private boolean keyMinEq = false; - private Object keyMax = null; - private boolean keyMaxEq = false; - - public RangeConditions(List conditions) { - for (Condition c : conditions) { - Relation r = (Relation) c; - switch (r.relation()) { - case EQ: - this.keyEq = r.value(); - break; - case GTE: - this.keyMinEq = true; - this.keyMin = r.value(); - break; - case GT: - this.keyMin = r.value(); - break; - case LTE: - this.keyMaxEq = true; - this.keyMax = r.value(); - break; - case LT: - this.keyMax = r.value(); - break; - default: - E.checkArgument(false, "Unsupported relation '%s'", - r.relation()); - } - } - } - - public Object keyEq() { - return this.keyEq; - } - - public Object keyMin() { - return this.keyMin; - } - - public Object keyMax() { - return this.keyMax; - } - - public boolean keyMinEq() { - return this.keyMinEq; - } - - public boolean keyMaxEq() { - return this.keyMaxEq; - } - - public boolean hasRange() { - return this.keyMin != null || this.keyMax != null; - } - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQuery.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQuery.java deleted file mode 100644 index 6da8da23db..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQuery.java +++ /dev/null @@ -1,971 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.backend.query; - -import java.math.BigDecimal; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.SplicingIdGenerator; -import org.apache.hugegraph.backend.query.Condition.Relation; -import org.apache.hugegraph.backend.query.Condition.RelationType; -import org.apache.hugegraph.backend.query.serializer.QueryAdapter; -import org.apache.hugegraph.backend.query.serializer.QueryIdAdapter; -import org.apache.hugegraph.perf.PerfUtil.Watched; -import org.apache.hugegraph.structure.HugeElement; -import org.apache.hugegraph.structure.HugeProperty; -import org.apache.hugegraph.type.HugeType; -import org.apache.hugegraph.type.define.HugeKeys; -import org.apache.hugegraph.util.CollectionUtil; -import org.apache.hugegraph.util.E; -import org.apache.hugegraph.util.InsertionOrderUtil; -import org.apache.hugegraph.util.LongEncoding; -import org.apache.hugegraph.util.NumericUtil; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - -public class ConditionQuery extends IdQuery { - - public static final char INDEX_SYM_MIN = '\u0000'; - public static final String INDEX_SYM_ENDING = "\u0000"; - public static final String INDEX_SYM_NULL = "\u0001"; - public static final String INDEX_SYM_EMPTY = "\u0002"; - public static final char INDEX_SYM_MAX = '\u0003'; - - // Note: here we use "new String" to distinguish normal string code - public static final String INDEX_VALUE_NULL = ""; - public static final String INDEX_VALUE_EMPTY = ""; - - public static final Set IGNORE_SYM_SET; - - static { - List list = new ArrayList<>(INDEX_SYM_MAX - INDEX_SYM_MIN); - for (char ch = INDEX_SYM_MIN; ch <= INDEX_SYM_MAX; ch++) { - list.add(String.valueOf(ch)); - } - IGNORE_SYM_SET = ImmutableSet.copyOf(list); - } - - private static final List EMPTY_CONDITIONS = ImmutableList.of(); - - private static final Gson gson = new GsonBuilder() - .registerTypeAdapter(Condition.class, new QueryAdapter()) - .registerTypeAdapter(Id.class, new QueryIdAdapter()) - .setDateFormat("yyyy-MM-dd HH:mm:ss.SSS") - .create(); - - // Conditions will be contacted with `and` by default - private List conditions = EMPTY_CONDITIONS; - - private OptimizedType optimizedType = OptimizedType.NONE; - private ResultsFilter resultsFilter = null; - private Element2IndexValueMap element2IndexValueMap = null; - - public ConditionQuery(HugeType resultType) { - super(resultType); - } - - public ConditionQuery(HugeType resultType, Query originQuery) { - super(resultType, originQuery); - } - - public ConditionQuery query(Condition condition) { - // Query by id (HugeGraph-259) - if (condition instanceof Relation) { - Relation relation = (Relation) condition; - if (relation.key().equals(HugeKeys.ID) && - relation.relation() == RelationType.EQ) { - E.checkArgument(relation.value() instanceof Id, - "Invalid id value '%s'", relation.value()); - super.query((Id) relation.value()); - return this; - } - } - - if (this.conditions == EMPTY_CONDITIONS) { - this.conditions = InsertionOrderUtil.newList(); - } - this.conditions.add(condition); - return this; - } - - public ConditionQuery query(List conditions) { - for (Condition condition : conditions) { - this.query(condition); - } - return this; - } - - public ConditionQuery eq(HugeKeys key, Object value) { - // Filter value by key - return this.query(Condition.eq(key, value)); - } - - public ConditionQuery gt(HugeKeys key, Object value) { - return this.query(Condition.gt(key, value)); - } - - public ConditionQuery gte(HugeKeys key, Object value) { - return this.query(Condition.gte(key, value)); - } - - public ConditionQuery lt(HugeKeys key, Object value) { - return this.query(Condition.lt(key, value)); - } - - public ConditionQuery lte(HugeKeys key, Object value) { - return this.query(Condition.lte(key, value)); - } - - public ConditionQuery neq(HugeKeys key, Object value) { - return this.query(Condition.neq(key, value)); - } - - public ConditionQuery prefix(HugeKeys key, Id value) { - return this.query(Condition.prefix(key, value)); - } - - public ConditionQuery key(HugeKeys key, Object value) { - return this.query(Condition.containsKey(key, value)); - } - - public ConditionQuery scan(String start, String end) { - return this.query(Condition.scan(start, end)); - } - - @Override - public int conditionsSize() { - return this.conditions.size(); - } - - @Override - public Collection conditions() { - return Collections.unmodifiableList(this.conditions); - } - - public void resetConditions(List conditions) { - this.conditions = conditions; - } - - public void resetConditions() { - this.conditions = EMPTY_CONDITIONS; - } - - public void recordIndexValue(Id propertyId, Id id, Object indexValue) { - this.element2IndexValueMap().addIndexValue(propertyId, id, indexValue); - } - - public void selectedIndexField(Id indexField) { - this.element2IndexValueMap().selectedIndexField(indexField); - } - - public void removeElementLeftIndex(Id elementId) { - if (this.element2IndexValueMap == null) { - return; - } - this.element2IndexValueMap.removeElementLeftIndex(elementId); - } - - public boolean existLeftIndex(Id elementId) { - return this.getLeftIndexOfElement(elementId) != null; - } - - public Set getLeftIndexOfElement(Id elementId) { - if (this.element2IndexValueMap == null) { - return null; - } - return this.element2IndexValueMap.getLeftIndex(elementId); - } - - private Element2IndexValueMap element2IndexValueMap() { - if (this.element2IndexValueMap == null) { - this.element2IndexValueMap = new Element2IndexValueMap(); - } - return this.element2IndexValueMap; - } - - public List relations() { - List relations = new ArrayList<>(); - for (Condition c : this.conditions) { - relations.addAll(c.relations()); - } - return relations; - } - - public Relation relation(Id key) { - for (Relation r : this.relations()) { - if (r.key().equals(key)) { - return r; - } - } - return null; - } - - public boolean containsLabelOrUserpropRelation() { - for (Condition c : this.conditions) { - while (c instanceof Condition.Not) { - c = ((Condition.Not) c).condition(); - } - if (c.isLogic()) { - Condition.BinCondition binCondition = - (Condition.BinCondition) c; - ConditionQuery query = new ConditionQuery(HugeType.EDGE); - query.query(binCondition.left()); - query.query(binCondition.right()); - if (query.containsLabelOrUserpropRelation()) { - return true; - } - } else { - Condition.Relation r = (Condition.Relation) c; - if (r.key().equals(HugeKeys.LABEL) || - c instanceof Condition.UserpropRelation) { - return true; - } - } - } - return false; - } - - @Watched - public T condition(Object key) { - List valuesEQ = InsertionOrderUtil.newList(); - List valuesIN = InsertionOrderUtil.newList(); - for (Condition c : this.conditions) { - if (c.isRelation()) { - Condition.Relation r = (Condition.Relation) c; - if (r.key().equals(key)) { - if (r.relation() == RelationType.EQ) { - valuesEQ.add(r.value()); - } else if (r.relation() == RelationType.IN) { - Object value = r.value(); - assert value instanceof List; - valuesIN.add(value); - } - } - } - } - if (valuesEQ.isEmpty() && valuesIN.isEmpty()) { - return null; - } - if (valuesEQ.size() == 1 && valuesIN.isEmpty()) { - @SuppressWarnings("unchecked") - T value = (T) valuesEQ.get(0); - return value; - } - if (valuesEQ.isEmpty() && valuesIN.size() == 1) { - @SuppressWarnings("unchecked") - T value = (T) valuesIN.get(0); - return value; - } - - boolean initialized = false; - Set intersectValues = InsertionOrderUtil.newSet(); - for (Object value : valuesEQ) { - List valueAsList = ImmutableList.of(value); - if (!initialized) { - intersectValues.addAll(valueAsList); - initialized = true; - } else { - CollectionUtil.intersectWithModify(intersectValues, - valueAsList); - } - } - for (Object value : valuesIN) { - @SuppressWarnings("unchecked") - List valueAsList = (List) value; - if (!initialized) { - intersectValues.addAll(valueAsList); - initialized = true; - } else { - CollectionUtil.intersectWithModify(intersectValues, - valueAsList); - } - } - - if (intersectValues.isEmpty()) { - return null; - } - E.checkState(intersectValues.size() == 1, - "Illegal key '%s' with more than one value: %s", - key, intersectValues); - @SuppressWarnings("unchecked") - T value = (T) intersectValues.iterator().next(); - return value; - } - - public void unsetCondition(Object key) { - this.conditions.removeIf(c -> c.isRelation() && ((Relation) c).key().equals(key)); - } - - public boolean containsCondition(HugeKeys key) { - for (Condition c : this.conditions) { - if (c.isRelation()) { - Condition.Relation r = (Condition.Relation) c; - if (r.key().equals(key)) { - return true; - } - } - } - return false; - } - - public boolean containsCondition(Condition.RelationType type) { - for (Relation r : this.relations()) { - if (r.relation().equals(type)) { - return true; - } - } - return false; - } - - public boolean containsScanCondition() { - return this.containsCondition(Condition.RelationType.SCAN); - } - - public boolean containsRelation(HugeKeys key, Condition.RelationType type) { - for (Relation r : this.relations()) { - if (r.key().equals(key) && r.relation().equals(type)) { - return true; - } - } - return false; - } - - public boolean containsRelation(Condition.RelationType type) { - for (Relation r : this.relations()) { - if (r.relation().equals(type)) { - return true; - } - } - return false; - } - - public boolean containsScanRelation() { - return this.containsRelation(Condition.RelationType.SCAN); - } - - public boolean containsContainsCondition(Id key) { - for (Relation r : this.relations()) { - if (r.key().equals(key)) { - return r.relation().equals(RelationType.CONTAINS) || - r.relation().equals(RelationType.TEXT_CONTAINS); - } - } - return false; - } - - public boolean allSysprop() { - for (Condition c : this.conditions) { - if (!c.isSysprop()) { - return false; - } - } - return true; - } - - public boolean allRelation() { - for (Condition c : this.conditions) { - if (!c.isRelation()) { - return false; - } - } - return true; - } - - public List syspropConditions() { - this.checkFlattened(); - List conds = new ArrayList<>(); - for (Condition c : this.conditions) { - if (c.isSysprop()) { - conds.add(c); - } - } - return conds; - } - - public List syspropConditions(HugeKeys key) { - this.checkFlattened(); - List conditions = new ArrayList<>(); - for (Condition condition : this.conditions) { - Relation relation = (Relation) condition; - if (relation.key().equals(key)) { - conditions.add(relation); - } - } - return conditions; - } - - public List userpropConditions() { - this.checkFlattened(); - List conds = new ArrayList<>(); - for (Condition c : this.conditions) { - if (!c.isSysprop()) { - conds.add(c); - } - } - return conds; - } - - public List userpropConditions(Id key) { - this.checkFlattened(); - List conditions = new ArrayList<>(); - for (Condition condition : this.conditions) { - Relation relation = (Relation) condition; - if (relation.key().equals(key)) { - conditions.add(relation); - } - } - return conditions; - } - - public List userpropRelations() { - List relations = new ArrayList<>(); - for (Relation r : this.relations()) { - if (!r.isSysprop()) { - relations.add(r); - } - } - return relations; - } - - public void resetUserpropConditions() { - this.conditions.removeIf(condition -> !condition.isSysprop()); - } - - public Set userpropKeys() { - Set keys = new LinkedHashSet<>(); - for (Relation r : this.relations()) { - if (!r.isSysprop()) { - Condition.UserpropRelation ur = (Condition.UserpropRelation) r; - keys.add(ur.key()); - } - } - return keys; - } - - /** - * This method is only used for secondary index scenario, - * its relation must be EQ - * - * @param fields the user property fields - * @return the corresponding user property serial values of fields - */ - public String userpropValuesString(List fields) { - List values = new ArrayList<>(fields.size()); - for (Id field : fields) { - boolean got = false; - for (Relation r : this.userpropRelations()) { - if (r.key().equals(field) && !r.isSysprop()) { - E.checkState(r.relation == RelationType.EQ || - r.relation == RelationType.CONTAINS, - "Method userpropValues(List) only " + - "used for secondary index, " + - "relation must be EQ or CONTAINS, but got %s", - r.relation()); - values.add(r.serialValue()); - got = true; - } - } - if (!got) { - throw new BackendException( - "No such userprop named '%s' in the query '%s'", - field, this); - } - } - return concatValues(values); - } - - public Set userpropValues(Id field) { - Set values = new HashSet<>(); - for (Relation r : this.userpropRelations()) { - if (r.key().equals(field)) { - values.add(r.serialValue()); - } - } - return values; - } - - public Object userpropValue(Id field) { - Set values = this.userpropValues(field); - if (values.isEmpty()) { - return null; - } - E.checkState(values.size() == 1, - "Expect one user-property value of field '%s', " + - "but got '%s'", field, values.size()); - return values.iterator().next(); - } - - public boolean hasRangeCondition() { - // NOTE: we need to judge all the conditions, including the nested - for (Condition.Relation r : this.relations()) { - if (r.relation().isRangeType()) { - return true; - } - } - return false; - } - - public boolean hasSearchCondition() { - // NOTE: we need to judge all the conditions, including the nested - for (Condition.Relation r : this.relations()) { - if (r.relation().isSearchType()) { - return true; - } - } - return false; - } - - public boolean hasSecondaryCondition() { - // NOTE: we need to judge all the conditions, including the nested - for (Condition.Relation r : this.relations()) { - if (r.relation().isSecondaryType()) { - return true; - } - } - return false; - } - - public boolean hasNeqCondition() { - // NOTE: we need to judge all the conditions, including the nested - for (Condition.Relation r : this.relations()) { - if (r.relation() == RelationType.NEQ) { - return true; - } - } - return false; - } - - public boolean matchUserpropKeys(List keys) { - Set conditionKeys = this.userpropKeys(); - return !keys.isEmpty() && conditionKeys.containsAll(keys); - } - - @Override - public ConditionQuery copy() { - ConditionQuery query = (ConditionQuery) super.copy(); - query.originQuery(this); - if (query.conditions != EMPTY_CONDITIONS) { - query.conditions = InsertionOrderUtil.newList(this.conditions); - } - query.optimizedType = OptimizedType.NONE; - query.resultsFilter = null; - - return query; - } - - public ConditionQuery copyAndResetUnshared() { - ConditionQuery query = this.copy(); - // These fields should not be shared by multiple sub-query - query.optimizedType = OptimizedType.NONE; - query.resultsFilter = null; - return query; - } - - public Condition.Relation copyRelationAndUpdateQuery(Object key) { - Condition.Relation copyRes = null; - for (int i = 0; i < this.conditions.size(); i++) { - Condition c = this.conditions.get(i); - if (c.isRelation()) { - Condition.Relation r = (Condition.Relation) c; - if (r.key().equals(key)) { - copyRes = r.copy(); - this.conditions.set(i, copyRes); - break; - } - } - } - E.checkArgument(copyRes != null, "Failed to copy Condition.Relation: %s", key); - return copyRes; - } - - @Override - public boolean test(HugeElement element) { - return this.test(element, this.resultsFilter); - } - - public boolean test(HugeElement element, ResultsFilter filter) { - if (!this.ids().isEmpty() && !super.test(element)) { - return false; - } - - /* - * Currently results-filter is used to filter unmatched results returned - * by search index, and there may be multiple results-filter for every - * sub-query like within() + Text.contains(). - * We can't use sub-query results-filter here for fresh element which is - * not committed to backend store, because it's not from a sub-query. - */ - if (filter != null && !element.fresh()) { - return filter.test(element); - } - - /* - * NOTE: seems need to keep call checkRangeIndex() for each condition, - * so don't break early even if test() return false. - */ - boolean valid = true; - Map rangeIndexMatches = null; - if (this.element2IndexValueMap != null) { - rangeIndexMatches = new HashMap<>(); - } - for (Condition cond : this.conditions) { - valid &= cond.test(element); - if (this.element2IndexValueMap != null) { - valid &= this.element2IndexValueMap.checkRangeIndex( - element, cond, rangeIndexMatches); - } - } - return valid; - } - - public void checkFlattened() { - E.checkState(this.isFlattened(), - "Query has none-flatten condition: %s", this); - } - - public boolean isFlattened() { - for (Condition condition : this.conditions) { - if (!condition.isFlattened()) { - return false; - } - } - return true; - } - - public boolean mayHasDupKeys(Set keys) { - Map keyCounts = new HashMap<>(); - for (Condition condition : this.conditions) { - if (!condition.isRelation()) { - // Assume may exist duplicate keys when has nested conditions - return true; - } - Relation relation = (Relation) condition; - if (keys.contains(relation.key())) { - int keyCount = keyCounts.getOrDefault(relation.key(), 0); - if (++keyCount > 1) { - return true; - } - keyCounts.put((HugeKeys) relation.key(), keyCount); - } - } - return false; - } - - public void optimized(OptimizedType optimizedType) { - assert this.optimizedType.ordinal() <= optimizedType.ordinal() : - this.optimizedType + " !<= " + optimizedType; - this.optimizedType = optimizedType; - - Query originQuery = this.originQuery(); - if (originQuery instanceof ConditionQuery) { - ConditionQuery cq = ((ConditionQuery) originQuery); - /* - * Two sub-query(flatten) will both set optimized of originQuery, - * here we just keep the higher one, this may not be a perfect way - */ - if (optimizedType.ordinal() > cq.optimized().ordinal()) { - cq.optimized(optimizedType); - } - } - } - - public OptimizedType optimized() { - return this.optimizedType; - } - - public void registerResultsFilter(ResultsFilter filter) { - assert this.resultsFilter == null; - this.resultsFilter = filter; - } - - ResultsFilter resultsFilter() { - return this.resultsFilter; - } - - public ConditionQuery originConditionQuery() { - Query originQuery = this.originQuery(); - if (!(originQuery instanceof ConditionQuery)) { - return null; - } - - while (originQuery.originQuery() instanceof ConditionQuery) { - originQuery = originQuery.originQuery(); - } - return (ConditionQuery) originQuery; - } - - public static String concatValues(List values) { - assert !values.isEmpty(); - List newValues = new ArrayList<>(values.size()); - for (Object v : values) { - newValues.add(concatValues(v)); - } - return SplicingIdGenerator.concatValues(newValues); - } - - public static String concatValues(Object value) { - if (value instanceof String) { - return escapeSpecialValueIfNeeded((String) value); - } - if (value instanceof List) { - return concatValues((List) value); - } else if (needConvertNumber(value)) { - return LongEncoding.encodeNumber(value); - } else { - return escapeSpecialValueIfNeeded(value.toString()); - } - } - - public static ConditionQuery fromBytes(byte[] bytes) { - Gson gson = new GsonBuilder() - .registerTypeAdapter(Condition.class, new QueryAdapter()) - .registerTypeAdapter(Id.class, new QueryIdAdapter()) - .setDateFormat("yyyy-MM-dd HH:mm:ss.SSS") - .create(); - String cqs = new String(bytes, StandardCharsets.UTF_8); - ConditionQuery conditionQuery = gson.fromJson(cqs, ConditionQuery.class); - - return conditionQuery; - } - - private static boolean needConvertNumber(Object value) { - // Numeric or date values should be converted to number from string - return NumericUtil.isNumber(value) || value instanceof Date; - } - - private static String escapeSpecialValueIfNeeded(String value) { - if (value.isEmpty()) { - // Escape empty String to INDEX_SYM_EMPTY (char `\u0002`) - value = INDEX_SYM_EMPTY; - } else if (value == INDEX_VALUE_EMPTY) { - value = ""; - } else if (value == INDEX_VALUE_NULL) { - value = INDEX_SYM_NULL; - } else { - char ch = value.charAt(0); - if (ch <= INDEX_SYM_MAX) { - /* - * Special symbols can't be used due to impossible to parse, - * and treat it as illegal value for the origin text property. - * TODO: escape special symbols - */ - E.checkArgument(false, - "Illegal leading char '\\u%s' " + - "in index property: '%s'", - (int) ch, value); - } - } - return value; - } - - public enum OptimizedType { - NONE, - PRIMARY_KEY, - SORT_KEYS, - INDEX, - INDEX_FILTER - } - - public static final class Element2IndexValueMap { - - private final Map> leftIndexMap; - private final Map>> filed2IndexValues; - private Id selectedIndexField; - - public Element2IndexValueMap() { - this.filed2IndexValues = new HashMap<>(); - this.leftIndexMap = new HashMap<>(); - } - - public void addIndexValue(Id indexField, Id elementId, - Object indexValue) { - if (!this.filed2IndexValues.containsKey(indexField)) { - this.filed2IndexValues.putIfAbsent(indexField, new HashMap<>()); - } - Map> element2IndexValueMap = - this.filed2IndexValues.get(indexField); - if (element2IndexValueMap.containsKey(elementId)) { - element2IndexValueMap.get(elementId).add(indexValue); - } else { - element2IndexValueMap.put(elementId, - Sets.newHashSet(indexValue)); - } - } - - public void selectedIndexField(Id indexField) { - this.selectedIndexField = indexField; - } - - public Set toRemoveIndexValues(Id indexField, Id elementId) { - if (!this.filed2IndexValues.containsKey(indexField)) { - return null; - } - return this.filed2IndexValues.get(indexField).get(elementId); - } - - public void addLeftIndex(Id elementId, Id indexField, - Set indexValues) { - LeftIndex leftIndex = new LeftIndex(indexValues, indexField); - if (this.leftIndexMap.containsKey(elementId)) { - this.leftIndexMap.get(elementId).add(leftIndex); - } else { - this.leftIndexMap.put(elementId, Sets.newHashSet(leftIndex)); - } - } - - public Set getLeftIndex(Id elementId) { - return this.leftIndexMap.get(elementId); - } - - public void removeElementLeftIndex(Id elementId) { - this.leftIndexMap.remove(elementId); - } - - public boolean checkRangeIndex(HugeElement element, Condition cond, - Map rangeIndexMatches) { - // Not UserpropRelation - if (!(cond instanceof Condition.UserpropRelation)) { - return true; - } - - Condition.UserpropRelation propRelation = - (Condition.UserpropRelation) cond; - Id propId = propRelation.key(); - Set fieldValues = this.toRemoveIndexValues(propId, - element.id()); - if (fieldValues == null) { - // Not range index - return true; - } - - if (rangeIndexMatches.containsKey(propId)) { - return rangeIndexMatches.get(propId); - } - - HugeProperty property = element.getProperty(propId); - if (property == null) { - // Property value has been deleted, so it's not matched - this.addLeftIndex(element.id(), propId, fieldValues); - return this.cacheRangeIndexMatch(rangeIndexMatches, propId, - false); - } - - /* - * NOTE: If removing successfully means there is correct index, - * else we should add left-index values to left index map to - * wait the left-index to be removed. - */ - boolean hasRightValue = removeFieldValue(fieldValues, - property.value()); - if (!fieldValues.isEmpty()) { - this.addLeftIndex(element.id(), propId, fieldValues); - } - - /* - * NOTE: When query by more than one range index field, - * if current field is not the selected one, it can only be used to - * determine whether the index values matched, can't determine - * the element is valid or not. - */ - if (this.selectedIndexField != null) { - hasRightValue = !propId.equals(this.selectedIndexField) || - hasRightValue; - } - - return this.cacheRangeIndexMatch(rangeIndexMatches, propId, - hasRightValue); - } - - private boolean cacheRangeIndexMatch(Map rangeIndexMatches, - Id propertyId, - boolean matched) { - rangeIndexMatches.put(propertyId, matched); - return matched; - } - - private static boolean removeFieldValue(Set values, - Object value) { - for (Object elem : values) { - if (numberEquals(elem, value)) { - values.remove(elem); - return true; - } - } - return false; - } - - private static boolean numberEquals(Object number1, Object number2) { - // Same class compare directly - if (number1.getClass().equals(number2.getClass())) { - return number1.equals(number2); - } - - // Otherwise convert to BigDecimal to make two numbers comparable - Number n1 = NumericUtil.convertToNumber(number1); - Number n2 = NumericUtil.convertToNumber(number2); - BigDecimal b1 = BigDecimal.valueOf(n1.doubleValue()); - BigDecimal b2 = BigDecimal.valueOf(n2.doubleValue()); - return b1.compareTo(b2) == 0; - } - } - - public static final class LeftIndex { - - private final Set indexFieldValues; - private final Id indexField; - - public LeftIndex(Set indexFieldValues, Id indexField) { - this.indexFieldValues = indexFieldValues; - this.indexField = indexField; - } - - public Set indexFieldValues() { - return this.indexFieldValues; - } - - public Id indexField() { - return this.indexField; - } - } - - public interface ResultsFilter { - - boolean test(HugeElement element); - } - - public byte[] bytes() { - String cqs = gson.toJson(this); - return cqs.getBytes(StandardCharsets.UTF_8); - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQueryFlatten.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQueryFlatten.java index 649f88e7b3..1cc91be0d1 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQueryFlatten.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQueryFlatten.java @@ -26,9 +26,12 @@ import java.util.Set; import java.util.stream.Collectors; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.Condition.Relation; -import org.apache.hugegraph.backend.query.Condition.SyspropRelation; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.Condition.Relation; +import org.apache.hugegraph.query.Condition.SyspropRelation; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.type.define.HugeKeys; import org.apache.hugegraph.util.E; import org.apache.hugegraph.util.InsertionOrderUtil; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/EdgesQueryIterator.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/EdgesQueryIterator.java index d8bce082c6..99c436b289 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/EdgesQueryIterator.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/EdgesQueryIterator.java @@ -20,8 +20,10 @@ import java.util.Iterator; import java.util.List; -import org.apache.hugegraph.backend.id.Id; import org.apache.hugegraph.backend.tx.GraphTransaction; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.type.define.Directions; public class EdgesQueryIterator implements Iterator { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/IdQuery.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/IdQuery.java deleted file mode 100644 index f7a1c732b3..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/IdQuery.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.backend.query; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Set; - -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.structure.HugeElement; -import org.apache.hugegraph.type.HugeType; -import org.apache.hugegraph.util.E; -import org.apache.hugegraph.util.InsertionOrderUtil; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; - -public class IdQuery extends Query { - - private static final List EMPTY_IDS = ImmutableList.of(); - - // The id(s) will be concated with `or` - private List ids = EMPTY_IDS; - private boolean mustSortByInput = true; - - public IdQuery(HugeType resultType) { - super(resultType); - } - - public IdQuery(HugeType resultType, Query originQuery) { - super(resultType, originQuery); - } - - public IdQuery(HugeType resultType, Set ids) { - this(resultType); - this.query(ids); - } - - public IdQuery(HugeType resultType, Id id) { - this(resultType); - this.query(id); - } - - public IdQuery(Query originQuery, Id id) { - this(originQuery.resultType(), originQuery); - this.query(id); - } - - public IdQuery(Query originQuery, Set ids) { - this(originQuery.resultType(), originQuery); - this.query(ids); - } - - public boolean mustSortByInput() { - return this.mustSortByInput; - } - - public void mustSortByInput(boolean mustSortedByInput) { - this.mustSortByInput = mustSortedByInput; - } - - @Override - public int idsSize() { - return this.ids.size(); - } - - @Override - public Collection ids() { - return Collections.unmodifiableList(this.ids); - } - - public void resetIds() { - this.ids = EMPTY_IDS; - } - - public IdQuery query(Id id) { - E.checkArgumentNotNull(id, "Query id can't be null"); - if (this.ids == EMPTY_IDS) { - this.ids = InsertionOrderUtil.newList(); - } - - int last = this.ids.size() - 1; - if (last >= 0 && id.equals(this.ids.get(last))) { - // The same id as the previous one, just ignore it - return this; - } - - this.ids.add(id); - this.checkCapacity(this.ids.size()); - return this; - } - - public IdQuery query(Set ids) { - for (Id id : ids) { - this.query(id); - } - return this; - } - - @Override - public boolean test(HugeElement element) { - return this.ids.contains(element.id()); - } - - @Override - public IdQuery copy() { - IdQuery query = (IdQuery) super.copy(); - query.ids = this.ids == EMPTY_IDS ? EMPTY_IDS : - InsertionOrderUtil.newList(this.ids); - return query; - } - - public static final class OneIdQuery extends IdQuery { - - private Id id; - - public OneIdQuery(HugeType resultType, Id id) { - super(resultType); - super.mustSortByInput = false; - this.id = id; - } - - public OneIdQuery(Query originQuery, Id id) { - super(originQuery.resultType(), originQuery); - super.mustSortByInput = false; - this.id = id; - } - - public Id id() { - return this.id; - } - - public void resetId(Id id) { - this.id = id; - } - - @Override - public int idsSize() { - return this.id == null ? 0 : 1; - } - - @Override - public Set ids() { - return this.id == null ? ImmutableSet.of() : - ImmutableSet.of(this.id); - } - - @Override - public void resetIds() { - this.id = null; - } - - @Override - public IdQuery query(Id id) { - E.checkArgumentNotNull(id, "Query id can't be null"); - this.id = id; - return this; - } - - @Override - public boolean test(HugeElement element) { - if (this.id == null) { - return true; - } - return this.id.equals(element.id()); - } - - @Override - public IdQuery copy() { - OneIdQuery query = (OneIdQuery) super.copy(); - assert this.id.equals(query.id); - return query; - } - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/Query.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/Query.java deleted file mode 100644 index b8fc8e2964..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/Query.java +++ /dev/null @@ -1,655 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.backend.query; - -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.Aggregate.AggregateFunc; -import org.apache.hugegraph.exception.LimitExceedException; -import org.apache.hugegraph.structure.HugeElement; -import org.apache.hugegraph.type.HugeType; -import org.apache.hugegraph.type.define.CollectionType; -import org.apache.hugegraph.type.define.HugeKeys; -import org.apache.hugegraph.util.CollectionUtil; -import org.apache.hugegraph.util.E; -import org.apache.hugegraph.util.InsertionOrderUtil; -import org.apache.hugegraph.util.collection.IdSet; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; - -public class Query implements Cloneable { - - // TODO: we should better not use Long.Max as the unify limit number - public static final long NO_LIMIT = Long.MAX_VALUE; - - public static final long COMMIT_BATCH = 500L; - public static final long QUERY_BATCH = 100L; - - public static final long NO_CAPACITY = -1L; - public static final long DEFAULT_CAPACITY = 800000L; // HugeGraph-777 - - private static final ThreadLocal CAPACITY_CONTEXT = new ThreadLocal<>(); - - protected static final Query NONE = new Query(HugeType.UNKNOWN); - - private static final Set EMPTY_OLAP_PKS = ImmutableSet.of(); - - private HugeType resultType; - private Map orders; - private long offset; - private long actualOffset; - private long actualStoreOffset; - private long limit; - private long skipDegree; - private String page; - private long capacity; - private boolean showHidden; - private boolean showDeleting; - private boolean showExpired; - private boolean olap; - private boolean withProperties; - private OrderType orderType; - private Set olapPks; - - private Aggregate aggregate; - - private Query originQuery; - - public Query(HugeType resultType) { - this(resultType, null); - } - - public Query(HugeType resultType, Query originQuery) { - this.resultType = resultType; - this.originQuery = originQuery; - - this.orders = null; - - this.offset = 0L; - this.actualOffset = 0L; - this.actualStoreOffset = 0L; - this.limit = NO_LIMIT; - this.skipDegree = NO_LIMIT; - this.page = null; - - this.capacity = defaultCapacity(); - - this.showHidden = false; - this.showDeleting = false; - - this.withProperties = true; - this.orderType = OrderType.ORDER_STRICT; - - this.aggregate = null; - this.showExpired = false; - this.olap = false; - this.olapPks = EMPTY_OLAP_PKS; - } - - public void copyBasic(Query query) { - E.checkNotNull(query, "query"); - this.offset = query.offset(); - this.limit = query.limit(); - this.skipDegree = query.skipDegree(); - this.page = query.page(); - this.capacity = query.capacity(); - this.showHidden = query.showHidden(); - this.showDeleting = query.showDeleting(); - this.withProperties = query.withProperties(); - this.orderType = query.orderType(); - this.aggregate = query.aggregate(); - this.showExpired = query.showExpired(); - this.olap = query.olap(); - if (query.orders != null) { - this.orders(query.orders); - } - } - - public HugeType resultType() { - return this.resultType; - } - - public void resultType(HugeType resultType) { - this.resultType = resultType; - } - - public Query originQuery() { - return this.originQuery; - } - - public void setOriginQuery(Query query) { - this.originQuery = query; - } - - public Query rootOriginQuery() { - Query root = this; - while (root.originQuery != null) { - root = root.originQuery; - } - return root; - } - - protected void originQuery(Query originQuery) { - this.originQuery = originQuery; - } - - public Map orders() { - return Collections.unmodifiableMap(this.getOrNewOrders()); - } - - public void orders(Map orders) { - this.orders = InsertionOrderUtil.newMap(orders); - } - - public void order(HugeKeys key, Order order) { - this.getOrNewOrders().put(key, order); - } - - protected Map getOrNewOrders() { - if (this.orders != null) { - return this.orders; - } - this.orders = InsertionOrderUtil.newMap(); - return this.orders; - } - - public long offset() { - return this.offset; - } - - public void offset(long offset) { - if (offset < 0L) { - E.checkArgument(false, "Invalid offset %s", offset); - } - this.offset = offset; - } - - public void copyOffset(Query parent) { - assert this.offset == 0L || this.offset == parent.offset; - assert this.actualOffset == 0L || - this.actualOffset == parent.actualOffset; - this.offset = parent.offset; - this.actualOffset = parent.actualOffset; - } - - public long actualOffset() { - return this.actualOffset; - } - - public void resetActualOffset() { - this.actualOffset = 0L; - this.actualStoreOffset = 0L; - } - - public long goOffset(long offset) { - if (offset < 0L) { - E.checkArgument(false, "Invalid offset value: %s", offset); - } - if (this.originQuery != null) { - this.goParentOffset(offset); - } - return this.goSelfOffset(offset); - } - - private void goParentOffset(long offset) { - assert offset >= 0L; - Query parent = this.originQuery; - while (parent != null) { - parent.actualOffset += offset; - parent = parent.originQuery; - } - } - - private long goSelfOffset(long offset) { - assert offset >= 0L; - if (this.originQuery != null) { - this.originQuery.goStoreOffsetBySubQuery(offset); - } - this.actualOffset += offset; - return this.actualOffset; - } - - private long goStoreOffsetBySubQuery(long offset) { - Query parent = this.originQuery; - while (parent != null) { - parent.actualStoreOffset += offset; - parent = parent.originQuery; - } - this.actualStoreOffset += offset; - return this.actualStoreOffset; - } - - public Set skipOffsetIfNeeded(Set elems) { - /* - * Skip index(index query with offset) for performance optimization. - * We assume one result is returned by each index, but if there are - * overridden index it will cause confusing offset and results. - */ - long fromIndex = this.offset() - this.actualOffset(); - if (fromIndex < 0L) { - // Skipping offset is overhead, no need to skip - fromIndex = 0L; - } - // An index holder yields ids in batches, only count this batch's ids - fromIndex = Math.min(fromIndex, elems.size()); - if (fromIndex > 0L) { - this.goOffset(fromIndex); - } - - if (fromIndex >= elems.size()) { - return ImmutableSet.of(); - } - long toIndex = this.total(); - if (this.noLimit() || toIndex > elems.size()) { - toIndex = elems.size(); - } - if (fromIndex == 0L && toIndex == elems.size()) { - return elems; - } - assert fromIndex < elems.size(); - assert toIndex <= elems.size(); - return CollectionUtil.subSet(elems, (int) fromIndex, (int) toIndex); - } - - public long remaining() { - if (this.limit == NO_LIMIT) { - return NO_LIMIT; - } else { - return this.total() - this.actualOffset(); - } - } - - public long total() { - if (this.limit == NO_LIMIT) { - return NO_LIMIT; - } else { - return this.offset + this.limit; - } - } - - public long limit() { - if (this.capacity != NO_CAPACITY) { - if (this.limit == NO_LIMIT) { - /* - * TODO: may need to return this.capacity here. - * In most cases, capacity == DEFAULT_CAPACITY, then limit() - * will return NO_LIMIT, thus rely on Query.checkCapacity() - * to check in the next step. - */ - } - if (this.limit != NO_LIMIT && this.limit > this.capacity) { - E.checkArgument(false, - "Invalid limit %s, must be <= capacity(%s)", - this.limit, this.capacity); - } - } - return this.limit; - } - - public void limit(long limit) { - if (limit != NO_LIMIT && limit < 0L) { - E.checkArgument(false, "Invalid limit %s", limit); - } - this.limit = limit; - } - - public boolean noLimit() { - return this.limit() == NO_LIMIT; - } - - public boolean noLimitAndOffset() { - return this.limit() == NO_LIMIT && this.offset() == 0L; - } - - public boolean reachLimit(long count) { - long limit = this.limit(); - if (limit == NO_LIMIT) { - return false; - } - return count >= (limit + this.offset()); - } - - /** - * Set or update the offset and limit by a range [start, end) - * NOTE: it will use the min range one: max start and min end - * - * @param start the range start, include it - * @param end the range end, exclude it - */ - public long range(long start, long end) { - // Update offset - long offset = this.offset(); - start = Math.max(start, offset); - this.offset(start); - - // Update limit - if (end != -1L) { - if (!this.noLimit()) { - end = Math.min(end, offset + this.limit()); - } else { - assert end < Query.NO_LIMIT; - } - if (end < start) { - E.checkArgument(false, "Invalid range: [%s, %s)", start, end); - } - this.limit(end - start); - } else { - // Keep the origin limit - assert this.limit() <= Query.NO_LIMIT; - } - return this.limit; - } - - public String page() { - if (this.page != null) { - if (this.limit() == 0L) { - E.checkState(false, - "Can't set limit=0 when using paging"); - } - if (this.offset() != 0L) { - E.checkState(false, - "Can't set offset when using paging, but got '%s'", - this.offset()); - } - } - return this.page; - } - - public String pageWithoutCheck() { - return this.page; - } - - public void page(String page) { - this.page = page; - } - - public boolean paging() { - return this.page != null; - } - - public void olap(boolean olap) { - this.olap = olap; - } - - public boolean olap() { - return this.olap; - } - - public void olapPks(Set olapPks) { - for (Id olapPk : olapPks) { - this.olapPk(olapPk); - } - } - - public void olapPk(Id olapPk) { - if (this.olapPks == EMPTY_OLAP_PKS) { - this.olapPks = new IdSet(CollectionType.EC); - } - this.olapPks.add(olapPk); - } - - public Set olapPks() { - return this.olapPks; - } - - public long capacity() { - return this.capacity; - } - - public void capacity(long capacity) { - this.capacity = capacity; - } - - public boolean bigCapacity() { - return this.capacity == NO_CAPACITY || this.capacity > DEFAULT_CAPACITY; - } - - public void checkCapacity(long count) throws LimitExceedException { - // Throw LimitExceedException if reach capacity - if (this.capacity != NO_CAPACITY && count > this.capacity) { - final int MAX_CHARS = 256; - String query = this.toString(); - if (query.length() > MAX_CHARS) { - query = query.substring(0, MAX_CHARS) + "..."; - } - throw new LimitExceedException( - "Too many records(must <= %s) for the query: %s", - this.capacity, query); - } - } - - public Aggregate aggregate() { - return this.aggregate; - } - - public Aggregate aggregateNotNull() { - if (this.aggregate == null) { - E.checkArgument(false, - "The aggregate must be set for number query"); - } - return this.aggregate; - } - - public void aggregate(AggregateFunc func, String property) { - this.aggregate = new Aggregate(func, property); - } - - public void aggregate(Aggregate aggregate) { - this.aggregate = aggregate; - } - - public boolean showHidden() { - return this.showHidden; - } - - public void showHidden(boolean showHidden) { - this.showHidden = showHidden; - } - - public boolean showDeleting() { - return this.showDeleting; - } - - public void showDeleting(boolean showDeleting) { - this.showDeleting = showDeleting; - } - - public long skipDegree() { - return this.skipDegree; - } - - public void skipDegree(long skipDegree) { - this.skipDegree = skipDegree; - } - - public boolean withProperties() { - return this.withProperties; - } - - public void withProperties(boolean withProperties) { - this.withProperties = withProperties; - } - - public OrderType orderType() { - return this.orderType; - } - - public void orderType(OrderType orderType) { - this.orderType = orderType; - } - - public boolean showExpired() { - return this.showExpired; - } - - public void showExpired(boolean showExpired) { - this.showExpired = showExpired; - } - - public Collection ids() { - return ImmutableList.of(); - } - - public Collection conditions() { - return ImmutableList.of(); - } - - public int idsSize() { - return 0; - } - - public int conditionsSize() { - return 0; - } - - public boolean empty() { - return this.idsSize() == 0 && this.conditionsSize() == 0; - } - - public boolean test(HugeElement element) { - return true; - } - - public Query copy() { - try { - return (Query) this.clone(); - } catch (CloneNotSupportedException e) { - throw new BackendException(e); - } - } - - @Override - public boolean equals(Object object) { - if (!(object instanceof Query)) { - return false; - } - Query other = (Query) object; - return this.resultType.equals(other.resultType) && - this.orders().equals(other.orders()) && - this.offset == other.offset && - this.limit == other.limit && - Objects.equals(this.page, other.page) && - this.ids().equals(other.ids()) && - this.conditions().equals(other.conditions()) && - this.withProperties == other.withProperties; - } - - @Override - public int hashCode() { - return this.resultType.hashCode() ^ - this.orders().hashCode() ^ - Long.hashCode(this.offset) ^ - Long.hashCode(this.limit) ^ - Objects.hashCode(this.page) ^ - this.ids().hashCode() ^ - this.conditions().hashCode() ^ - Boolean.hashCode(this.withProperties); - } - - @Override - public String toString() { - Map pairs = InsertionOrderUtil.newMap(); - if (this.page != null) { - pairs.put("page", String.format("'%s'", this.page)); - } - if (this.offset != 0) { - pairs.put("offset", this.offset); - } - if (this.limit != NO_LIMIT) { - pairs.put("limit", this.limit); - } - if (!this.orders().isEmpty()) { - pairs.put("order by", this.orders()); - } - - StringBuilder sb = new StringBuilder(128); - sb.append("`Query "); - if (this.aggregate != null) { - sb.append(this.aggregate); - } else { - sb.append('*'); - } - sb.append(" from ").append(this.resultType); - for (Map.Entry entry : pairs.entrySet()) { - sb.append(' ').append(entry.getKey()) - .append(' ').append(entry.getValue()).append(','); - } - if (!pairs.isEmpty()) { - // Delete last comma - sb.deleteCharAt(sb.length() - 1); - } - - if (!this.empty()) { - sb.append(" where"); - } - - // Append ids - if (!this.ids().isEmpty()) { - sb.append(" id in ").append(this.ids()); - } - - // Append conditions - if (!this.conditions().isEmpty()) { - if (!this.ids().isEmpty()) { - sb.append(" and"); - } - sb.append(" ").append(this.conditions()); - } - - sb.append('`'); - return sb.toString(); - } - - public static long defaultCapacity(long capacity) { - Long old = CAPACITY_CONTEXT.get(); - CAPACITY_CONTEXT.set(capacity); - return old != null ? old : DEFAULT_CAPACITY; - } - - public static long defaultCapacity() { - Long capacity = CAPACITY_CONTEXT.get(); - return capacity != null ? capacity : DEFAULT_CAPACITY; - } - - public static void checkForceCapacity(long count) throws LimitExceedException { - if (count > Query.DEFAULT_CAPACITY) { - throw new LimitExceedException( - "Too many records(must <= %s) for one query", - Query.DEFAULT_CAPACITY); - } - } - - public enum OrderType { - // Under batch interface, the requirement for return order - ORDER_NONE, // Allow unordered - ORDER_WITHIN_VERTEX, // Edges within a vertex will not be broken, but there is no order between different vertices. - ORDER_STRICT // Ensure the original input point order - } - - public enum Order { - ASC, - DESC - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/QueryBatch.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/QueryBatch.java index f210a503a2..58088a9263 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/QueryBatch.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/QueryBatch.java @@ -25,10 +25,11 @@ import java.util.function.BiPredicate; import java.util.function.Function; -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.exception.HugeException; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.iterator.CIter; import org.apache.hugegraph.iterator.Metadatable; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.type.Idfiable; import org.apache.hugegraph.util.InsertionOrderUtil; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/QueryResultContext.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/QueryResultContext.java index 27e6ec67ae..6392981e50 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/QueryResultContext.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/QueryResultContext.java @@ -21,9 +21,12 @@ import java.util.Collections; import java.util.List; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.ConditionQuery.OptimizedType; -import org.apache.hugegraph.backend.query.ConditionQuery.ResultsFilter; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.ConditionQuery.OptimizedType; +import org.apache.hugegraph.query.ConditionQuery.ResultsFilter; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.IdQuery; +import org.apache.hugegraph.query.Query; /** Decisions captured for one batch; queries retain shared index cleanup data. */ public final class QueryResultContext { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/QueryResults.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/QueryResults.java index 35675bcf35..ce68722408 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/QueryResults.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/QueryResults.java @@ -25,17 +25,21 @@ import java.util.function.BiPredicate; import java.util.function.Function; -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.backend.id.Id; import org.apache.hugegraph.backend.query.QueryBatch.BatchIterator; +import org.apache.hugegraph.exception.HugeException; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.iterator.CIter; import org.apache.hugegraph.iterator.ListIterator; import org.apache.hugegraph.perf.PerfUtil.Watched; +import org.apache.hugegraph.query.Query; +import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.Idfiable; /** A lazy stream of query batches. Only the final consumer flattens the stream. */ public class QueryResults { + private static final Query EMPTY_QUERY = new Query(HugeType.UNKNOWN); + private final BatchIterator> batches; private final Object metadata; private Iterator results; @@ -346,7 +350,7 @@ public static Iterator iterator(T value) { } public static QueryResults empty() { - return new QueryResults(QueryResults.emptyIterator(), Query.NONE); + return new QueryResults(QueryResults.emptyIterator(), EMPTY_QUERY); } public static Iterator emptyIterator() { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/serializer/AbstractSerializerAdapter.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/serializer/AbstractSerializerAdapter.java deleted file mode 100644 index 1a66ddf074..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/serializer/AbstractSerializerAdapter.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package org.apache.hugegraph.backend.query.serializer; - -import java.lang.reflect.Type; -import java.util.Map; - -import org.apache.hugegraph.backend.BackendException; - -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.JsonPrimitive; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; - -// TODO: optimize by binary protocol -public abstract class AbstractSerializerAdapter implements JsonSerializer, - JsonDeserializer { - - //Note: By overriding the method to get the mapping - public abstract Map validType(); - - @Override - public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws - JsonParseException { - JsonObject object = json.getAsJsonObject(); - String type = object.get("cls").getAsString(); - JsonElement element = object.get("el"); - try { - return context.deserialize(element, validType().get(type)); - } catch (Exception e) { - throw new BackendException("Unknown element type: " + type, e); - } - } - - /* - * Note: Currently, only the first character of the class name is taken as the key - * to reduce serialization results - * */ - @Override - public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) { - JsonObject result = new JsonObject(); - Class clazz = src.getClass(); - result.add("cls", new JsonPrimitive(clazz.getSimpleName().substring(0, 1).toUpperCase())); - result.add("el", context.serialize(src, clazz)); - return result; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/serializer/QueryAdapter.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/serializer/QueryAdapter.java deleted file mode 100644 index 47b7c76a00..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/serializer/QueryAdapter.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package org.apache.hugegraph.backend.query.serializer; - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; - -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.type.define.Directions; - -import com.google.common.collect.ImmutableMap; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.JsonPrimitive; -import com.google.gson.JsonSerializationContext; -import com.google.gson.reflect.TypeToken; - -public class QueryAdapter extends AbstractSerializerAdapter { - - static ImmutableMap cls = - ImmutableMap.builder() - // TODO: uncomment later - .put("N", Condition.Not.class) - .put("A", Condition.And.class) - .put("O", Condition.Or.class) - .put("S", Condition.SyspropRelation.class) - .put("U", Condition.UserpropRelation.class) - .build(); - - static boolean isPrimitive(Class clz) { - try { - return (clz == Date.class) || ((Class) clz.getField("TYPE").get(null)).isPrimitive(); - } catch (Exception e) { - return false; - } - } - - @Override - public Map validType() { - return cls; - } - - @Override - public Condition deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { - Condition condition = super.deserialize(json, typeOfT, context); - if (condition instanceof Condition.Relation) { - JsonObject object = json.getAsJsonObject(); - if (object.has("el")) { - JsonElement elElement = object.get("el"); - JsonElement valueElement = elElement.getAsJsonObject().get("value"); - if (valueElement.isJsonObject()) { - String cls = valueElement.getAsJsonObject().get("cls").getAsString(); - try { - Class actualClass = Class.forName(cls); - Object obj = context.deserialize(valueElement, actualClass); - ((Condition.Relation) condition).value(obj); - } catch (ClassNotFoundException e) { - throw new JsonParseException(e.getMessage()); - } - } else if (elElement.getAsJsonObject().has("valuecls")) { - if (valueElement.isJsonArray()) { - String cls = elElement.getAsJsonObject().get("valuecls").getAsString(); - try { - Class actualClass = Class.forName(cls); - Type type = TypeToken.getParameterized(ArrayList.class, actualClass) - .getType(); - Object value = context.deserialize(valueElement, type); - ((Condition.Relation) condition).value(value); - } catch (ClassNotFoundException e) { - throw new JsonParseException(e.getMessage()); - } - } else { - String cls = elElement.getAsJsonObject().get("valuecls").getAsString(); - try { - Class actualClass = Class.forName(cls); - Object obj = context.deserialize(valueElement, actualClass); - ((Condition.Relation) condition).value(obj); - } catch (ClassNotFoundException e) { - throw new JsonParseException(e.getMessage()); - } - } - - } else if (valueElement.isJsonPrimitive() && - valueElement.getAsJsonPrimitive().isString()) { - switch ((String) ((Condition.Relation) condition).value()) { - case "OUT": - ((Condition.Relation) condition).value(Directions.OUT); - break; - case "IN": - ((Condition.Relation) condition).value(Directions.IN); - break; - default: - break; - } - } - } - } - return condition; - } - - @Override - public JsonElement serialize(Condition src, Type typeOfSrc, JsonSerializationContext context) { - JsonElement result = super.serialize(src, typeOfSrc, context); - if (src instanceof Condition.Relation) { - JsonObject object = result.getAsJsonObject(); - JsonElement valueElement = object.get("el").getAsJsonObject().get("value"); - if (valueElement.isJsonObject()) { - valueElement.getAsJsonObject() - .add("cls", - new JsonPrimitive( - ((Condition.Relation) src).value().getClass().getName())); - } else if (isPrimitive(((Condition.Relation) src).value().getClass())) { - object.get("el").getAsJsonObject() - .add("valuecls", - new JsonPrimitive( - ((Condition.Relation) src).value().getClass().getName())); - } else if (valueElement.isJsonArray()) { - if (((Condition.Relation) src).value() instanceof List) { - String valueCls = - ((List) ((Condition.Relation) src).value()).get(0).getClass().getName(); - object.get("el").getAsJsonObject().add("valuecls", new JsonPrimitive(valueCls)); - } - } - } - return result; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/serializer/QueryIdAdapter.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/serializer/QueryIdAdapter.java deleted file mode 100644 index e7ebaea766..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/serializer/QueryIdAdapter.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package org.apache.hugegraph.backend.query.serializer; - -import java.lang.reflect.Type; -import java.util.Map; - -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.serializer.BinaryBackendEntry; - -import com.google.common.collect.ImmutableMap; - -public class QueryIdAdapter extends AbstractSerializerAdapter { - - static ImmutableMap cls = - ImmutableMap.builder() - .put("E", EdgeId.class) - .put("S", IdGenerator.StringId.class) - .put("L", IdGenerator.LongId.class) - .put("U", IdGenerator.UuidId.class) - .put("O", IdGenerator.ObjectId.class) - .put("B", BinaryBackendEntry.BinaryId.class) - .build(); - - @Override - public Map validType() { - return cls; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/AbstractSerializer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/AbstractSerializer.java index 734cb90426..ce79e5b5aa 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/AbstractSerializer.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/AbstractSerializer.java @@ -18,11 +18,11 @@ package org.apache.hugegraph.backend.serializer; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.IdQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.exception.BackendException; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.IdQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.iterator.CIter; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BinaryBackendEntry.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BinaryBackendEntry.java index 9dfb8b4e5c..50b8b4436d 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BinaryBackendEntry.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BinaryBackendEntry.java @@ -17,19 +17,20 @@ package org.apache.hugegraph.backend.serializer; -import java.nio.ByteBuffer; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.backend.BackendColumn; +import org.apache.hugegraph.backend.BinaryId; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.backend.store.BackendEntryIterator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.type.HugeType; -import org.apache.hugegraph.util.Bytes; import org.apache.hugegraph.util.E; +import org.apache.hugegraph.util.Bytes; public class BinaryBackendEntry implements BackendEntry { @@ -207,79 +208,4 @@ public boolean equals(Object obj) { public int hashCode() { return this.id().hashCode() ^ this.columns.size(); } - - public static class BinaryId implements Id { - - protected byte[] bytes; - protected Id id; - - public BinaryId(byte[] bytes, Id id) { - this.bytes = bytes; - this.id = id; - } - - public Id origin() { - return this.id; - } - - @Override - public IdType type() { - return IdType.UNKNOWN; - } - - @Override - public Object asObject() { - return ByteBuffer.wrap(this.bytes); - } - - @Override - public String asString() { - throw new UnsupportedOperationException(); - } - - @Override - public long asLong() { - throw new UnsupportedOperationException(); - } - - @Override - public int compareTo(Id other) { - return Bytes.compare(this.bytes, other.asBytes()); - } - - @Override - public byte[] asBytes() { - return this.bytes; - } - - public byte[] asBytes(int offset) { - E.checkArgument(offset < this.bytes.length, - "Invalid offset %s, must be < length %s", - offset, this.bytes.length); - return Arrays.copyOfRange(this.bytes, offset, this.bytes.length); - } - - @Override - public int length() { - return this.bytes.length; - } - - @Override - public int hashCode() { - return ByteBuffer.wrap(this.bytes).hashCode(); - } - - @Override - public boolean equals(Object other) { - if (!(other instanceof BinaryId)) { - return false; - } - return Arrays.equals(this.bytes, ((BinaryId) other).bytes); - } - - @Override - public String toString() { - return "0x" + Bytes.toHex(this.bytes); - } - } } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BinaryEntryIterator.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BinaryEntryIterator.java index 1095742681..a499ffa00c 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BinaryEntryIterator.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BinaryEntryIterator.java @@ -20,7 +20,7 @@ import java.util.function.BiFunction; import org.apache.hugegraph.backend.page.PageState; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.backend.store.BackendEntry.BackendIterator; import org.apache.hugegraph.backend.store.BackendEntryIterator; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BinaryScatterSerializer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BinaryScatterSerializer.java index 18b642a001..f69fd703cb 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BinaryScatterSerializer.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BinaryScatterSerializer.java @@ -17,13 +17,15 @@ package org.apache.hugegraph.backend.serializer; +import org.apache.hugegraph.serializer.BytesBuffer; + import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.store.BackendEntry; -import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.config.HugeConfig; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeProperty; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.structure.HugeVertexProperty; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BinarySerializer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BinarySerializer.java index 0bb07760a5..445d028cf7 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BinarySerializer.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BinarySerializer.java @@ -17,7 +17,10 @@ package org.apache.hugegraph.backend.serializer; -import static org.apache.hugegraph.schema.SchemaElement.UNDEF; +import org.apache.hugegraph.serializer.BytesBuffer; +import org.apache.hugegraph.serializer.BytesBuffer.IndexColumnName; +import org.apache.hugegraph.serializer.BytesBuffer.IndexExpiryLayout; +import org.apache.hugegraph.serializer.BinaryElementSerializer; import java.util.Arrays; import java.util.Collection; @@ -27,32 +30,32 @@ import org.apache.commons.lang.NotImplementedException; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.exception.BackendException; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.page.PageState; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.Condition.RangeConditions; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.IdPrefixQuery; -import org.apache.hugegraph.backend.query.IdRangeQuery; -import org.apache.hugegraph.backend.query.Query; -import org.apache.hugegraph.backend.serializer.BinaryBackendEntry.BinaryId; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.Condition.RangeConditions; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.IdPrefixQuery; +import org.apache.hugegraph.query.IdRangeQuery; +import org.apache.hugegraph.query.Query; +import org.apache.hugegraph.backend.BinaryId; import org.apache.hugegraph.backend.store.BackendEntry; -import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.iterator.CIter; import org.apache.hugegraph.iterator.MapperIterator; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeEdgeProperty; import org.apache.hugegraph.structure.HugeElement; -import org.apache.hugegraph.structure.HugeIndex; +import org.apache.hugegraph.structure.Index; import org.apache.hugegraph.structure.HugeProperty; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.structure.HugeVertexProperty; @@ -61,7 +64,6 @@ import org.apache.hugegraph.type.define.Cardinality; import org.apache.hugegraph.type.define.DataType; import org.apache.hugegraph.type.define.Directions; -import org.apache.hugegraph.type.define.EdgeLabelType; import org.apache.hugegraph.type.define.Frequency; import org.apache.hugegraph.type.define.HugeKeys; import org.apache.hugegraph.type.define.IdStrategy; @@ -198,137 +200,55 @@ protected byte[] formatPropertyName(HugeProperty prop) { protected BackendColumn formatProperty(HugeProperty prop) { BytesBuffer buffer = BytesBuffer.allocate(BytesBuffer.BUF_PROPERTY); - buffer.writeProperty(prop.propertyKey(), prop.value()); + buffer.writeSchemaProperty(prop.propertyKey(), prop.value()); return BackendColumn.of(this.formatPropertyName(prop), buffer.bytes()); } protected void parseProperty(Id pkeyId, BytesBuffer buffer, HugeElement owner) { - PropertyKey pkey = owner.graph().propertyKey(pkeyId); - - // Parse value - Object value = buffer.readProperty(pkey); - - // Set properties of vertex/edge - if (pkey.cardinality() == Cardinality.SINGLE) { - owner.addProperty(pkey, value); - } else { - if (!(value instanceof Collection)) { - throw new BackendException( - "Invalid value of non-single property: %s", value); - } - owner.addProperty(pkey, value); - } + BinaryElementSerializer.getInstance().parseSchemaProperty( + owner.graph(), pkeyId, buffer, owner::addProperty); } - protected void formatProperties(Collection> props, - BytesBuffer buffer) { - // Write properties size - buffer.writeVInt(props.size()); - - // Write properties data - for (HugeProperty property : props) { - PropertyKey pkey = property.propertyKey(); - buffer.writeVInt(SchemaElement.schemaId(pkey.id())); - buffer.writeProperty(pkey, property.value()); - } + protected void formatProperties(HugeElement owner, BytesBuffer buffer) { + BinaryElementSerializer.getInstance().formatSchemaProperties(owner.element(), buffer); } protected void parseProperties(BytesBuffer buffer, HugeElement owner) { - int size = buffer.readVInt(); - assert size >= 0; - for (int i = 0; i < size; i++) { - Id pkeyId = IdGenerator.of(buffer.readVInt()); - this.parseProperty(pkeyId, buffer, owner); - } + BinaryElementSerializer.getInstance().parseSchemaProperties( + owner.graph(), buffer, owner::addProperty); } protected void formatExpiredTime(long expiredTime, BytesBuffer buffer) { - buffer.writeVLong(expiredTime); + BinaryElementSerializer.getInstance().formatExpiredTime(expiredTime, buffer); } protected void parseExpiredTime(BytesBuffer buffer, HugeElement element) { - element.expiredTime(buffer.readVLong()); + BinaryElementSerializer.getInstance().parseExpiredTime(buffer, element.element()); } protected byte[] formatEdgeValue(HugeEdge edge) { - int propsCount = edge.sizeOfProperties(); - BytesBuffer buffer = BytesBuffer.allocate(4 + 16 * propsCount); - - // Write edge id - //buffer.writeId(edge.id()); - - // Write edge properties - this.formatProperties(edge.getProperties(), buffer); - - // Write edge expired time if needed - if (edge.hasTtl()) { - this.formatExpiredTime(edge.expiredTime(), buffer); - } - - return buffer.bytes(); + return BinaryElementSerializer.getInstance().formatSchemaEdgeValue(edge.element()); } protected void parseEdge(BackendColumn col, HugeVertex vertex, HugeGraph graph) { - // owner-vertex + dir + edge-label + sort-values + other-vertex - - BytesBuffer buffer = BytesBuffer.wrap(col.name); - if (this.keyWithIdPrefix) { - // Consume owner-vertex id - buffer.readId(); - } - byte type = buffer.read(); - Id labelId = buffer.readId(); - Id subLabelId = buffer.readId(); - String sortValues = buffer.readStringWithEnding(); - Id otherVertexId = buffer.readId(); - - boolean direction = EdgeId.isOutDirectionFromCode(type); - - HugeEdge edge; - if (graph == null) { /* when calculation sinking */ - EdgeLabel edgeLabel = new EdgeLabel(null, subLabelId, UNDEF); - if (subLabelId != labelId) { - edgeLabel.edgeLabelType(EdgeLabelType.SUB); - edgeLabel.fatherId(labelId); - } - edge = HugeEdge.constructEdgeWithoutGraph(vertex, direction, edgeLabel, - sortValues, otherVertexId); - } else { - EdgeLabel edgeLabel = graph.edgeLabelOrNone(subLabelId); - edge = HugeEdge.constructEdge(vertex, direction, edgeLabel, - sortValues, otherVertexId); - } - - // Parse edge-id + edge-properties - buffer = BytesBuffer.wrap(col.value); - - //Id id = buffer.readId(); - - // Parse edge properties - this.parseProperties(buffer, edge); - - // Parse edge expired time if needed - if (edge.hasTtl()) { - this.parseExpiredTime(buffer, edge); - } + EdgeId id = BytesBuffer.wrap(col.name).readEdgeId(this.keyWithIdPrefix, vertex.id()); + EdgeLabel edgeLabel = BinaryElementSerializer.getInstance().edgeLabel(graph, id, vertex.graph()); + boolean direction = id.direction() == Directions.OUT; + HugeEdge edge = graph == null ? + HugeEdge.constructEdgeWithoutGraph(vertex, direction, edgeLabel, + id.sortValues(), id.otherVertexId()) : + HugeEdge.constructEdge(vertex, direction, edgeLabel, + id.sortValues(), id.otherVertexId()); + + BinaryElementSerializer.getInstance().parseSchemaEdgeValue( + edge.graph(), col.value, edge.element(), edge::addProperty); } protected void parseVertex(byte[] value, HugeVertex vertex) { - BytesBuffer buffer = BytesBuffer.wrap(value); - - // Parse vertex label - VertexLabel label = vertex.graph().vertexLabelOrNone(buffer.readId()); - vertex.correctVertexLabel(label); - - // Parse properties - this.parseProperties(buffer, vertex); - - // Parse vertex expired time if needed - if (vertex.hasTtl()) { - this.parseExpiredTime(buffer, vertex); - } + BinaryElementSerializer.getInstance().parseSchemaVertexValue( + vertex.graph(), value, vertex.element(), vertex::addProperty); } protected void parseColumn(BackendColumn col, HugeVertex vertex) { @@ -357,48 +277,32 @@ else if (type == HugeType.SYS_PROPERTY.code()) { } } - protected byte[] formatIndexName(HugeIndex index) { - BytesBuffer buffer; - Id elemId = index.elementId(); - if (!this.indexWithIdPrefix) { - int idLen = 1 + elemId.length(); - buffer = BytesBuffer.allocate(idLen); - } else { - Id indexId = index.id(); - HugeType type = index.type(); - if (!type.isNumericIndex() && indexIdLengthExceedLimit(indexId)) { - indexId = index.hashId(); - } - int idLen = 1 + elemId.length() + 1 + indexId.length(); - buffer = BytesBuffer.allocate(idLen); - // Write index-id - buffer.writeIndexId(indexId, type); - } - // Write element-id - buffer.writeId(elemId); - // Write expired time if needed - if (index.hasTtl()) { - buffer.writeVLong(index.expiredTime()); - } - - return buffer.bytes(); + protected byte[] formatIndexName(Index index) { + return BinaryElementSerializer.getInstance().formatSchemaIndex( + index.type(), index.indexLabelId(), index.fieldValues(), index.elementId(), + this.indexWithIdPrefix, index.hasTtl(), index.expiredTime()).name; } protected void parseIndexName(HugeGraph graph, ConditionQuery query, BinaryBackendEntry entry, - HugeIndex index, Object fieldValues) { + Index index, Object fieldValues) { for (BackendColumn col : entry.columns()) { - if (indexFieldValuesUnmatched(col.value, fieldValues)) { - // Skip if field-values is not matched (just the same hash) + if (!index.type().isLabelIndex() && indexFieldValuesUnmatched(col.value, fieldValues)) { + // User-index hash collision filtering remains an engine adapter. continue; } BytesBuffer buffer = BytesBuffer.wrap(col.name); - if (this.indexWithIdPrefix) { - buffer.readIndexId(index.type()); + IndexColumnName name = buffer.readIndexColumnName( + index.type(), this.indexWithIdPrefix, + index.hasTtl() ? IndexExpiryLayout.REQUIRED : IndexExpiryLayout.NONE); + Long storedLabelExpiry = BinaryElementSerializer.getInstance().storedLabelIndexExpiredTime( + index.type(), buffer.remaining() == 0, col.value); + if (index.type().isLabelIndex() && storedLabelExpiry == null && + indexFieldValuesUnmatched(col.value, fieldValues)) { + continue; } - Id elemId = buffer.readId(); - long expiredTime = index.hasTtl() ? buffer.readVLong() : 0L; - index.elementIds(elemId, expiredTime); + index.elementIds(name.elementId(), storedLabelExpiry == null ? + name.expiredTime() : storedLabelExpiry); } } @@ -414,25 +318,15 @@ public BackendEntry writeVertex(HugeVertex vertex) { return entry; } - int propsCount = vertex.sizeOfProperties(); - BytesBuffer buffer = BytesBuffer.allocate(8 + 16 * propsCount); - - // Write vertex label - buffer.writeId(vertex.schemaLabel().id()); - - // Write all properties of the vertex - this.formatProperties(vertex.getProperties(), buffer); - - // Write vertex expired time if needed + byte[] value = BinaryElementSerializer.getInstance().formatSchemaVertexValue(vertex.element()); if (vertex.hasTtl()) { entry.ttl(vertex.ttl()); - this.formatExpiredTime(vertex.expiredTime(), buffer); } - // Fill column + // Backend-specific column keys and entry TTL remain in the adapter. byte[] name = this.keyWithIdPrefix ? entry.id().asBytes() : BytesBuffer.BYTES_EMPTY; - entry.column(name, buffer.bytes()); + entry.column(name, value); return entry; } @@ -451,8 +345,7 @@ public BackendEntry writeOlapVertex(HugeVertex vertex) { } HugeProperty property = properties.iterator().next(); PropertyKey propertyKey = property.propertyKey(); - buffer.writeVInt(SchemaElement.schemaId(propertyKey.id())); - buffer.writeProperty(propertyKey, property.value()); + BinaryElementSerializer.getInstance().formatSchemaProperty(property.baseProperty(), buffer); // Fill column byte[] name = this.keyWithIdPrefix ? @@ -504,9 +397,8 @@ public HugeVertex readVertex(HugeGraph graph, BackendEntry bytesEntry) { } protected void parseVertexOlap(byte[] value, HugeVertex vertex) { - BytesBuffer buffer = BytesBuffer.wrap(value); - Id pkeyId = IdGenerator.of(buffer.readVInt()); - this.parseProperty(pkeyId, buffer, vertex); + BinaryElementSerializer.getInstance().parseSchemaPropertyRecord( + vertex.graph(), BytesBuffer.wrap(value), vertex::addProperty); } @Override @@ -576,7 +468,7 @@ public CIter readEdges(HugeGraph graph, BackendEntry bytesEntry) { } @Override - public BackendEntry writeIndex(HugeIndex index) { + public BackendEntry writeIndex(Index index) { BinaryBackendEntry entry; if (index.fieldValues() == null && index.elementIds().isEmpty()) { /* @@ -586,20 +478,17 @@ public BackendEntry writeIndex(HugeIndex index) { */ entry = this.formatILDeletion(index); } else { - Id id = index.id(); HugeType type = index.type(); - byte[] value = null; - if (!type.isNumericIndex() && indexIdLengthExceedLimit(id)) { - id = index.hashId(); - // Save field-values as column value if the key is a hash string - value = StringEncoding.encode(index.fieldValues().toString()); - } - + Id id = BinaryElementSerializer.schemaIndexId(type, index.indexLabelId(), index.fieldValues()); + BackendColumn column = + BinaryElementSerializer.getInstance().formatSchemaIndex( + type, index.indexLabelId(), index.fieldValues(), index.elementId(), + this.indexWithIdPrefix, index.hasTtl(), index.expiredTime()); entry = newBackendEntry(type, id); if (index.indexLabel().olap()) { entry.olap(true); } - entry.column(this.formatIndexName(index), value); + entry.columns(column); entry.subId(index.elementId()); if (index.hasTtl()) { @@ -610,7 +499,7 @@ public BackendEntry writeIndex(HugeIndex index) { } @Override - public HugeIndex readIndex(HugeGraph graph, ConditionQuery query, + public Index readIndex(HugeGraph graph, ConditionQuery query, BackendEntry bytesEntry) { if (bytesEntry == null) { return null; @@ -619,7 +508,7 @@ public HugeIndex readIndex(HugeGraph graph, ConditionQuery query, BinaryBackendEntry entry = this.convertEntry(bytesEntry); // NOTE: index id without length prefix byte[] bytes = entry.id().asBytes(); - HugeIndex index = HugeIndex.parseIndexId(graph, entry.type(), bytes); + Index index = Index.parseIndexId(graph, entry.type(), bytes); Object fieldValues = null; if (!index.type().isRangeIndex()) { @@ -871,7 +760,7 @@ private Query writeRangeIndexQuery(ConditionQuery query) { return new IdRangeQuery(query, start, keyMinEq, max, keyMaxEq); } - private BinaryBackendEntry formatILDeletion(HugeIndex index) { + private BinaryBackendEntry formatILDeletion(Index index) { Id id = index.indexLabelId(); BinaryId bid = new BinaryId(id.asBytes(), id); BinaryBackendEntry entry = new BinaryBackendEntry(index.type(), bid); @@ -967,17 +856,14 @@ protected static BinaryId formatIndexId(HugeType type, Id indexLabel, Object fieldValues, boolean equal) { boolean withEnding = type.isRangeIndex() || equal; - Id id = HugeIndex.formatIndexId(type, indexLabel, fieldValues); - if (!type.isNumericIndex() && indexIdLengthExceedLimit(id)) { - id = HugeIndex.formatIndexHashId(type, indexLabel, fieldValues); - } + Id id = BinaryElementSerializer.schemaIndexId(type, indexLabel, fieldValues); BytesBuffer buffer = BytesBuffer.allocate(1 + id.length()); byte[] idBytes = buffer.writeIndexId(id, type, withEnding).bytes(); return new BinaryId(idBytes, id); } protected static boolean indexIdLengthExceedLimit(Id id) { - return id.asBytes().length > BytesBuffer.INDEX_HASH_ID_THRESHOLD; + return BinaryElementSerializer.indexIdLengthExceedLimit(id); } protected static boolean indexFieldValuesUnmatched(byte[] value, diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BytesBuffer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BytesBuffer.java deleted file mode 100644 index faf1508299..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BytesBuffer.java +++ /dev/null @@ -1,1030 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.backend.serializer; - -import java.io.OutputStream; -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.Collection; -import java.util.Date; -import java.util.UUID; - -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.Id.IdType; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.serializer.BinaryBackendEntry.BinaryId; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.type.HugeType; -import org.apache.hugegraph.type.define.Cardinality; -import org.apache.hugegraph.type.define.DataType; -import org.apache.hugegraph.util.Blob; -import org.apache.hugegraph.util.Bytes; -import org.apache.hugegraph.util.E; -import org.apache.hugegraph.util.KryoUtil; -import org.apache.hugegraph.util.StringEncoding; - -/** - * class BytesBuffer is a util for read/write binary - */ -public final class BytesBuffer extends OutputStream { - - public static final int BYTE_LEN = Byte.BYTES; - public static final int SHORT_LEN = Short.BYTES; - public static final int INT_LEN = Integer.BYTES; - public static final int LONG_LEN = Long.BYTES; - public static final int CHAR_LEN = Character.BYTES; - public static final int FLOAT_LEN = Float.BYTES; - public static final int DOUBLE_LEN = Double.BYTES; - public static final int BYTES_LEN = 4; - public static final int BLOB_LEN = 5; - - public static final int UINT8_MAX = ((byte) -1) & 0xff; - public static final int UINT16_MAX = ((short) -1) & 0xffff; - public static final long UINT32_MAX = (-1) & 0xffffffffL; - - // TODO: support user-defined configuration - // NOTE: +1 to let code 0 represent length 1 - public static final int ID_LEN_MAX = 0x3fff + 1; // 16KB - public static final int EID_LEN_MAX = 64 * 1024; - - public static final byte STRING_ENDING_BYTE = (byte) 0x00; - public static final byte STRING_ENDING_BYTE_FF = (byte) 0xff; - - // TODO: support user-defined configuration - public static final long BYTES_LEN_MAX = 10 * Bytes.MB; - public static final long BLOB_LEN_MAX = 1 * Bytes.GB; - - public static final int MAX_PROPERTIES = BytesBuffer.UINT16_MAX; - - // The value must be in range [8, ID_LEN_MAX] - public static final int INDEX_HASH_ID_THRESHOLD = 32; - - public static final int DEFAULT_CAPACITY = 64; - public static final int MAX_BUFFER_CAPACITY = 128 * 1024 * 1024; // 128M - public static final int MAX_BUFFER_CAPACITY_UPPER_BOUND = (int) Bytes.GB; - - public static final int BUF_EDGE_ID = 128; - public static final int BUF_PROPERTY = 64; - - public static final byte[] BYTES_EMPTY = new byte[0]; - - private static volatile Integer maxBufferCapacity; - - private ByteBuffer buffer; - private final boolean resize; - - public BytesBuffer() { - this(DEFAULT_CAPACITY); - } - - public BytesBuffer(int capacity) { - int maxCapacity = maxBufferCapacity(); - if (capacity > maxCapacity) { - E.checkArgument(false, - "Capacity %s exceeds max buffer capacity: %s", - capacity, maxCapacity); - } - this.buffer = ByteBuffer.allocate(capacity); - this.resize = true; - } - - public BytesBuffer(ByteBuffer buffer) { - E.checkNotNull(buffer, "buffer"); - this.buffer = buffer; - this.resize = false; - } - - public static BytesBuffer allocate(int capacity) { - return new BytesBuffer(capacity); - } - - public static BytesBuffer wrap(ByteBuffer buffer) { - return new BytesBuffer(buffer); - } - - public static BytesBuffer wrap(byte[] array) { - return new BytesBuffer(ByteBuffer.wrap(array)); - } - - public static BytesBuffer wrap(byte[] array, int offset, int length) { - return new BytesBuffer(ByteBuffer.wrap(array, offset, length)); - } - - public static int maxBufferCapacity() { - Integer capacity = maxBufferCapacity; - return capacity != null ? capacity : MAX_BUFFER_CAPACITY; - } - - public static synchronized void initMaxBufferCapacity(int capacity) { - initMaxBufferCapacity(capacity, true); - } - - public static synchronized void initMaxBufferCapacity(int capacity, - boolean explicit) { - E.checkArgument(capacity >= DEFAULT_CAPACITY && - capacity <= MAX_BUFFER_CAPACITY_UPPER_BOUND, - "Max buffer capacity must be in range [%s, %s], " + - "but got %s", - DEFAULT_CAPACITY, MAX_BUFFER_CAPACITY_UPPER_BOUND, - capacity); - - if (!explicit) { - return; - } - - if (maxBufferCapacity == null) { - maxBufferCapacity = capacity; - return; - } - - if (maxBufferCapacity == capacity) { - return; - } - - throw new IllegalArgumentException(String.format( - "The process-wide serializer buffer max capacity has been " + - "initialized to %s, but got conflicting value %s", - maxBufferCapacity, capacity)); - } - - public ByteBuffer asByteBuffer() { - return this.buffer; - } - - public BytesBuffer forReadWritten() { - this.buffer.flip(); - return this; - } - - public BytesBuffer forReadAll() { - this.buffer.position(this.buffer.limit()); - return this; - } - - public byte[] array() { - return this.buffer.array(); - } - - public byte[] bytes() { - byte[] bytes = this.buffer.array(); - int position = this.buffer.position(); - if (position == bytes.length) { - return bytes; - } else { - return Arrays.copyOf(bytes, position); - } - } - - public int position() { - return this.buffer.position(); - } - - public BytesBuffer copyFrom(BytesBuffer other) { - this.write(other.bytes()); - return this; - } - - public int remaining() { - return this.buffer.remaining(); - } - - private void require(int size) { - // Does need to resize? - if (this.buffer.remaining() >= size) { - return; - } - // Can't resize for wrapped buffer since will change the origin ref - if (!this.resize) { - E.checkState(false, "Can't resize for wrapped buffer"); - } - - int maxCapacity = maxBufferCapacity(); - long requiredCapacity = (long) this.buffer.position() + size; - if (requiredCapacity > maxCapacity) { - E.checkArgument(false, - "Capacity %s exceeds max buffer capacity: %s", - requiredCapacity, maxCapacity); - } - - // Extra capacity as buffer - long newCapacity = Math.min(requiredCapacity + DEFAULT_CAPACITY, - maxCapacity); - ByteBuffer newBuffer = ByteBuffer.allocate((int) newCapacity); - this.buffer.flip(); - newBuffer.put(this.buffer); - this.buffer = newBuffer; - } - - public BytesBuffer write(byte val) { - require(BYTE_LEN); - this.buffer.put(val); - return this; - } - - @Override - public void write(int val) { - assert val <= UINT8_MAX; - require(BYTE_LEN); - this.buffer.put((byte) val); - } - - @Override - public void write(byte[] val) { - require(BYTE_LEN * val.length); - this.buffer.put(val); - } - - @Override - public void write(byte[] val, int offset, int length) { - require(BYTE_LEN * length); - this.buffer.put(val, offset, length); - } - - public BytesBuffer writeBoolean(boolean val) { - this.write(val ? 1 : 0); - return this; - } - - public BytesBuffer writeChar(char val) { - require(CHAR_LEN); - this.buffer.putChar(val); - return this; - } - - public BytesBuffer writeShort(short val) { - require(SHORT_LEN); - this.buffer.putShort(val); - return this; - } - - public BytesBuffer writeInt(int val) { - require(INT_LEN); - this.buffer.putInt(val); - return this; - } - - public BytesBuffer writeLong(long val) { - require(LONG_LEN); - this.buffer.putLong(val); - return this; - } - - public BytesBuffer writeFloat(float val) { - require(FLOAT_LEN); - this.buffer.putFloat(val); - return this; - } - - public BytesBuffer writeDouble(double val) { - require(DOUBLE_LEN); - this.buffer.putDouble(val); - return this; - } - - public byte peek() { - return this.buffer.get(this.buffer.position()); - } - - public byte peekLast() { - return this.buffer.get(this.buffer.limit() - 1); - } - - public byte read() { - return this.buffer.get(); - } - - public byte[] read(int length) { - byte[] bytes = new byte[length]; - this.buffer.get(bytes); - return bytes; - } - - public boolean readBoolean() { - return this.buffer.get() != 0; - } - - public char readChar() { - return this.buffer.getChar(); - } - - public short readShort() { - return this.buffer.getShort(); - } - - public int readInt() { - return this.buffer.getInt(); - } - - public long readLong() { - return this.buffer.getLong(); - } - - public float readFloat() { - return this.buffer.getFloat(); - } - - public double readDouble() { - return this.buffer.getDouble(); - } - - public BytesBuffer writeBytes(byte[] bytes) { - if (bytes.length > BYTES_LEN_MAX) { - E.checkArgument(false, - "The max length of bytes is %s, but got %s", - BYTES_LEN_MAX, bytes.length); - } - require(BYTES_LEN + bytes.length); - this.writeVInt(bytes.length); - this.write(bytes); - return this; - } - - public byte[] readBytes() { - int length = this.readVInt(); - assert length >= 0; - return this.read(length); - } - - public BytesBuffer writeBigBytes(byte[] bytes) { - if (bytes.length > BLOB_LEN_MAX) { - E.checkArgument(false, - "The max length of bytes is %s, but got %s", - BLOB_LEN_MAX, bytes.length); - } - require(BLOB_LEN + bytes.length); - this.writeVInt(bytes.length); - this.write(bytes); - return this; - } - - public byte[] readBigBytes() { - int length = this.readVInt(); - assert length >= 0; - return this.read(length); - } - - public BytesBuffer writeStringRaw(String val) { - this.write(StringEncoding.encode(val)); - return this; - } - - public BytesBuffer writeString(String val) { - byte[] bytes = StringEncoding.encode(val); - this.writeBytes(bytes); - return this; - } - - public String readString() { - return StringEncoding.decode(this.readBytes()); - } - - public BytesBuffer writeStringWithEnding(String value) { - if (!value.isEmpty()) { - byte[] bytes = StringEncoding.encode(value); - /* - * assert '0x00'/'0xFF' not exist in string index id - * NOTE: - * 0x00 is NULL in UTF8(or ASCII) bytes - * 0xFF is not a valid byte in UTF8 bytes - */ - assert !Bytes.contains(bytes, STRING_ENDING_BYTE_FF) : - "Invalid UTF8 bytes: " + value; - if (Bytes.contains(bytes, STRING_ENDING_BYTE)) { - E.checkArgument(false, "Can't contains byte '0x00' in string: '%s'", value); - } - this.write(bytes); - } - /* - * Choose 0x00 as ending symbol (see #1057) - * The following is out of date: - * A reasonable ending symbol should be 0x00(to ensure order), but - * considering that some backends like PG do not support 0x00 string, - * so choose 0xFF currently. - */ - this.write(STRING_ENDING_BYTE); - return this; - } - - public String readStringWithEnding() { - return StringEncoding.decode(this.readBytesWithEnding()); - } - - public BytesBuffer writeStringToRemaining(String value) { - byte[] bytes = StringEncoding.encode(value); - this.write(bytes); - return this; - } - - public String readStringFromRemaining() { - byte[] bytes = new byte[this.buffer.remaining()]; - this.buffer.get(bytes); - return StringEncoding.decode(bytes); - } - - public BytesBuffer writeUInt8(int val) { - assert val <= UINT8_MAX; - this.write(val); - return this; - } - - public int readUInt8() { - return this.read() & 0x000000ff; - } - - public BytesBuffer writeUInt16(int val) { - assert val <= UINT16_MAX; - this.writeShort((short) val); - return this; - } - - public int readUInt16() { - return this.readShort() & 0x0000ffff; - } - - public BytesBuffer writeUInt32(long val) { - assert val <= UINT32_MAX; - this.writeInt((int) val); - return this; - } - - public long readUInt32() { - return this.readInt() & 0xffffffffL; - } - - public BytesBuffer writeVInt(int value) { - // NOTE: negative numbers are not compressed - if (value > 0x0fffffff || value < 0) { - this.write(0x80 | ((value >>> 28) & 0x7f)); - } - if (value > 0x1fffff || value < 0) { - this.write(0x80 | ((value >>> 21) & 0x7f)); - } - if (value > 0x3fff || value < 0) { - this.write(0x80 | ((value >>> 14) & 0x7f)); - } - if (value > 0x7f || value < 0) { - this.write(0x80 | ((value >>> 7) & 0x7f)); - } - this.write(value & 0x7f); - - return this; - } - - public int readVInt() { - byte leading = this.read(); - if (leading == 0x80) { - E.checkArgument(false, - "Unexpected varint with leading byte '0x%s'", - Bytes.toHex(leading)); - } - int value = leading & 0x7f; - if (leading >= 0) { - assert (leading & 0x80) == 0; - return value; - } - - int i = 1; - for (; i < 5; i++) { - byte b = this.read(); - if (b >= 0) { - value = b | (value << 7); - break; - } else { - value = (b & 0x7f) | (value << 7); - } - } - - if (i >= 5) { - E.checkArgument(false, - "Unexpected varint %s with too many bytes(%s)", - value, i + 1); - } - if (i >= 4 && (leading & 0x70) != 0) { - E.checkArgument(false, - "Unexpected varint %s with leading byte '0x%s'", - value, Bytes.toHex(leading)); - } - return value; - } - - public BytesBuffer writeVLong(long value) { - if (value < 0) { - this.write((byte) 0x81); - } - if (value > 0xffffffffffffffL || value < 0L) { - this.write(0x80 | ((int) (value >>> 56) & 0x7f)); - } - if (value > 0x1ffffffffffffL || value < 0L) { - this.write(0x80 | ((int) (value >>> 49) & 0x7f)); - } - if (value > 0x3ffffffffffL || value < 0L) { - this.write(0x80 | ((int) (value >>> 42) & 0x7f)); - } - if (value > 0x7ffffffffL || value < 0L) { - this.write(0x80 | ((int) (value >>> 35) & 0x7f)); - } - if (value > 0xfffffffL || value < 0L) { - this.write(0x80 | ((int) (value >>> 28) & 0x7f)); - } - if (value > 0x1fffffL || value < 0L) { - this.write(0x80 | ((int) (value >>> 21) & 0x7f)); - } - if (value > 0x3fffL || value < 0L) { - this.write(0x80 | ((int) (value >>> 14) & 0x7f)); - } - if (value > 0x7fL || value < 0L) { - this.write(0x80 | ((int) (value >>> 7) & 0x7f)); - } - this.write((int) value & 0x7f); - - return this; - } - - public long readVLong() { - byte leading = this.read(); - if (leading == 0x80) { - E.checkArgument(false, - "Unexpected varlong with leading byte '0x%s'", - Bytes.toHex(leading)); - } - long value = leading & 0x7fL; - if (leading >= 0) { - assert (leading & 0x80) == 0; - return value; - } - - int i = 1; - for (; i < 10; i++) { - byte b = this.read(); - if (b >= 0) { - value = b | (value << 7); - break; - } else { - value = (b & 0x7f) | (value << 7); - } - } - - if (i >= 10) { - E.checkArgument(false, - "Unexpected varlong %s with too many bytes(%s)", - value, i + 1); - } - if (i >= 9 && (leading & 0x7e) != 0) { - E.checkArgument(false, - "Unexpected varlong %s with leading byte '0x%s'", - value, Bytes.toHex(leading)); - } - return value; - } - - public BytesBuffer writeProperty(PropertyKey pkey, Object value) { - if (pkey.cardinality() == Cardinality.SINGLE) { - this.writeProperty(pkey.dataType(), value); - return this; - } - - assert pkey.cardinality() == Cardinality.LIST || - pkey.cardinality() == Cardinality.SET; - Collection values = (Collection) value; - this.writeVInt(values.size()); - for (Object o : values) { - this.writeProperty(pkey.dataType(), o); - } - return this; - } - - public Object readProperty(PropertyKey pkey) { - if (pkey.cardinality() == Cardinality.SINGLE) { - return this.readProperty(pkey.dataType()); - } - - assert pkey.cardinality() == Cardinality.LIST || - pkey.cardinality() == Cardinality.SET; - int size = this.readVInt(); - Collection values = pkey.newValue(); - for (int i = 0; i < size; i++) { - values.add(this.readProperty(pkey.dataType())); - } - return values; - } - - public void writeProperty(DataType dataType, Object value) { - switch (dataType) { - case BOOLEAN: - this.writeVInt(((Boolean) value) ? 1 : 0); - break; - case BYTE: - this.writeVInt((Byte) value); - break; - case INT: - this.writeVInt((Integer) value); - break; - case FLOAT: - this.writeFloat((Float) value); - break; - case LONG: - this.writeVLong((Long) value); - break; - case DATE: - this.writeVLong(((Date) value).getTime()); - break; - case DOUBLE: - this.writeDouble((Double) value); - break; - case TEXT: - this.writeString((String) value); - break; - case BLOB: - byte[] bytes = value instanceof byte[] ? (byte[]) value : ((Blob) value).bytes(); - this.writeBigBytes(bytes); - break; - case UUID: - UUID uuid = (UUID) value; - // Generally writeVLong(uuid) can't save space - this.writeLong(uuid.getMostSignificantBits()); - this.writeLong(uuid.getLeastSignificantBits()); - break; - default: - // TODO: replace Kryo with Fury (https://github.com/apache/fury) - this.writeBytes(KryoUtil.toKryoWithType(value)); - break; - } - } - - public static byte getType(int value) { - return (byte) (value & 0x3f); - } - - public Object readProperty(DataType dataType) { - switch (dataType) { - case BOOLEAN: - return this.readVInt() == 1; - case BYTE: - return (byte) this.readVInt(); - case INT: - return this.readVInt(); - case FLOAT: - return this.readFloat(); - case LONG: - return this.readVLong(); - case DATE: - return new Date(this.readVLong()); - case DOUBLE: - return this.readDouble(); - case TEXT: - return this.readString(); - case BLOB: - return Blob.wrap(this.readBigBytes()); - case UUID: - return new UUID(this.readLong(), this.readLong()); - default: - // TODO: replace Kryo with Fury (https://github.com/apache/fury) - return KryoUtil.fromKryoWithType(this.readBytes()); - } - } - - public BytesBuffer writeId(Id id) { - switch (id.type()) { - case LONG: - // Number Id - long value = id.asLong(); - this.writeNumber(value); - break; - case UUID: - // UUID ID - byte[] bytes = id.asBytes(); - assert bytes.length == Id.UUID_LENGTH; - this.writeUInt8(0x7f); // 0b01111111 means UUID - this.write(bytes); - break; - case EDGE: - // Edge ID - this.writeUInt8(0x7e); // 0b01111110 means EdgeId - this.writeEdgeId(id); - break; - default: - // String Id (VertexID) - bytes = id.asBytes(); - int len = bytes.length; - if (len <= 0) { - E.checkArgument(false, "Can't write empty id"); - } - if (len > ID_LEN_MAX) { - E.checkArgument(false, "Big id max length is %s, but got %s {%s}", - ID_LEN_MAX, len, id); - } - len -= 1; // mapping [1, 16384] to [0, 16383] - if (len <= 0x3f) { - // If length is <= 63, use a single byte with the highest bit set to 1 - this.writeUInt8(len | 0x80); - } else { - int high = len >> 8; - int low = len & 0xff; - // Write high 8 bits with highest two bits set to 11 - this.writeUInt8(high | 0xc0); - this.writeUInt8(low); - } - this.write(bytes); - break; - } - return this; - } - - public Id readId() { - byte b = this.read(); - boolean number = (b & 0x80) == 0; - if (number) { - if (b == 0x7f) { - // UUID Id - return IdGenerator.of(this.read(Id.UUID_LENGTH), IdType.UUID); - } else if (b == 0x7e) { - // Edge Id - return this.readEdgeId(); - } else { - // Number Id - return IdGenerator.of(this.readNumber(b)); - } - } else { - // String Id - int len = b & 0x3f; // Take the lowest 6 bits as part of the length - if ((b & 0x40) != 0) { // If the 7th bit is set, length information spans 2 bytes - int high = len << 8; - int low = this.readUInt8(); - len = high + low; - } - len += 1; // restore [0, 16383] to [1, 16384] - byte[] id = this.read(len); - return IdGenerator.of(id, IdType.STRING); - } - } - - public BytesBuffer writeEdgeId(Id id) { - // owner-vertex + dir + edge-label + sub-edge-label + sort-values + other-vertex - EdgeId edge = (EdgeId) id; - this.writeId(edge.ownerVertexId()); - this.write(edge.directionCode()); - this.writeId(edge.edgeLabelId()); - this.writeId(edge.subLabelId()); - this.writeStringWithEnding(edge.sortValues()); - this.writeId(edge.otherVertexId()); - return this; - } - - public Id readEdgeId() { - return new EdgeId(this.readId(), EdgeId.directionFromCode(this.read()), - this.readId(), this.readId(), this.readStringWithEnding(), - this.readId()); - } - - public BytesBuffer writeIndexId(Id id, HugeType type) { - return this.writeIndexId(id, type, true); - } - - public BytesBuffer writeIndexId(Id id, HugeType type, boolean withEnding) { - byte[] bytes = id.asBytes(); - int len = bytes.length; - if (len == 0) { - E.checkArgument(false, "Can't write empty id"); - } - - this.write(bytes); - if (type.isStringIndex()) { - if (Bytes.contains(bytes, STRING_ENDING_BYTE)) { - // Not allow STRING_ENDING_BYTE to exist in string index id - E.checkArgument(false, - "The %s type index id can't contains " + - "byte '0x%s', but got: 0x%s", - type, Bytes.toHex(STRING_ENDING_BYTE), Bytes.toHex(bytes)); - } - if (withEnding) { - this.writeStringWithEnding(""); - } - } - return this; - } - - public BinaryId readIndexId(HugeType type) { - byte[] id; - if (type.isRange4Index()) { - // HugeTypeCode 1 byte + IndexLabel 4 bytes + fieldValue 4 bytes - id = this.read(9); - } else if (type.isRange8Index()) { - // HugeTypeCode 1 byte + IndexLabel 4 bytes + fieldValue 8 bytes - id = this.read(13); - } else { - assert type.isStringIndex(); - id = this.readBytesWithEnding(); - } - return new BinaryId(id, IdGenerator.of(id, IdType.STRING)); - } - - public BinaryId asId() { - return new BinaryId(this.bytes(), null); - } - - public BinaryId parseId(HugeType type, boolean enablePartition) { - if (type.isIndex()) { - return this.readIndexId(type); - } - // Parse id from bytes - if ((type.isVertex() || type.isEdge()) && enablePartition) { - this.readShort(); - } - int start = this.buffer.position(); - /* - * Since edge id in edges table doesn't prefix with leading 0x7e, - * so readId() will return the source vertex id instead of edge id, - * can't call: type.isEdge() ? this.readEdgeId() : this.readId(); - */ - Id id = this.readId(); - int end = this.buffer.position(); - int len = end - start; - byte[] bytes = new byte[len]; - System.arraycopy(this.array(), start, bytes, 0, len); - return new BinaryId(bytes, id); - } - - /** - * Analyze olap id - * @param type - * @param isOlap - * @return - */ - public BinaryId parseOlapId(HugeType type, boolean isOlap) { - if (type.isIndex()) { - return this.readIndexId(type); - } - // Parse id from bytes - int start = this.buffer.position(); - // OLAP {PropertyKey}{VertexId} - if (isOlap) { - // Read olap property id first - Id pkId = this.readId(); - } - Id id = this.readId(); - int end = this.buffer.position(); - int len = end - start; - byte[] bytes = new byte[len]; - System.arraycopy(this.array(), start, bytes, 0, len); - return new BinaryId(bytes, id); - } - - private void writeNumber(long val) { - /* - * 8 kinds of number, 2 ~ 9 bytes number: - * 0b 0kkksxxx X... - * 0(1 bit) + kind(3 bits) + signed(1 bit) + number(n bits) - * - * 2 byte : 0b 0000 1xxx X(8 bits) [0, 2047] - * 0b 0000 0xxx X(8 bits) [-2048, -1] - * 3 bytes: 0b 0001 1xxx X X [0, 524287] - * 0b 0001 0xxx X X [-524288, -1] - * 4 bytes: 0b 0010 1xxx X X X [0, 134217727] - * 0b 0010 0xxx X X X [-134217728, -1] - * 5 bytes: 0b 0011 1xxx X X X X [0, 2^35 - 1] - * 0b 0011 0xxx X X X X [-2^35, -1] - * 6 bytes: 0b 0100 1xxx X X X X X [0, 2^43 - 1] - * 0b 0100 0xxx X X X X X [-2^43, -1] - * 7 bytes: 0b 0101 1xxx X X X X X X [0, 2^51 - 1] - * 0b 0101 0xxx X X X X X X [-2^51, -1] - * 8 bytes: 0b 0110 1xxx X X X X X X X [0, 2^59 - 1] - * 0b 0110 0xxx X X X X X X X [-2^59, -1] - * 9 bytes: 0b 0111 1000 X X X X X X X X [0, 2^64 - 1] - * 0b 0111 0000 X X X X X X X X [-2^64, -1] - * - * NOTE: 0b 0111 1111 is used by 128 bits UUID - * 0b 0111 1110 is used by EdgeId - */ - int positive = val >= 0 ? 0x08 : 0x00; - if (~0x7ffL <= val && val <= 0x7ffL) { - int high3bits = (int) (val >> 8) & 0x07; - this.writeUInt8(0x00 | positive | high3bits); - this.writeUInt8((byte) val); - } else if (~0x7ffffL <= val && val <= 0x7ffffL) { - int high3bits = (int) (val >> 16) & 0x07; - this.writeUInt8(0x10 | positive | high3bits); - this.writeShort((short) val); - } else if (~0x7ffffffL <= val && val <= 0x7ffffffL) { - int high3bits = (int) (val >> 24 & 0x07); - this.writeUInt8(0x20 | positive | high3bits); - this.write((byte) (val >> 16)); - this.writeShort((short) val); - } else if (~0x7ffffffffL <= val && val <= 0x7ffffffffL) { - int high3bits = (int) (val >> 32) & 0x07; - this.writeUInt8(0x30 | positive | high3bits); - this.writeInt((int) val); - } else if (~0x7ffffffffffL <= val && val <= 0x7ffffffffffL) { - int high3bits = (int) (val >> 40) & 0x07; - this.writeUInt8(0x40 | positive | high3bits); - this.write((byte) (val >> 32)); - this.writeInt((int) val); - } else if (~0x7ffffffffffffL <= val && val <= 0x7ffffffffffffL) { - int high3bits = (int) (val >> 48) & 0x07; - this.writeUInt8(0x50 | positive | high3bits); - this.writeShort((short) (val >> 32)); - this.writeInt((int) val); - } else if (~0x7ffffffffffffffL <= val && val <= 0x7ffffffffffffffL) { - int high3bits = (int) (val >> 56) & 0x07; - this.writeUInt8(0x60 | positive | high3bits); - this.write((byte) (val >> 48)); - this.writeShort((short) (val >> 32)); - this.writeInt((int) val); - } else { - // high3bits is always 0b000 for 9 bytes number - this.writeUInt8(0x70 | positive); - this.writeLong(val); - } - } - - private long readNumber(byte b) { - if ((b & 0x80) != 0) { - E.checkArgument(false, - "Not a number type with prefix byte '0x%s'", - Bytes.toHex(b)); - } - // Parse the kind from byte 0kkksxxx - int kind = b >>> 4; - boolean positive = (b & 0x08) > 0; - long high3bits = b & 0x07; - long value = high3bits << ((kind + 1) * 8); - switch (kind) { - case 0: - value |= this.readUInt8(); - break; - case 1: - value |= this.readUInt16(); - break; - case 2: - value |= (long) this.readUInt8() << 16 | this.readUInt16(); - break; - case 3: - value |= this.readUInt32(); - break; - case 4: - value |= (long) this.readUInt8() << 32 | this.readUInt32(); - break; - case 5: - value |= (long) this.readUInt16() << 32 | this.readUInt32(); - break; - case 6: - value |= (long) this.readUInt8() << 48 | - (long) this.readUInt16() << 32 | - this.readUInt32(); - break; - case 7: - assert high3bits == 0L; - value |= this.readLong(); - break; - default: - throw new AssertionError("Invalid length of number: " + kind); - } - if (!positive && kind < 7) { - // Restore the bits of the original negative number - long mask = Long.MIN_VALUE >> (52 - kind * 8); - value |= mask; - } - return value; - } - - private byte[] readBytesWithEnding() { - int start = this.buffer.position(); - boolean foundEnding = false; - int remaining = this.remaining(); - for (int i = 0; i < remaining; i++) { - byte current = this.read(); - if (current == STRING_ENDING_BYTE) { - foundEnding = true; - break; - } - } - if (!foundEnding) { - E.checkArgument(false, - "Not found ending '0x%s'", - Bytes.toHex(STRING_ENDING_BYTE)); - } - int end = this.buffer.position() - 1; - int len = end - start; - if (len <= 0) { - return BYTES_EMPTY; - } - byte[] bytes = new byte[len]; - System.arraycopy(this.array(), start, bytes, 0, len); - return bytes; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/GraphSerializer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/GraphSerializer.java index 2d14df1c84..548ddba7ad 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/GraphSerializer.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/GraphSerializer.java @@ -18,14 +18,14 @@ package org.apache.hugegraph.backend.serializer; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.iterator.CIter; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeEdgeProperty; -import org.apache.hugegraph.structure.HugeIndex; +import org.apache.hugegraph.structure.Index; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.structure.HugeVertexProperty; import org.apache.hugegraph.type.HugeType; @@ -49,9 +49,9 @@ public interface GraphSerializer { CIter readEdges(HugeGraph graph, BackendEntry bytesEntry); - BackendEntry writeIndex(HugeIndex index); + BackendEntry writeIndex(Index index); - HugeIndex readIndex(HugeGraph graph, ConditionQuery query, BackendEntry entry); + Index readIndex(HugeGraph graph, ConditionQuery query, BackendEntry entry); BackendEntry writeId(HugeType type, Id id); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/SchemaSerializer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/SchemaSerializer.java index 74e2dcc09f..aea85495b7 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/SchemaSerializer.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/SchemaSerializer.java @@ -19,10 +19,10 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.backend.store.BackendEntry; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; public interface SchemaSerializer { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/SerializerFactory.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/SerializerFactory.java index 213cf2b264..42962d5757 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/SerializerFactory.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/SerializerFactory.java @@ -20,7 +20,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.config.HugeConfig; public class SerializerFactory { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TableBackendEntry.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TableBackendEntry.java index 918a95b511..34d15e2b11 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TableBackendEntry.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TableBackendEntry.java @@ -27,7 +27,8 @@ import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.lang3.NotImplementedException; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.backend.BackendColumn; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Cardinality; @@ -252,17 +253,17 @@ public int columnsSize() { } @Override - public Collection columns() { + public Collection columns() { throw new NotImplementedException("Not supported by table backend"); } @Override - public void columns(Collection bytesColumns) { + public void columns(Collection bytesColumns) { throw new NotImplementedException("Not supported by table backend"); } @Override - public void columns(BackendEntry.BackendColumn bytesColumn) { + public void columns(BackendColumn bytesColumn) { throw new NotImplementedException("Not supported by table backend"); } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TableSerializer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TableSerializer.java index a2e3279976..e322e90d11 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TableSerializer.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TableSerializer.java @@ -23,26 +23,26 @@ import java.util.Set; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.id.IdUtil; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.exception.BackendException; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.id.IdUtil; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.config.HugeConfig; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.schema.SchemaLabel; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.SchemaLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeEdgeProperty; import org.apache.hugegraph.structure.HugeElement; -import org.apache.hugegraph.structure.HugeIndex; +import org.apache.hugegraph.structure.Index; import org.apache.hugegraph.structure.HugeProperty; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.structure.HugeVertexProperty; @@ -83,7 +83,7 @@ protected TableBackendEntry newBackendEntry(SchemaElement e) { return newBackendEntry(e.type(), e.id()); } - protected TableBackendEntry newBackendEntry(HugeIndex index) { + protected TableBackendEntry newBackendEntry(Index index) { return newBackendEntry(index.type(), index.id()); } @@ -305,7 +305,7 @@ public HugeEdge readEdge(HugeGraph graph, BackendEntry backendEntry) { } @Override - public BackendEntry writeIndex(HugeIndex index) { + public BackendEntry writeIndex(Index index) { TableBackendEntry entry = newBackendEntry(index); /* * When field-values is null and elementIds size is 0, it is @@ -327,7 +327,7 @@ public BackendEntry writeIndex(HugeIndex index) { } @Override - public HugeIndex readIndex(HugeGraph graph, ConditionQuery query, + public Index readIndex(HugeGraph graph, ConditionQuery query, BackendEntry backendEntry) { E.checkNotNull(graph, "serializer graph"); if (backendEntry == null) { @@ -342,7 +342,7 @@ public HugeIndex readIndex(HugeGraph graph, ConditionQuery query, Number expiredTime = entry.column(HugeKeys.EXPIRED_TIME); IndexLabel indexLabel = graph.indexLabel(this.toId(indexLabelId)); - HugeIndex index = new HugeIndex(graph, indexLabel); + Index index = new Index(graph, indexLabel); index.fieldValues(indexValues); long expired = index.hasTtl() ? expiredTime.longValue() : 0L; for (Object elemId : elemIds) { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TableSerializerV2.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TableSerializerV2.java index 54f9e4cf54..b2ec49bde6 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TableSerializerV2.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TableSerializerV2.java @@ -18,13 +18,13 @@ package org.apache.hugegraph.backend.serializer; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.config.HugeConfig; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeEdgeProperty; import org.apache.hugegraph.structure.HugeVertex; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TextBackendEntry.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TextBackendEntry.java index 2dfdb2cba9..f1878fde35 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TextBackendEntry.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TextBackendEntry.java @@ -27,8 +27,9 @@ import java.util.Set; import java.util.concurrent.ConcurrentSkipListMap; -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.backend.BackendColumn; +import org.apache.hugegraph.exception.BackendException; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.HugeKeys; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TextSerializer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TextSerializer.java index 2d5cb81ec1..5a7ca40f7b 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TextSerializer.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TextSerializer.java @@ -24,32 +24,32 @@ import java.util.Map; import org.apache.commons.lang.NotImplementedException; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.id.IdUtil; -import org.apache.hugegraph.backend.id.SplicingIdGenerator; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.IdPrefixQuery; -import org.apache.hugegraph.backend.query.IdRangeQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.exception.BackendException; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.id.IdUtil; +import org.apache.hugegraph.id.SplicingIdGenerator; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.IdPrefixQuery; +import org.apache.hugegraph.query.IdRangeQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.iterator.CIter; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeEdgeProperty; import org.apache.hugegraph.structure.HugeElement; -import org.apache.hugegraph.structure.HugeIndex; -import org.apache.hugegraph.structure.HugeIndex.IdWithExpiredTime; +import org.apache.hugegraph.structure.Index; +import org.apache.hugegraph.structure.Index.IdWithExpiredTime; import org.apache.hugegraph.structure.HugeProperty; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.structure.HugeVertexProperty; @@ -363,7 +363,7 @@ public CIter readEdges(HugeGraph graph, BackendEntry bytesEntry) { } @Override - public BackendEntry writeIndex(HugeIndex index) { + public BackendEntry writeIndex(Index index) { TextBackendEntry entry = newBackendEntry(index.type(), index.id()); if (index.fieldValues() == null && index.elementIds().isEmpty()) { /* @@ -386,7 +386,7 @@ public BackendEntry writeIndex(HugeIndex index) { } @Override - public HugeIndex readIndex(HugeGraph graph, ConditionQuery query, + public Index readIndex(HugeGraph graph, ConditionQuery query, BackendEntry backendEntry) { E.checkNotNull(graph, "serializer graph"); if (backendEntry == null) { @@ -402,7 +402,7 @@ public HugeIndex readIndex(HugeGraph graph, ConditionQuery query, formatSyspropName(HugeKeys.ELEMENT_IDS)); IndexLabel indexLabel = IndexLabel.label(graph, readId(indexLabelId)); - HugeIndex index = new HugeIndex(graph, indexLabel); + Index index = new Index(graph, indexLabel); index.fieldValues(JsonUtil.fromJson(indexValues, Object.class)); for (IdWithExpiredTime elemId : readElementIds(elemIds)) { long expiredTime = elemId.expiredTime(); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/AbstractBackendStore.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/AbstractBackendStore.java index adb3c8c400..89e9fd8ffc 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/AbstractBackendStore.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/AbstractBackendStore.java @@ -18,10 +18,10 @@ package org.apache.hugegraph.backend.store; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; import org.apache.hugegraph.backend.query.ConditionQueryFlatten; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.exception.ConnectionException; import org.apache.hugegraph.iterator.ExtendableIterator; import org.apache.hugegraph.iterator.FlatMapperIterator; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/AbstractBackendStoreProvider.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/AbstractBackendStoreProvider.java index ff9ff00d4d..2ec8662375 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/AbstractBackendStoreProvider.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/AbstractBackendStoreProvider.java @@ -21,7 +21,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Future; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.backend.store.raft.StoreSnapshotFile; import org.apache.hugegraph.config.CoreOptions; import org.apache.hugegraph.config.HugeConfig; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendEntry.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendEntry.java index b1a5f89dc1..3e40668b76 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendEntry.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendEntry.java @@ -21,60 +21,16 @@ import java.util.Iterator; import java.util.NoSuchElementException; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.backend.BackendColumn; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.iterator.WrappedIterator; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.Idfiable; import org.apache.hugegraph.util.Bytes; import org.apache.hugegraph.util.E; -import org.apache.hugegraph.util.StringEncoding; public interface BackendEntry extends Idfiable { - class BackendColumn implements Comparable { - - public byte[] name; - public byte[] value; - - public static BackendColumn of(byte[] name, byte[] value) { - BackendColumn col = new BackendColumn(); - col.name = name; - col.value = value; - return col; - } - - @Override - public String toString() { - return String.format("%s=%s", - StringEncoding.decode(name), - StringEncoding.decode(value)); - } - - @Override - public int compareTo(BackendColumn other) { - if (other == null) { - return 1; - } - return Bytes.compare(this.name, other.name); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof BackendColumn)) { - return false; - } - BackendColumn other = (BackendColumn) obj; - return Bytes.equals(this.name, other.name) && - Bytes.equals(this.value, other.value); - } - - public int hashCode() { - return this.name.hashCode() ^ - this.value.hashCode(); - } - - } - HugeType type(); @Override diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendEntryIterator.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendEntryIterator.java index 20469f77aa..e5d2acaa40 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendEntryIterator.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendEntryIterator.java @@ -19,10 +19,10 @@ import java.util.NoSuchElementException; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.backend.page.PageInfo; import org.apache.hugegraph.backend.page.PageState; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.exception.LimitExceedException; import org.apache.hugegraph.exception.NotSupportException; import org.apache.hugegraph.iterator.CIter; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendMutation.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendMutation.java index 5b17fdf8e9..9d301ac700 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendMutation.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendMutation.java @@ -23,8 +23,8 @@ import java.util.Map; import java.util.Set; -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.exception.HugeException; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.iterator.ExtendableIterator; import org.apache.hugegraph.perf.PerfUtil.Watched; import org.apache.hugegraph.type.HugeType; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendProviderFactory.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendProviderFactory.java index 2612ea3a07..c8e94d145f 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendProviderFactory.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendProviderFactory.java @@ -23,7 +23,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.backend.store.memory.InMemoryDBStoreProvider; import org.apache.hugegraph.backend.store.raft.RaftBackendStoreProvider; import org.apache.hugegraph.config.CoreOptions; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendStore.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendStore.java index 6486d353c1..a1a28b285e 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendStore.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendStore.java @@ -22,9 +22,9 @@ import java.util.function.Function; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendTable.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendTable.java index a9ee4b5c72..91b6ef7922 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendTable.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendTable.java @@ -24,9 +24,10 @@ import java.util.List; import org.apache.commons.lang3.NotImplementedException; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.Query; -import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.backend.Shard; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.Query; +import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Directions; import org.apache.hugegraph.type.define.HugeKeys; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/Shard.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/Shard.java deleted file mode 100644 index 3f1d2bf9e8..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/Shard.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.backend.store; - -/** - * Shard is used for distributed backend storage scanning. - * operations. Each shard represents a range of tokens for a node. - * Reading data from a given shard does not cross multiple nodes. - */ -public class Shard { - - // token range start - private String start; - // token range end - private String end; - // partitions count in this range - private long length; - - public Shard(String start, String end, long length) { - this.start = start; - this.end = end; - this.length = length; - } - - public String start() { - return this.start; - } - - public void start(String start) { - this.start = start; - } - - public String end() { - return this.end; - } - - public void end(String end) { - this.end = end; - } - - public long length() { - return this.length; - } - - public void length(long length) { - this.length = length; - } - - @Override - public String toString() { - return String.format("Shard{start=%s, end=%s, length=%s}", - this.start, this.end, this.length); - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/SystemSchemaStore.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/SystemSchemaStore.java index 1ce7700ad0..d32cc3514c 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/SystemSchemaStore.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/SystemSchemaStore.java @@ -19,8 +19,8 @@ import java.util.Map; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.schema.SchemaElement; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.struct.schema.SchemaElement; import org.apache.hugegraph.type.define.CollectionType; import org.apache.hugegraph.util.collection.CollectionFactory; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/memory/InMemoryDBStore.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/memory/InMemoryDBStore.java index c482749744..3368256482 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/memory/InMemoryDBStore.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/memory/InMemoryDBStore.java @@ -22,10 +22,10 @@ import java.util.Iterator; import java.util.Map; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.backend.LocalCounter; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.serializer.TextBackendEntry; import org.apache.hugegraph.backend.store.AbstractBackendStore; import org.apache.hugegraph.backend.store.BackendAction; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/memory/InMemoryDBTable.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/memory/InMemoryDBTable.java index 4768080905..ce8d5ec4f3 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/memory/InMemoryDBTable.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/memory/InMemoryDBTable.java @@ -25,21 +25,21 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.Aggregate; -import org.apache.hugegraph.backend.query.Aggregate.AggregateFunc; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.IdPrefixQuery; -import org.apache.hugegraph.backend.query.IdRangeQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.exception.BackendException; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.Aggregate; +import org.apache.hugegraph.query.Aggregate.AggregateFunc; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.IdPrefixQuery; +import org.apache.hugegraph.query.IdRangeQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.backend.serializer.TextBackendEntry; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.backend.store.BackendSession; import org.apache.hugegraph.backend.store.BackendTable; -import org.apache.hugegraph.backend.store.Shard; +import org.apache.hugegraph.backend.Shard; import org.apache.hugegraph.exception.NotSupportException; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/memory/InMemoryDBTables.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/memory/InMemoryDBTables.java index 445c28a5d6..8ce4a8e86f 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/memory/InMemoryDBTables.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/memory/InMemoryDBTables.java @@ -29,21 +29,21 @@ import java.util.SortedMap; import java.util.concurrent.ConcurrentSkipListMap; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.Condition.RangeConditions; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.IdQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.Condition.RangeConditions; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.IdQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.backend.serializer.TextBackendEntry; import org.apache.hugegraph.backend.store.BackendEntry; -import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.backend.store.BackendSession; import org.apache.hugegraph.iterator.ExtendableIterator; -import org.apache.hugegraph.structure.HugeIndex; +import org.apache.hugegraph.structure.Index; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.HugeKeys; import org.apache.hugegraph.util.E; @@ -429,7 +429,7 @@ public Iterator query(BackendSession session, } assert fieldValue != null && indexLabelId != null; - Id id = HugeIndex.formatIndexId(query.resultType(), + Id id = Index.formatIndexId(query.resultType(), indexLabelId, fieldValue); IdQuery q = new IdQuery(query, id); q.offset(query.offset()); @@ -502,7 +502,7 @@ public Iterator query(BackendSession session, RangeConditions range = new RangeConditions(relations); if (range.keyEq() != null) { - Id id = HugeIndex.formatIndexId(query.resultType(), + Id id = Index.formatIndexId(query.resultType(), indexLabelId, range.keyEq()); IdQuery q = new IdQuery(query, id); q.offset(query.offset()); @@ -529,7 +529,7 @@ private Iterator betweenQuery(Id indexLabelId, // Field value < keyMax keyMin = NumericUtil.minValueOf(keyMax.getClass()); } - Id min = HugeIndex.formatIndexId(type, indexLabelId, keyMin); + Id min = Index.formatIndexId(type, indexLabelId, keyMin); if (keyMax == null) { // Field value > keyMin @@ -537,7 +537,7 @@ private Iterator betweenQuery(Id indexLabelId, indexLabelId = IdGenerator.of(indexLabelId.asLong() + 1L); keyMax = NumericUtil.minValueOf(keyMin.getClass()); } - Id max = HugeIndex.formatIndexId(type, indexLabelId, keyMax); + Id max = Index.formatIndexId(type, indexLabelId, keyMax); max = keyMaxEq ? rs.floorKey(max) : rs.lowerKey(max); if (max == null) { @@ -569,9 +569,9 @@ public void delete(BackendSession session, TextBackendEntry entry) { return; } Id indexLabelId = IdGenerator.of(Long.parseLong(indexLabel)); - Id min = HugeIndex.formatIndexId(entry.type(), indexLabelId, 0L); + Id min = Index.formatIndexId(entry.type(), indexLabelId, 0L); indexLabelId = IdGenerator.of(indexLabelId.asLong() + 1L); - Id max = HugeIndex.formatIndexId(entry.type(), indexLabelId, 0L); + Id max = Index.formatIndexId(entry.type(), indexLabelId, 0L); SortedMap subStore; subStore = this.store().subMap(min, max); Iterator> iter; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftBackendStore.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftBackendStore.java index 1765562127..cbdd5c5bd1 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftBackendStore.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftBackendStore.java @@ -23,8 +23,8 @@ import java.util.function.Function; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.exception.BackendException; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.backend.store.BackendFeatures; import org.apache.hugegraph.backend.store.BackendMutation; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftBackendStoreProvider.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftBackendStoreProvider.java index ecdff19bd5..ff6cfee8c6 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftBackendStoreProvider.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftBackendStoreProvider.java @@ -21,7 +21,7 @@ import java.util.concurrent.Future; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.backend.store.BackendStore; import org.apache.hugegraph.backend.store.BackendStoreProvider; import org.apache.hugegraph.backend.store.raft.rpc.RaftRequests.StoreAction; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftClosure.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftClosure.java index bd4e45da42..eb6be8cd0b 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftClosure.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftClosure.java @@ -23,7 +23,7 @@ import java.util.concurrent.TimeoutException; import java.util.function.Supplier; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.util.Log; import org.slf4j.Logger; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftContext.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftContext.java index 3928a4127f..ea2e92bfc8 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftContext.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftContext.java @@ -30,11 +30,11 @@ import java.util.concurrent.ThreadPoolExecutor; import org.apache.commons.io.FileUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraphParams; import org.apache.hugegraph.backend.cache.Cache; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.store.BackendAction; import org.apache.hugegraph.backend.store.BackendMutation; import org.apache.hugegraph.backend.store.BackendStore; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftException.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftException.java index 85e6915bf8..4610d09a77 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftException.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftException.java @@ -17,7 +17,7 @@ package org.apache.hugegraph.backend.store.raft; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; public class RaftException extends HugeException { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftGroupManagerImpl.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftGroupManagerImpl.java index 0f231d734c..c0a144030c 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftGroupManagerImpl.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftGroupManagerImpl.java @@ -20,7 +20,7 @@ import java.util.List; import java.util.stream.Collectors; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.backend.store.raft.rpc.RaftRequests.AddPeerRequest; import org.apache.hugegraph.backend.store.raft.rpc.RaftRequests.ListPeersRequest; import org.apache.hugegraph.backend.store.raft.rpc.RaftRequests.ListPeersResponse; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftNode.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftNode.java index a8e07b4114..3b39ea3de0 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftNode.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftNode.java @@ -24,7 +24,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.util.LZ4Util; import org.apache.hugegraph.util.Log; import org.slf4j.Logger; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/StoreCommand.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/StoreCommand.java index f49f94348f..3f25aaf5e1 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/StoreCommand.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/StoreCommand.java @@ -17,7 +17,7 @@ package org.apache.hugegraph.backend.store.raft; -import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.backend.store.raft.rpc.RaftRequests.StoreAction; import org.apache.hugegraph.backend.store.raft.rpc.RaftRequests.StoreType; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/StoreSerializer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/StoreSerializer.java index 69937737da..c76afb9d64 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/StoreSerializer.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/StoreSerializer.java @@ -21,13 +21,13 @@ import java.util.Iterator; import java.util.List; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.serializer.BinaryBackendEntry; -import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.backend.store.BackendAction; import org.apache.hugegraph.backend.store.BackendEntry; -import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.backend.store.BackendMutation; import org.apache.hugegraph.backend.store.raft.RaftBackendStore.IncrCounter; import org.apache.hugegraph.type.HugeType; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/StoreStateMachine.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/StoreStateMachine.java index df54a8276d..a6237ce8fb 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/StoreStateMachine.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/StoreStateMachine.java @@ -23,8 +23,8 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.exception.BackendException; +import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.backend.store.BackendMutation; import org.apache.hugegraph.backend.store.BackendStore; import org.apache.hugegraph.backend.store.raft.RaftBackendStore.IncrCounter; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/rpc/RpcForwarder.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/rpc/RpcForwarder.java index 0944f5cc39..ba4973d69d 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/rpc/RpcForwarder.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/rpc/RpcForwarder.java @@ -19,7 +19,7 @@ import java.util.concurrent.ExecutionException; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.backend.store.raft.RaftClosure; import org.apache.hugegraph.backend.store.raft.RaftContext; import org.apache.hugegraph.backend.store.raft.RaftStoreClosure; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/ram/IntIntMap.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/ram/IntIntMap.java index 1b2a4293ea..02d3261590 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/ram/IntIntMap.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/ram/IntIntMap.java @@ -22,7 +22,7 @@ import java.io.IOException; import java.util.Arrays; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; public final class IntIntMap implements RamMap { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/ram/IntLongMap.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/ram/IntLongMap.java index bc980db5a5..ccf7db5a30 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/ram/IntLongMap.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/ram/IntLongMap.java @@ -22,7 +22,7 @@ import java.io.IOException; import java.util.Arrays; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; public final class IntLongMap implements RamMap { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/ram/RamTable.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/ram/RamTable.java index 0e2c58bddc..707f02c9be 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/ram/RamTable.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/ram/RamTable.java @@ -35,18 +35,18 @@ import java.util.concurrent.ExecutorService; import org.apache.commons.io.FileUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; import org.apache.hugegraph.backend.query.ConditionQueryFlatten; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.iterator.FlatMapperIterator; import org.apache.hugegraph.perf.PerfUtil.Watched; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.type.HugeType; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/AbstractTransaction.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/AbstractTransaction.java index 43393252d2..0a5d527832 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/AbstractTransaction.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/AbstractTransaction.java @@ -20,14 +20,14 @@ import java.util.Set; import org.apache.commons.lang3.StringUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.backend.Transaction; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.IdQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.IdQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.backend.serializer.AbstractSerializer; import org.apache.hugegraph.backend.store.BackendEntry; @@ -37,7 +37,7 @@ import org.apache.hugegraph.backend.store.BackendStore; import org.apache.hugegraph.exception.NotFoundException; import org.apache.hugegraph.perf.PerfUtil.Watched; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Action; import org.apache.hugegraph.type.define.CollectionType; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/GraphIndexTransaction.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/GraphIndexTransaction.java index 6faace9671..b333c929df 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/GraphIndexTransaction.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/GraphIndexTransaction.java @@ -20,7 +20,6 @@ import java.nio.CharBuffer; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -31,12 +30,10 @@ import java.util.function.Function; import java.util.stream.Collectors; -import org.apache.commons.lang3.StringUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.analyzer.Analyzer; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.page.IdHolder; import org.apache.hugegraph.backend.page.IdHolder.BatchIdHolder; import org.apache.hugegraph.backend.page.IdHolder.FixedIdHolder; @@ -46,14 +43,15 @@ import org.apache.hugegraph.backend.page.PageInfo; import org.apache.hugegraph.backend.page.PageState; import org.apache.hugegraph.backend.page.SortByCountIdHolderList; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.Condition.RangeConditions; -import org.apache.hugegraph.backend.query.Condition.Relation; -import org.apache.hugegraph.backend.query.Condition.RelationType; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.ConditionQuery.OptimizedType; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.Condition.RangeConditions; +import org.apache.hugegraph.query.Condition.Relation; +import org.apache.hugegraph.query.Condition.RelationType; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.ConditionQuery.OptimizedType; import org.apache.hugegraph.backend.query.ConditionQueryFlatten; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Query; +import org.apache.hugegraph.query.MatchedIndex; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.backend.serializer.AbstractSerializer; import org.apache.hugegraph.backend.store.BackendEntry; @@ -67,15 +65,17 @@ import org.apache.hugegraph.job.EphemeralJob; import org.apache.hugegraph.job.system.DeleteExpiredJob; import org.apache.hugegraph.perf.PerfUtil.Watched; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.SchemaLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeElement; -import org.apache.hugegraph.structure.HugeIndex; -import org.apache.hugegraph.structure.HugeIndex.IdWithExpiredTime; +import org.apache.hugegraph.structure.Index; +import org.apache.hugegraph.structure.builder.IndexBuilder; +import org.apache.hugegraph.structure.Index.IdWithExpiredTime; import org.apache.hugegraph.structure.HugeProperty; +import org.apache.hugegraph.structure.BaseProperty; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.task.EphemeralJobQueue; import org.apache.hugegraph.type.HugeType; @@ -97,18 +97,17 @@ public class GraphIndexTransaction extends AbstractTransaction { - public static final String START_SYMBOL = "("; - public static final String END_SYMBOL = ")"; - public static final String WORD_DELIMITER = "|"; + public static final String START_SYMBOL = IndexBuilder.START_SYMBOL; + public static final String END_SYMBOL = IndexBuilder.END_SYMBOL; + public static final String WORD_DELIMITER = IndexBuilder.WORD_DELIMITER; - private final Analyzer textAnalyzer; + private final IndexBuilder indexBuilder; private final int indexIntersectThresh; public GraphIndexTransaction(HugeGraphParams graph, BackendStore store) { super(graph, store); - this.textAnalyzer = graph.analyzer(); - assert this.textAnalyzer != null; + this.indexBuilder = new IndexBuilder(this.graph(), graph.analyzer()); final HugeConfig conf = graph.configuration(); this.indexIntersectThresh = @@ -137,27 +136,8 @@ public void updateLabelIndex(HugeElement element, boolean removed) { return; } - // Update label index if backend store not supports label-query - HugeIndex index = new HugeIndex(this.graph(), - IndexLabel.label(element.type())); - index.fieldValues(element.schemaLabel().id()); - index.elementIds(element.id(), element.expiredTime()); - - if (removed) { - this.doEliminate(this.serializer.writeIndex(index)); - } else { - this.doAppend(this.serializer.writeIndex(index)); - } - - if (element instanceof HugeEdge && ((EdgeLabel) label).hasFather()) { - HugeIndex fatherIndex = new HugeIndex(this.graph(), IndexLabel.label(element.type())); - fatherIndex.fieldValues(((EdgeLabel) label).fatherId()); - fatherIndex.elementIds(element.id(), element.expiredTime()); - if (removed) { - this.doEliminate(this.serializer.writeIndex(fatherIndex)); - } else { - this.doAppend(this.serializer.writeIndex(fatherIndex)); - } + for (Index index : this.indexBuilder.buildLabelIndex(element.element())) { + this.writeIndex(index, removed); } } @@ -168,39 +148,20 @@ public void updateVertexIndex(HugeVertex vertex, boolean removed) { return; } // Update index(only property, no edge) of a vertex - for (Id id : vertex.schemaLabel().indexLabels()) { - this.updateIndex(id, vertex, removed); - } + IndexBuilder.forEachIndexLabelId(vertex.element(), this.graph()::edgeLabel, + id -> this.updateIndex(id, vertex, removed)); } @Watched(prefix = "index") public void updateEdgeIndex(HugeEdge edge, boolean removed) { - // Update index of an edge - for (Id id : edge.schemaLabel().indexLabels()) { - this.updateIndex(id, edge, removed); - } - - EdgeLabel label = edge.schemaLabel(); - if (label.hasFather()) { - for (Id id : graph().edgeLabel(label.fatherId()).indexLabels()) { - this.updateIndex(id, edge, removed); - } - } + IndexBuilder.forEachIndexLabelId(edge.element(), this.graph()::edgeLabel, + id -> this.updateIndex(id, edge, removed)); } private void updateVertexOlapIndex(HugeVertex vertex, boolean removed) { - Set propKeys = vertex.getPropertyKeys(); - E.checkArgument(propKeys.size() == 1, - "Expect only 1 property for olap vertex, but got %s", - propKeys.size()); - Id pkId = propKeys.iterator().next(); - List indexLabels = this.params().schemaTransaction() - .getIndexLabels(); - for (IndexLabel il : indexLabels) { - if (il.indexFields().contains(pkId)) { - this.updateIndex(il.id(), vertex, removed); - } - } + IndexBuilder.forEachOlapIndexLabelId(vertex.element(), + () -> this.params().schemaTransaction().getIndexLabels().iterator(), + id -> this.updateIndex(id, vertex, removed)); } /** @@ -216,110 +177,18 @@ protected void updateIndex(Id ilId, HugeElement element, boolean removed) { E.checkArgument(indexLabel != null, "Not exist index label with id '%s'", ilId); - // Collect property values of index fields - List allPropValues = new ArrayList<>(); - int fieldsNum = indexLabel.indexFields().size(); - int firstNullField = fieldsNum; - for (Id fieldId : indexLabel.indexFields()) { - HugeProperty property = element.getProperty(fieldId); - if (property == null) { - E.checkState(hasNullableProp(element, fieldId), - "Non-null property '%s' is null for '%s'", - this.graph().propertyKey(fieldId), element); - if (firstNullField == fieldsNum) { - firstNullField = allPropValues.size(); - } - allPropValues.add(ConditionQuery.INDEX_VALUE_NULL); - } else { - allPropValues.add(property.value()); + this.indexBuilder.forEachIndex(element.element(), indexLabel, index -> { + Object value = index.fieldValues(); + if (indexLabel.indexType().isUnique() && !removed && + this.existUniqueValue(indexLabel, value, element.id())) { + throw new IllegalArgumentException(String.format( + "Unique constraint %s conflict is found for %s", indexLabel, element)); } - } - - if (firstNullField == 0 && !indexLabel.indexType().isUnique()) { - // The property value of first index field is null - return; - } - // Not build index for record with nullable field (except unique index) - List nnPropValues = allPropValues.subList(0, firstNullField); - - // Expired time - long expiredTime = element.expiredTime(); - - // Update index for each index type - switch (indexLabel.indexType()) { - case RANGE_INT: - case RANGE_FLOAT: - case RANGE_LONG: - case RANGE_DOUBLE: - E.checkState(nnPropValues.size() == 1, - "Expect only one property in range index"); - Object value = NumericUtil.convertToNumber(nnPropValues.get(0)); - this.updateIndex(indexLabel, value, element.id(), - expiredTime, removed); - break; - case SEARCH: - E.checkState(nnPropValues.size() == 1, - "Expect only one property in search index"); - value = nnPropValues.get(0); - Set words = - this.segmentWords(propertyValueToString(value)); - for (String word : words) { - this.updateIndex(indexLabel, word, element.id(), - expiredTime, removed); - } - break; - case SECONDARY: - // Secondary index maybe include multi prefix index - if (isCollectionIndex(nnPropValues)) { - /* - * Property value is a collection - * we should create index for each item - */ - for (Object propValue : (Collection) nnPropValues.get(0)) { - value = ConditionQuery.concatValues(propValue); - this.updateIndex(indexLabel, value, element.id(), - expiredTime, removed); - } - } else { - for (int i = 0, n = nnPropValues.size(); i < n; i++) { - List prefixValues = - nnPropValues.subList(0, i + 1); - value = ConditionQuery.concatValues(prefixValues); - this.updateIndex(indexLabel, value, element.id(), - expiredTime, removed); - } - } - break; - case SHARD: - value = ConditionQuery.concatValues(nnPropValues); - this.updateIndex(indexLabel, value, element.id(), - expiredTime, removed); - break; - case UNIQUE: - value = ConditionQuery.concatValues(allPropValues); - assert !"".equals(value); - Id id = element.id(); - // TODO: add lock for updating unique index - if (!removed && this.existUniqueValue(indexLabel, value, id)) { - throw new IllegalArgumentException(String.format( - "Unique constraint %s conflict is found for %s", - indexLabel, element)); - } - this.updateIndex(indexLabel, value, element.id(), - expiredTime, removed); - break; - default: - throw new AssertionError(String.format( - "Unknown index type '%s'", indexLabel.indexType())); - } + this.writeIndex(index, removed); + }); } - private void updateIndex(IndexLabel indexLabel, Object propValue, - Id elementId, long expiredTime, boolean removed) { - HugeIndex index = new HugeIndex(this.graph(), indexLabel); - index.fieldValues(propValue); - index.elementIds(elementId, expiredTime); - + private void writeIndex(Index index, boolean removed) { if (removed) { this.doEliminate(this.serializer.writeIndex(index)); } else { @@ -335,7 +204,7 @@ private boolean existUniqueValue(IndexLabel indexLabel, private boolean hasEliminateInTx(IndexLabel indexLabel, Object value, Id elementId) { - HugeIndex index = new HugeIndex(this.graph(), indexLabel); + Index index = new Index(this.graph(), indexLabel); index.fieldValues(value); index.elementIds(elementId); BackendEntry entry = this.serializer.writeIndex(index); @@ -351,7 +220,7 @@ private boolean existUniqueValueInStore(IndexLabel indexLabel, Object value) { try { exist = iterator.hasNext(); if (exist) { - HugeIndex index = this.serializer.readIndex(graph(), query, + Index index = this.serializer.readIndex(graph(), query, iterator.next()); this.removeExpiredIndexIfNeeded(index, query.showExpired()); // Memory backend might return empty BackendEntry @@ -507,7 +376,7 @@ private IdHolderList queryByUserprop(ConditionQuery query) { holders.addAll(this.doSearchIndex(query, index)); } else { // Do secondary-index, range-index or shard-index query - IndexQueries queries = index.constructIndexQueries(query); + IndexQueries queries = constructIndexQueries(query, index); assert !paging || queries.size() <= 1; IdHolder holder = this.doSingleOrJointIndex(queries); holders.add(holder); @@ -537,7 +406,7 @@ private IdHolderList doSearchIndex(ConditionQuery query, // Increase limit for union operation increaseLimit(q); } - IndexQueries queries = index.constructIndexQueries(q); + IndexQueries queries = constructIndexQueries(q, index); assert !query.paging() || queries.size() <= 1; IdHolder holder = this.doSingleOrJointIndex(queries); // NOTE: ids will be merged into one IdHolder if not in paging @@ -694,7 +563,7 @@ private IdHolder doIndexQueryBatch(IndexLabel indexLabel, Set ids = InsertionOrderUtil.newSet(); while ((batch == Query.NO_LIMIT || ids.size() < batch) && entries.hasNext()) { - HugeIndex index = this.serializer.readIndex(graph(), query, + Index index = this.serializer.readIndex(graph(), query, entries.next()); this.removeExpiredIndexIfNeeded(index, query.showExpired()); ids.addAll(index.elementIds()); @@ -708,7 +577,7 @@ private IdHolder doIndexQueryBatch(IndexLabel indexLabel, }, this.keepBackendIndexOrder(indexLabel, query)); } - private void recordIndexValue(ConditionQuery query, HugeIndex index) { + private void recordIndexValue(ConditionQuery query, Index index) { if (!shouldRecordIndexValue(query, index)) { return; } @@ -736,7 +605,7 @@ private PageIds doIndexQueryOnce(IndexLabel indexLabel, Set ids = InsertionOrderUtil.newSet(); entries = super.query(query).iterator(); while (entries.hasNext()) { - HugeIndex index = this.serializer.readIndex(graph(), query, + Index index = this.serializer.readIndex(graph(), query, entries.next()); this.removeExpiredIndexIfNeeded(index, query.showExpired()); ids.addAll(index.elementIds()); @@ -882,8 +751,8 @@ private ConditionQuery constructSearchQuery(ConditionQuery query, MatchedIndex i if (key instanceof Id && indexFields.contains(key)) { // This is an index field of search index Id field = (Id) key; - HugeProperty property = element.getProperty(field); - String propValue = propertyValueToString(property.value()); + BaseProperty property = element.getProperty(field); + String propValue = IndexBuilder.propertyValueToString(property.value()); String fieldValue = (String) query.userpropValue(field); if (this.matchSearchIndexWords(propValue, fieldValue)) { continue; @@ -907,46 +776,20 @@ private boolean matchSearchIndexWords(String propValue, String fieldValue) { } private Set segmentWords(String text) { - /* - Support 3 kinds of query: - - Text.contains("(word)"): query by user-specified word; - - Text.contains("(word1|word2|word3)"): query by user-specified words; - - Text.contains("words"): query by words splitted from analyzer; - Note: all kinds support words exact match - */ - if (text.startsWith(START_SYMBOL) && text.endsWith(END_SYMBOL)) { - String subText = text.substring(1, text.length() - 1); - if (subText.contains(WORD_DELIMITER)) { - String[] texts = StringUtils.split(subText, WORD_DELIMITER); - return ImmutableSet.copyOf(texts); - } else { - return ImmutableSet.of(subText); - } - } - Set segments = this.textAnalyzer.segment(text); - - /* - * Add original text to segments at the insertion stage, - * in order to can match fully words at the query stage. - */ - segments.add(text); - - // Ignore unicode \u0000 to \u0003 - segments.removeAll(ConditionQuery.IGNORE_SYM_SET); - return segments; + return this.indexBuilder.segmentWords(text); } private boolean needIndexForLabel() { return !this.store().features().supportsQueryByLabel(); } - private void removeExpiredIndexIfNeeded(HugeIndex index, + private void removeExpiredIndexIfNeeded(Index index, boolean showExpired) { if (this.store().features().supportsTtl() || showExpired) { return; } for (IdWithExpiredTime id : index.expiredElementIds()) { - HugeIndex removeIndex = index.clone(); + Index removeIndex = index.clone(); removeIndex.resetElementIds(); removeIndex.elementIds(id.id(), id.expiredTime()); DeleteExpiredJob.asyncDeleteExpiredObject(this.graph(), @@ -1183,7 +1026,7 @@ private static boolean cmn(List all, int m, int n, } private static boolean shouldRecordIndexValue(ConditionQuery query, - HugeIndex index) { + Index index) { // Currently, only range index has problems return query.originQuery() instanceof ConditionQuery && index.indexLabel().indexType().isRange(); @@ -1506,20 +1349,6 @@ private static Object toCollectionIfNeeded(PropertyKey pk, Object value) { return value; } - private static boolean isCollectionIndex(List propValues) { - return propValues.size() == 1 && - propValues.get(0) instanceof Collection; - } - - private static String propertyValueToString(Object value) { - /* - * Join collection items with white space if the value is Collection, - * or else keep the origin value. - */ - return value instanceof Collection ? - StringUtils.join(((Iterable) value), " ") : value.toString(); - } - private static NoIndexException noIndexException(HugeGraph graph, ConditionQuery query, Id label) { @@ -1557,10 +1386,6 @@ private static void validateIndexLabel(IndexLabel indexLabel) { indexLabel, indexLabel.status()); } - private static boolean hasNullableProp(HugeElement element, Id key) { - return element.schemaLabel().nullableKeys().contains(key); - } - private static Set relatedIndexLabels(HugeElement element) { Set indexLabels = InsertionOrderUtil.newSet(); Set indexLabelIds = element.schemaLabel().indexLabels(); @@ -1586,72 +1411,20 @@ private static void increaseLimit(Query query) { } protected void removeIndex(IndexLabel indexLabel) { - HugeIndex index = new HugeIndex(this.graph(), indexLabel); + Index index = new Index(this.graph(), indexLabel); this.doRemove(this.serializer.writeIndex(index)); } - private static class MatchedIndex { - - private final SchemaLabel schemaLabel; - private final Set indexLabels; - - public MatchedIndex(SchemaLabel schemaLabel, - Set indexLabels) { - this.schemaLabel = schemaLabel; - this.indexLabels = indexLabels; - } - - @SuppressWarnings("unused") - public SchemaLabel schemaLabel() { - return this.schemaLabel; - } - - public Set indexLabels() { - return Collections.unmodifiableSet(this.indexLabels); - } - - public IndexQueries constructIndexQueries(ConditionQuery query) { - // Condition query => Index Queries - if (this.indexLabels().size() == 1) { - /* - * Query by single index or composite index - */ - IndexLabel il = this.indexLabels().iterator().next(); - ConditionQuery indexQuery = constructQuery(query, il); - assert indexQuery != null; - return IndexQueries.of(il, indexQuery); - } else { - /* - * Query by joint indexes - */ - IndexQueries queries = buildJointIndexesQueries(query, this); - assert !queries.isEmpty(); - return queries; - } - } - - public boolean containsSearchIndex() { - for (IndexLabel il : this.indexLabels) { - if (il.indexType().isSearch()) { - return true; - } - } - return false; - } - - @Override - public int hashCode() { - return this.indexLabels.hashCode(); - } - - @Override - public boolean equals(Object other) { - if (!(other instanceof MatchedIndex)) { - return false; - } - Set indexLabels = ((MatchedIndex) other).indexLabels; - return Objects.equals(this.indexLabels, indexLabels); + private static IndexQueries constructIndexQueries(ConditionQuery query, MatchedIndex index) { + if (index.indexLabels().size() == 1) { + IndexLabel label = index.indexLabels().iterator().next(); + ConditionQuery indexQuery = constructQuery(query, label); + assert indexQuery != null; + return IndexQueries.of(label, indexQuery); } + IndexQueries queries = buildJointIndexesQueries(query, index); + assert !queries.isEmpty(); + return queries; } private static class IndexQueries @@ -1832,7 +1605,7 @@ private long processRangeIndexLeft(ConditionQuery query, AbstractSerializer serializer = this.tx.serializer; for (Object value : indexValues) { - HugeIndex index = new HugeIndex(this.graph(), indexLabel); + Index index = new Index(this.graph(), indexLabel); index.elementIds(element.id()); index.fieldValues(value); this.tx.doEliminate(serializer.writeIndex(index)); @@ -1947,7 +1720,7 @@ private boolean deletedByError(ConditionQuery query, if (elem == null) { return false; } - return query.test(elem); + return query.test(elem.element()); } private boolean deletedByError(HugeElement element, diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/GraphTransaction.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/GraphTransaction.java index 77ea7784ea..e807b74fb3 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/GraphTransaction.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/GraphTransaction.java @@ -33,24 +33,24 @@ import java.util.stream.Collectors; import org.apache.commons.collections.CollectionUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.SplicingIdGenerator; +import org.apache.hugegraph.exception.BackendException; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.SplicingIdGenerator; import org.apache.hugegraph.backend.page.IdHolderList; import org.apache.hugegraph.backend.page.PageInfo; import org.apache.hugegraph.backend.page.QueryList; -import org.apache.hugegraph.backend.query.Aggregate; -import org.apache.hugegraph.backend.query.Aggregate.AggregateFunc; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.ConditionQuery.OptimizedType; +import org.apache.hugegraph.query.Aggregate; +import org.apache.hugegraph.query.Aggregate.AggregateFunc; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.ConditionQuery.OptimizedType; import org.apache.hugegraph.backend.query.ConditionQueryFlatten; -import org.apache.hugegraph.backend.query.IdQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.IdQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.query.QueryBatch; import org.apache.hugegraph.backend.query.QueryResultContext; import org.apache.hugegraph.backend.query.QueryResults; @@ -69,17 +69,17 @@ import org.apache.hugegraph.iterator.MapperIterator; import org.apache.hugegraph.job.system.DeleteExpiredJob; import org.apache.hugegraph.perf.PerfUtil.Watched; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.schema.SchemaLabel; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.SchemaLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeEdgeProperty; import org.apache.hugegraph.structure.HugeElement; import org.apache.hugegraph.structure.HugeFeatures.HugeVertexFeatures; -import org.apache.hugegraph.structure.HugeIndex; +import org.apache.hugegraph.structure.Index; import org.apache.hugegraph.structure.HugeProperty; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.structure.HugeVertexProperty; @@ -547,7 +547,7 @@ public QueryResults query(Query query) { public Number queryNumber(Query query) { boolean isConditionQuery = query instanceof ConditionQuery; boolean hasUpdate = this.hasUpdate(); - Aggregate aggregate = query.aggregateNotNull(); + Aggregate aggregate = query.aggregateNotNull(); if (hasUpdate && (query.resultType() == HugeType.VERTEX || query.resultType() == HugeType.EDGE)) { @@ -1951,7 +1951,7 @@ private boolean rightResultFromIndexQuery(QueryResultContext context, HugeElemen } } - if (!context.conditionFilterRequired() || cq.test(elem, context.resultsFilter())) { + if (!context.conditionFilterRequired() || cq.test(elem.element(), context.resultsFilter())) { if (cq.existLeftIndex(elem.id())) { /* * Both have correct and left index, wo should return true @@ -2031,7 +2031,7 @@ private Iterator joinTxVertices(Query query, return null; } // Filter vertices matched conditions - return q.test(v) ? v : null; + return q.test(v.element()) ? v : null; }; vertices = this.joinTxRecords(query, vertices, matchTxFunc, this.addedVertices, this.removedVertices, @@ -2049,7 +2049,7 @@ private Iterator joinTxEdges(Query query, Iterator edges, return null; } // Filter edges matched conditions - return q.test(e) ? e : q.test(e = e.switchOwner()) ? e : null; + return q.test(e.element()) ? e : q.test((e = e.switchOwner()).element()) ? e : null; }; edges = this.joinTxRecords(query, edges, matchTxFunc, this.addedEdges, this.removedEdges, @@ -2063,7 +2063,7 @@ private Iterator joinTxEdges(Query query, Iterator edges, (this.addedEdges.containsKey(edge.id()) || this.updatedEdges.containsKey(edge.id()))) { HugeEdge opposite = edge.switchOwner(); - if (query.test(opposite)) { + if (query.test(opposite.element())) { return ImmutableList.of(edge, opposite).iterator(); } } @@ -2214,7 +2214,7 @@ public void updateIndex(Id ilId, HugeElement element, boolean removed) { this.indexTx.updateIndex(ilId, element, removed); } - public void removeIndex(HugeIndex index) { + public void removeIndex(Index index) { // TODO: use event to replace direct call this.checkOwnerThread(); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/ISchemaTransaction.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/ISchemaTransaction.java index dce1276ced..f7eb879152 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/ISchemaTransaction.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/ISchemaTransaction.java @@ -20,13 +20,13 @@ import java.util.List; import java.util.Set; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.schema.SchemaLabel; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.SchemaLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.GraphMode; import org.apache.hugegraph.type.define.SchemaStatus; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/IdCounter.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/IdCounter.java index 87a10ce2c8..9d1ee4c845 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/IdCounter.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/IdCounter.java @@ -17,16 +17,16 @@ package org.apache.hugegraph.backend.tx; +import java.util.AbstractMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.exception.BackendException; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.pd.client.PDClient; import org.apache.hugegraph.pd.grpc.Pdpb; -import org.apache.hugegraph.store.term.HgPair; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.util.E; @@ -35,7 +35,7 @@ public class IdCounter { private static final int TIMES = 10000; private static final int DELTA = 10000; private static final String DELIMITER = "/"; - private static final Map> ids = + private static final Map> ids = new ConcurrentHashMap<>(); private final PDClient pdClient; private final String graphName; @@ -68,7 +68,7 @@ public long getCounter(HugeType type) { public synchronized void increaseCounter(HugeType type, long lowest) { String key = toKey(this.graphName, type); getCounterFromPd(type); - HgPair idPair = ids.get(key); + Map.Entry idPair = ids.get(key); AtomicLong currentId = idPair.getKey(); AtomicLong maxId = idPair.getValue(); if (currentId.longValue() >= lowest) { @@ -97,7 +97,7 @@ protected String toKey(String graphName, HugeType type) { public long getCounterFromPd(HugeType type) { AtomicLong currentId; AtomicLong maxId; - HgPair idPair; + Map.Entry idPair; String key = toKey(this.graphName, type); if ((idPair = ids.get(key)) == null) { synchronized (ids) { @@ -105,7 +105,7 @@ public long getCounterFromPd(HugeType type) { try { currentId = new AtomicLong(0); maxId = new AtomicLong(0); - idPair = new HgPair<>(currentId, maxId); + idPair = new AbstractMap.SimpleImmutableEntry<>(currentId, maxId); ids.put(key, idPair); } catch (Exception e) { throw new BackendException(String.format( diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/IndexableTransaction.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/IndexableTransaction.java index 7c481b05c2..8a3963989e 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/IndexableTransaction.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/IndexableTransaction.java @@ -18,7 +18,7 @@ package org.apache.hugegraph.backend.tx; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.backend.store.BackendMutation; import org.apache.hugegraph.backend.store.BackendStore; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/SchemaIndexTransaction.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/SchemaIndexTransaction.java index 1fbade3190..c6122537bf 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/SchemaIndexTransaction.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/SchemaIndexTransaction.java @@ -20,16 +20,16 @@ import java.util.Iterator; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.IdQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.IdQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.backend.store.BackendStore; import org.apache.hugegraph.perf.PerfUtil.Watched; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.structure.HugeIndex; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.structure.Index; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.HugeKeys; import org.apache.hugegraph.util.E; @@ -49,7 +49,7 @@ public void updateNameIndex(SchemaElement element, boolean removed) { IndexLabel indexLabel = IndexLabel.label(element.type()); // Update name index if backend store not supports name-query - HugeIndex index = new HugeIndex(this.graph(), indexLabel); + Index index = new Index(this.graph(), indexLabel); index.fieldValues(element.name()); index.elementIds(element.id()); @@ -96,7 +96,7 @@ private QueryResults queryByName(ConditionQuery query) { Iterator entries = super.query(indexQuery).iterator(); try { while (entries.hasNext()) { - HugeIndex index = this.serializer.readIndex(graph(), indexQuery, + Index index = this.serializer.readIndex(graph(), indexQuery, entries.next()); idQuery.query(index.elementIds()); Query.checkForceCapacity(idQuery.idsSize()); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/SchemaTransaction.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/SchemaTransaction.java index f09c45cf71..af6e3dedc5 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/SchemaTransaction.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/SchemaTransaction.java @@ -25,12 +25,12 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.backend.LocalCounter; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.backend.store.BackendStore; @@ -47,13 +47,13 @@ import org.apache.hugegraph.job.schema.SchemaJob; import org.apache.hugegraph.job.schema.VertexLabelRemoveJob; import org.apache.hugegraph.perf.PerfUtil.Watched; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.schema.SchemaLabel; -import org.apache.hugegraph.schema.Userdata; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.SchemaLabel; +import org.apache.hugegraph.struct.schema.Userdata; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.task.HugeTask; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.GraphMode; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/SchemaTransactionV2.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/SchemaTransactionV2.java index 5eed063dae..5fcc35b46f 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/SchemaTransactionV2.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/SchemaTransactionV2.java @@ -23,8 +23,8 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.config.CoreOptions; import org.apache.hugegraph.exception.NotAllowException; import org.apache.hugegraph.job.JobBuilder; @@ -41,13 +41,13 @@ import org.apache.hugegraph.meta.PdMetaDriver; import org.apache.hugegraph.meta.managers.SchemaMetaManager; import org.apache.hugegraph.perf.PerfUtil.Watched; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.schema.SchemaLabel; -import org.apache.hugegraph.schema.Userdata; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.SchemaLabel; +import org.apache.hugegraph.struct.schema.Userdata; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.task.HugeTask; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.GraphMode; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/config/CoreOptions.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/config/CoreOptions.java index bbd634eb73..2f4e0d2cad 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/config/CoreOptions.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/config/CoreOptions.java @@ -17,13 +17,13 @@ package org.apache.hugegraph.config; -import org.apache.hugegraph.backend.query.Query; -import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.query.Query; +import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.backend.tx.GraphTransaction; import org.apache.hugegraph.type.define.CollectionType; import org.apache.hugegraph.util.Bytes; -import static org.apache.hugegraph.backend.query.Query.COMMIT_BATCH; +import static org.apache.hugegraph.query.Query.COMMIT_BATCH; import static org.apache.hugegraph.config.OptionChecker.*; public class CoreOptions extends OptionHolder { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/ConnectionException.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/ConnectionException.java index e6dc311815..70ac1bd1b7 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/ConnectionException.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/ConnectionException.java @@ -17,7 +17,7 @@ package org.apache.hugegraph.exception; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; public class ConnectionException extends HugeException { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/ErrorCodeProvider.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/ErrorCodeProvider.java deleted file mode 100644 index a5777f9fd1..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/ErrorCodeProvider.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2017 HugeGraph Authors - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package org.apache.hugegraph.exception; - -public interface ErrorCodeProvider { - - String format(Object... args); - - String with(String message); -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/ExistedException.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/ExistedException.java index b121588f0f..f6f64edf5d 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/ExistedException.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/ExistedException.java @@ -17,7 +17,7 @@ package org.apache.hugegraph.exception; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.type.HugeType; public class ExistedException extends HugeException { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/NoIndexException.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/NoIndexException.java index 3c1c788aee..2f72997972 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/NoIndexException.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/NoIndexException.java @@ -17,7 +17,7 @@ package org.apache.hugegraph.exception; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; public class NoIndexException extends HugeException { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/NotAllowException.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/NotAllowException.java deleted file mode 100644 index 24bb495d7a..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/NotAllowException.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.exception; - -import org.apache.hugegraph.HugeException; - -public class NotAllowException extends HugeException { - - private static final long serialVersionUID = -1407924451828873200L; - - public NotAllowException(String message) { - super(message); - } - - public NotAllowException(String message, Object... args) { - super(message, args); - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/io/GraphSONSchemaSerializer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/io/GraphSONSchemaSerializer.java index db8d874e8e..208c96d4e8 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/io/GraphSONSchemaSerializer.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/io/GraphSONSchemaSerializer.java @@ -22,11 +22,11 @@ import com.google.common.collect.ImmutableList; -import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.HugeGraphSupplier; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.EdgeLabelType; import org.apache.hugegraph.type.define.HugeKeys; @@ -34,7 +34,7 @@ public class GraphSONSchemaSerializer { public Map writeVertexLabel(VertexLabel vertexLabel) { - HugeGraph graph = vertexLabel.graph(); + HugeGraphSupplier graph = vertexLabel.graph(); assert graph != null; Map map = new LinkedHashMap<>(); @@ -61,7 +61,7 @@ public Map writeVertexLabel(VertexLabel vertexLabel) { } public Map writeEdgeLabel(EdgeLabel edgeLabel) { - HugeGraph graph = edgeLabel.graph(); + HugeGraphSupplier graph = edgeLabel.graph(); assert graph != null; Map map = new LinkedHashMap<>(); @@ -110,7 +110,7 @@ public Map writeEdgeLabel(EdgeLabel edgeLabel) { } public Map writePropertyKey(PropertyKey propertyKey) { - HugeGraph graph = propertyKey.graph(); + HugeGraphSupplier graph = propertyKey.graph(); assert graph != null; Map map = new LinkedHashMap<>(); @@ -128,7 +128,7 @@ public Map writePropertyKey(PropertyKey propertyKey) { } public Map writeIndexLabel(IndexLabel indexLabel) { - HugeGraph graph = indexLabel.graph(); + HugeGraphSupplier graph = indexLabel.graph(); assert graph != null; Map map = new LinkedHashMap<>(); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/io/HugeGraphSONModule.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/io/HugeGraphSONModule.java index c7758989fe..158efdb2c4 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/io/HugeGraphSONModule.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/io/HugeGraphSONModule.java @@ -33,18 +33,18 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.id.IdGenerator.LongId; -import org.apache.hugegraph.backend.id.IdGenerator.StringId; -import org.apache.hugegraph.backend.id.IdGenerator.UuidId; -import org.apache.hugegraph.backend.store.Shard; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.exception.HugeException; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.id.IdGenerator.LongId; +import org.apache.hugegraph.id.IdGenerator.StringId; +import org.apache.hugegraph.id.IdGenerator.UuidId; +import org.apache.hugegraph.backend.Shard; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.space.GraphSpace; import org.apache.hugegraph.space.Service; import org.apache.hugegraph.structure.HugeEdge; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/io/HugeGraphTypeSerializerRegistryBuilder.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/io/HugeGraphTypeSerializerRegistryBuilder.java index 28cb79bd74..d86eac92a6 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/io/HugeGraphTypeSerializerRegistryBuilder.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/io/HugeGraphTypeSerializerRegistryBuilder.java @@ -28,14 +28,14 @@ import java.util.Optional; import java.util.function.Function; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.store.Shard; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.SchemaElement; +import org.apache.hugegraph.backend.Shard; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.type.define.HugeKeys; import org.apache.hugegraph.util.Blob; import org.apache.tinkerpop.gremlin.structure.io.Buffer; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/io/HugeGryoModule.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/io/HugeGryoModule.java index 0feee228f6..cc1cbe6040 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/io/HugeGryoModule.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/io/HugeGryoModule.java @@ -21,14 +21,14 @@ import java.util.Map; import java.util.Optional; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.Id.IdType; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.Id.IdType; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.type.define.HugeKeys; import org.apache.hugegraph.util.StringEncoding; import org.apache.tinkerpop.gremlin.structure.io.gryo.GryoIo; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/EphemeralJobBuilder.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/EphemeralJobBuilder.java index a8a0966fa7..785a2563ea 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/EphemeralJobBuilder.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/EphemeralJobBuilder.java @@ -18,8 +18,8 @@ package org.apache.hugegraph.job; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.task.HugeTask; import org.apache.hugegraph.task.TaskScheduler; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/GremlinJob.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/GremlinJob.java index 8bde61feb4..01c03d18ed 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/GremlinJob.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/GremlinJob.java @@ -22,7 +22,7 @@ import java.util.List; import java.util.Map; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.exception.LimitExceedException; import org.apache.hugegraph.traversal.optimize.HugeScriptTraversal; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/JobBuilder.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/JobBuilder.java index fc7067b419..0ee870030f 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/JobBuilder.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/JobBuilder.java @@ -20,7 +20,7 @@ import java.util.Set; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.task.HugeTask; import org.apache.hugegraph.task.TaskCallable; import org.apache.hugegraph.task.TaskScheduler; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/AbstractAlgorithm.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/AbstractAlgorithm.java index b30d3ac83a..ce72882d03 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/AbstractAlgorithm.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/AbstractAlgorithm.java @@ -29,10 +29,10 @@ import org.apache.commons.lang3.StringEscapeUtils; import org.apache.commons.lang3.mutable.MutableLong; -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.exception.HugeException; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.iterator.FilterIterator; import org.apache.hugegraph.iterator.FlatMapperIterator; import org.apache.hugegraph.job.UserJob; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/BfsTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/BfsTraverser.java index 4a6cda246e..ba73e2bd29 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/BfsTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/BfsTraverser.java @@ -23,7 +23,7 @@ import java.util.Map; import java.util.Stack; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.job.UserJob; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.type.define.Directions; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/Consumers.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/Consumers.java index dc04bdf605..81680dbfa6 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/Consumers.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/Consumers.java @@ -25,7 +25,7 @@ import java.util.concurrent.TimeUnit; import java.util.function.Consumer; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.task.TaskManager.ContextCallable; import org.apache.hugegraph.util.ExecutorUtil; import org.apache.hugegraph.util.Log; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/SubgraphStatAlgorithm.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/SubgraphStatAlgorithm.java index d6a1be8aa2..6646fae82d 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/SubgraphStatAlgorithm.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/SubgraphStatAlgorithm.java @@ -23,7 +23,7 @@ import org.apache.commons.configuration2.PropertiesConfiguration; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.StandardHugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.config.CoreOptions; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.job.UserJob; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/AbstractCentAlgorithm.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/AbstractCentAlgorithm.java index 8ab6ca81f7..d34c245639 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/AbstractCentAlgorithm.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/AbstractCentAlgorithm.java @@ -17,6 +17,8 @@ package org.apache.hugegraph.job.algorithm.cent; +import org.apache.hugegraph.util.TinkerPopUtil; + import java.util.Collections; import java.util.HashMap; import java.util.Iterator; @@ -24,7 +26,7 @@ import java.util.Map; import org.apache.commons.lang3.tuple.Pair; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.iterator.MapperIterator; import org.apache.hugegraph.job.UserJob; import org.apache.hugegraph.job.algorithm.AbstractAlgorithm; @@ -114,7 +116,7 @@ protected GraphTraversal constructPathUnit( if (dir == null) { dir = Directions.BOTH; } - Direction direction = dir.direction(); + Direction direction = TinkerPopUtil.direction(dir); String[] labels = {}; if (label != null) { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/BetweennessCentralityAlgorithm.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/BetweennessCentralityAlgorithm.java index 512d14a158..a3e267a146 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/BetweennessCentralityAlgorithm.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/BetweennessCentralityAlgorithm.java @@ -23,8 +23,8 @@ import java.util.Map; import org.apache.commons.lang3.mutable.MutableFloat; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.SplicingIdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.SplicingIdGenerator; import org.apache.hugegraph.job.UserJob; import org.apache.hugegraph.structure.HugeElement; import org.apache.hugegraph.type.define.Directions; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/BetweennessCentralityAlgorithmV2.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/BetweennessCentralityAlgorithmV2.java index ca99fddf8d..0bace3503b 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/BetweennessCentralityAlgorithmV2.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/BetweennessCentralityAlgorithmV2.java @@ -22,8 +22,8 @@ import java.util.Map; import org.apache.commons.lang3.mutable.MutableFloat; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.job.UserJob; import org.apache.hugegraph.job.algorithm.BfsTraverser; import org.apache.hugegraph.structure.HugeVertex; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/ClosenessCentralityAlgorithmV2.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/ClosenessCentralityAlgorithmV2.java index 1519a2a456..ce92864ff5 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/ClosenessCentralityAlgorithmV2.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/ClosenessCentralityAlgorithmV2.java @@ -20,8 +20,8 @@ import java.util.Iterator; import java.util.Map; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.exception.NotSupportException; import org.apache.hugegraph.job.UserJob; import org.apache.hugegraph.job.algorithm.BfsTraverser; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/DegreeCentralityAlgorithm.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/DegreeCentralityAlgorithm.java index 19e68c0531..72d2ae7da2 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/DegreeCentralityAlgorithm.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/DegreeCentralityAlgorithm.java @@ -22,7 +22,7 @@ import java.util.List; import java.util.Map; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.job.UserJob; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.traversal.algorithm.steps.EdgeStep; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/StressCentralityAlgorithmV2.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/StressCentralityAlgorithmV2.java index d1c3da6d8d..e0614a42aa 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/StressCentralityAlgorithmV2.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/cent/StressCentralityAlgorithmV2.java @@ -22,8 +22,8 @@ import java.util.Map; import org.apache.commons.lang3.mutable.MutableLong; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.job.UserJob; import org.apache.hugegraph.job.algorithm.BfsTraverser; import org.apache.hugegraph.structure.HugeVertex; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/comm/KCoreAlgorithm.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/comm/KCoreAlgorithm.java index eb334e5cbe..f0c9502109 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/comm/KCoreAlgorithm.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/comm/KCoreAlgorithm.java @@ -27,7 +27,7 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.mutable.MutableInt; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.job.UserJob; import org.apache.hugegraph.traversal.algorithm.FusiformSimilarityTraverser; import org.apache.hugegraph.type.define.Directions; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/comm/LouvainTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/comm/LouvainTraverser.java index d30e798d41..6ac8022685 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/comm/LouvainTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/comm/LouvainTraverser.java @@ -38,17 +38,17 @@ import org.apache.commons.lang.mutable.MutableFloat; import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.lang3.tuple.Pair; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.exception.ExistedException; import org.apache.hugegraph.iterator.ListIterator; import org.apache.hugegraph.job.UserJob; import org.apache.hugegraph.job.algorithm.AbstractAlgorithm; import org.apache.hugegraph.job.algorithm.AbstractAlgorithm.AlgoTraverser; import org.apache.hugegraph.job.algorithm.Consumers; -import org.apache.hugegraph.schema.SchemaLabel; +import org.apache.hugegraph.struct.schema.SchemaLabel; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.type.define.Directions; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/comm/LpaAlgorithm.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/comm/LpaAlgorithm.java index 4b2e30db3e..e729d378e8 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/comm/LpaAlgorithm.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/comm/LpaAlgorithm.java @@ -26,10 +26,10 @@ import java.util.concurrent.atomic.AtomicLong; import org.apache.commons.lang3.mutable.MutableInt; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.job.UserJob; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.type.define.Directions; import org.apache.hugegraph.util.E; import org.apache.tinkerpop.gremlin.process.traversal.Scope; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/comm/TriangleCountAlgorithm.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/comm/TriangleCountAlgorithm.java index 3e5c6c6370..411a730008 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/comm/TriangleCountAlgorithm.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/comm/TriangleCountAlgorithm.java @@ -24,8 +24,8 @@ import java.util.concurrent.atomic.AtomicLong; import org.apache.commons.lang.mutable.MutableLong; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.job.UserJob; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.type.define.Directions; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/comm/WeakConnectedComponent.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/comm/WeakConnectedComponent.java index 674ec50235..25dab78af4 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/comm/WeakConnectedComponent.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/comm/WeakConnectedComponent.java @@ -23,10 +23,10 @@ import java.util.List; import java.util.Map; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.job.UserJob; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.type.define.Directions; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/path/RingsDetectAlgorithm.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/path/RingsDetectAlgorithm.java index f4e069c252..4bf53ae2bc 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/path/RingsDetectAlgorithm.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/path/RingsDetectAlgorithm.java @@ -20,7 +20,7 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicLong; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.job.UserJob; import org.apache.hugegraph.job.algorithm.AbstractAlgorithm; import org.apache.hugegraph.job.algorithm.Consumers.StopExecution; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/rank/PageRankAlgorithm.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/rank/PageRankAlgorithm.java index a7a189ea31..0d70bfaae3 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/rank/PageRankAlgorithm.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/algorithm/rank/PageRankAlgorithm.java @@ -23,11 +23,11 @@ import java.util.List; import java.util.Map; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.job.UserJob; import org.apache.hugegraph.job.algorithm.comm.AbstractCommAlgorithm; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.traversal.algorithm.HugeTraverser; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/computer/AbstractComputer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/computer/AbstractComputer.java index 5158ec7916..cb7e764f22 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/computer/AbstractComputer.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/computer/AbstractComputer.java @@ -32,7 +32,7 @@ import org.apache.commons.configuration2.tree.ImmutableNode; import org.apache.commons.configuration2.tree.NodeHandler; import org.apache.commons.configuration2.tree.NodeModel; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.job.ComputerJob; import org.apache.hugegraph.job.Job; import org.apache.hugegraph.traversal.algorithm.HugeTraverser; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/EdgeLabelRemoveJob.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/EdgeLabelRemoveJob.java index 00462b9d78..e9963805fe 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/EdgeLabelRemoveJob.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/EdgeLabelRemoveJob.java @@ -20,10 +20,10 @@ import java.util.Set; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.tx.GraphTransaction; import org.apache.hugegraph.backend.tx.ISchemaTransaction; -import org.apache.hugegraph.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; import org.apache.hugegraph.type.define.SchemaStatus; import org.apache.hugegraph.util.LockUtil; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/IndexLabelRebuildJob.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/IndexLabelRebuildJob.java index 9bf0142d76..0a0e198524 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/IndexLabelRebuildJob.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/IndexLabelRebuildJob.java @@ -22,14 +22,14 @@ import java.util.function.Consumer; import java.util.stream.Collectors; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.tx.GraphTransaction; import org.apache.hugegraph.backend.tx.ISchemaTransaction; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.schema.SchemaLabel; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.SchemaLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeElement; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.SchemaStatus; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/IndexLabelRemoveJob.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/IndexLabelRemoveJob.java index a8d8e1578d..2331202562 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/IndexLabelRemoveJob.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/IndexLabelRemoveJob.java @@ -18,10 +18,10 @@ package org.apache.hugegraph.job.schema; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.tx.GraphTransaction; import org.apache.hugegraph.backend.tx.ISchemaTransaction; -import org.apache.hugegraph.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; import org.apache.hugegraph.type.define.SchemaStatus; import org.apache.hugegraph.util.LockUtil; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/OlapPropertyKeyClearJob.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/OlapPropertyKeyClearJob.java index e82ca0c0a6..377b68a8be 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/OlapPropertyKeyClearJob.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/OlapPropertyKeyClearJob.java @@ -18,10 +18,10 @@ package org.apache.hugegraph.job.schema; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.tx.GraphTransaction; import org.apache.hugegraph.backend.tx.ISchemaTransaction; -import org.apache.hugegraph.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; import org.apache.hugegraph.type.define.SchemaStatus; import org.apache.hugegraph.util.LockUtil; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/OlapPropertyKeyCreateJob.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/OlapPropertyKeyCreateJob.java index 483b9106f8..367960e1aa 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/OlapPropertyKeyCreateJob.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/OlapPropertyKeyCreateJob.java @@ -18,7 +18,7 @@ package org.apache.hugegraph.job.schema; import org.apache.hugegraph.backend.tx.ISchemaTransaction; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.PropertyKey; public class OlapPropertyKeyCreateJob extends SchemaJob { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/OlapPropertyKeyRemoveJob.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/OlapPropertyKeyRemoveJob.java index e6f5f20e0c..6b9b5471f4 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/OlapPropertyKeyRemoveJob.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/OlapPropertyKeyRemoveJob.java @@ -17,9 +17,9 @@ package org.apache.hugegraph.job.schema; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.tx.ISchemaTransaction; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.PropertyKey; public class OlapPropertyKeyRemoveJob extends OlapPropertyKeyClearJob { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/SchemaJob.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/SchemaJob.java index 3165351396..01d456f368 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/SchemaJob.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/SchemaJob.java @@ -20,11 +20,11 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.tx.ISchemaTransaction; import org.apache.hugegraph.job.SysJob; -import org.apache.hugegraph.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.SchemaElement; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.util.E; import org.apache.hugegraph.util.Log; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/VertexLabelRemoveJob.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/VertexLabelRemoveJob.java index 90bc469124..4c95840321 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/VertexLabelRemoveJob.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/schema/VertexLabelRemoveJob.java @@ -20,13 +20,13 @@ import java.util.List; import java.util.Set; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.tx.GraphTransaction; import org.apache.hugegraph.backend.tx.ISchemaTransaction; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.type.define.SchemaStatus; import org.apache.hugegraph.util.LockUtil; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/system/DeleteExpiredIndexJob.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/system/DeleteExpiredIndexJob.java index 5556febb89..459b8de465 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/system/DeleteExpiredIndexJob.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/system/DeleteExpiredIndexJob.java @@ -21,10 +21,10 @@ import java.util.Set; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.query.IdQuery; +import org.apache.hugegraph.query.IdQuery; import org.apache.hugegraph.backend.tx.GraphTransaction; import org.apache.hugegraph.structure.HugeElement; -import org.apache.hugegraph.structure.HugeIndex; +import org.apache.hugegraph.structure.Index; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.util.E; @@ -32,9 +32,9 @@ public class DeleteExpiredIndexJob extends DeleteExpiredJob { private static final String JOB_TYPE = "delete_expired_index"; - private final Set indexes; + private final Set indexes; - public DeleteExpiredIndexJob(Set indexes) { + public DeleteExpiredIndexJob(Set indexes) { E.checkArgument(indexes != null && !indexes.isEmpty(), "The indexes can't be null or empty"); this.indexes = indexes; @@ -52,7 +52,7 @@ public V execute() throws Exception { HugeGraphParams graph = this.params(); GraphTransaction tx = graph.graphTransaction(); try { - for (HugeIndex index : this.indexes) { + for (Index index : this.indexes) { this.deleteExpiredIndex(graph, index); } tx.commit(); @@ -70,7 +70,7 @@ public V execute() throws Exception { * Delete expired element(if exist) of the index, * otherwise just delete expired index only */ - private void deleteExpiredIndex(HugeGraphParams graph, HugeIndex index) { + private void deleteExpiredIndex(HugeGraphParams graph, Index index) { GraphTransaction tx = graph.graphTransaction(); HugeType type = index.indexLabel().queryType().isVertex() ? HugeType.VERTEX : HugeType.EDGE; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/system/DeleteExpiredJob.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/system/DeleteExpiredJob.java index 9ffa9e955b..28f4012c88 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/system/DeleteExpiredJob.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/system/DeleteExpiredJob.java @@ -23,7 +23,7 @@ import org.apache.hugegraph.job.EphemeralJobBuilder; import org.apache.hugegraph.job.system.JobCounters.JobCounter; import org.apache.hugegraph.structure.HugeElement; -import org.apache.hugegraph.structure.HugeIndex; +import org.apache.hugegraph.structure.Index; import org.apache.hugegraph.task.HugeTask; import org.apache.hugegraph.util.E; import org.apache.hugegraph.util.Log; @@ -80,7 +80,7 @@ public static EphemeralJob newDeleteExpiredElementJob( if (object instanceof HugeElement) { return new DeleteExpiredElementJob<>(jobCounter.elements()); } else { - assert object instanceof HugeIndex; + assert object instanceof Index; return new DeleteExpiredIndexJob<>(jobCounter.indexes()); } } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/system/JobCounters.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/system/JobCounters.java index 6feed5699c..848a821058 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/system/JobCounters.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/job/system/JobCounters.java @@ -24,7 +24,7 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.config.CoreOptions; import org.apache.hugegraph.structure.HugeElement; -import org.apache.hugegraph.structure.HugeIndex; +import org.apache.hugegraph.structure.Index; public class JobCounters { @@ -43,7 +43,7 @@ public static class JobCounter { private final AtomicInteger jobs; private Set elements; - private Set indexes; + private Set indexes; private final int batchSize; public JobCounter(int batchSize) { @@ -69,7 +69,7 @@ public Set elements() { return this.elements; } - public Set indexes() { + public Set indexes() { return this.indexes; } @@ -77,7 +77,7 @@ public void clear(Object object) { if (object instanceof HugeElement) { this.elements = ConcurrentHashMap.newKeySet(); } else { - assert object instanceof HugeIndex; + assert object instanceof Index; this.indexes = ConcurrentHashMap.newKeySet(); } } @@ -85,7 +85,7 @@ public void clear(Object object) { public boolean addAndTriggerDelete(Object object) { return object instanceof HugeElement ? addElementAndTriggerDelete((HugeElement) object) : - addIndexAndTriggerDelete((HugeIndex) object); + addIndexAndTriggerDelete((Index) object); } /** @@ -108,7 +108,7 @@ public boolean addElementAndTriggerDelete(HugeElement element) { * @param index * @return true if we should create a new delete job, false otherwise */ - public boolean addIndexAndTriggerDelete(HugeIndex index) { + public boolean addIndexAndTriggerDelete(Index index) { if (this.indexes.size() >= this.batchSize) { return true; } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/k8s/K8sDriver.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/k8s/K8sDriver.java index 47a34658fd..61b3340fdc 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/k8s/K8sDriver.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/k8s/K8sDriver.java @@ -31,7 +31,7 @@ import io.fabric8.kubernetes.client.dsl.ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable; import io.fabric8.kubernetes.client.dsl.Resource; import org.apache.commons.io.FileUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.space.GraphSpace; import org.apache.hugegraph.space.Service; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/k8s/K8sManager.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/k8s/K8sManager.java index 11db1adf32..1e3057c860 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/k8s/K8sManager.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/k8s/K8sManager.java @@ -19,7 +19,7 @@ import com.google.common.base.Strings; import io.fabric8.kubernetes.api.model.Namespace; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.config.CoreOptions; import org.apache.hugegraph.space.GraphSpace; import org.apache.hugegraph.space.Service; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/k8s/K8sRegister.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/k8s/K8sRegister.java index c1dd29abc8..73701f463e 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/k8s/K8sRegister.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/k8s/K8sRegister.java @@ -23,7 +23,7 @@ import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/kvstore/KvStore.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/kvstore/KvStore.java index 569af417f4..94ed2a32a7 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/kvstore/KvStore.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/kvstore/KvStore.java @@ -23,7 +23,7 @@ import java.util.List; import java.util.Map; -import org.apache.hugegraph.backend.store.Shard; +import org.apache.hugegraph.backend.Shard; import org.apache.tinkerpop.gremlin.structure.Vertex; public interface KvStore { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/masterelection/GlobalMasterInfo.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/masterelection/GlobalMasterInfo.java index ef7c2f338d..668c0413f6 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/masterelection/GlobalMasterInfo.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/masterelection/GlobalMasterInfo.java @@ -17,8 +17,8 @@ package org.apache.hugegraph.masterelection; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.type.define.NodeRole; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/factory/IdFactory.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/factory/IdFactory.java index 976b9cb373..e05d50326c 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/factory/IdFactory.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/factory/IdFactory.java @@ -17,13 +17,15 @@ package org.apache.hugegraph.memory.consumer.factory; +import org.apache.hugegraph.backend.BinaryId; + import java.util.UUID; import org.apache.hugegraph.backend.cache.CachedBackendStore; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.serializer.BinaryBackendEntry; import org.apache.hugegraph.memory.MemoryManager; import org.apache.hugegraph.memory.consumer.OffHeapObject; @@ -50,7 +52,7 @@ private IdFactory() { /** * If using off-heap mode, param id must be OffHeapObject */ - public BinaryBackendEntry.BinaryId newBinaryId(byte[] bytes, Id id) { + public BinaryId newBinaryId(byte[] bytes, Id id) { switch (memoryMode) { case ENABLE_ON_HEAP_MANAGEMENT: case ENABLE_OFF_HEAP_MANAGEMENT: @@ -63,7 +65,7 @@ public BinaryBackendEntry.BinaryId newBinaryId(byte[] bytes, Id id) { (OffHeapObject) id); case DISABLE_MEMORY_MANAGEMENT: default: - return new BinaryBackendEntry.BinaryId(bytes, id); + return new BinaryId(bytes, id); } } @@ -238,8 +240,8 @@ public EdgeId newEdgeId(HugeVertex ownerVertex, ); case DISABLE_MEMORY_MANAGEMENT: default: - return new EdgeId(ownerVertex, direction, edgeLabelId, subLabelId, sortValues, - otherVertex); + return new EdgeId(ownerVertex.id(), direction, edgeLabelId, subLabelId, sortValues, + otherVertex.id()); } } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/factory/PropertyFactory.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/factory/PropertyFactory.java index c628155eb1..896e25248a 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/factory/PropertyFactory.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/factory/PropertyFactory.java @@ -24,7 +24,7 @@ import org.apache.hugegraph.memory.consumer.impl.property.HugeEdgePropertyOffHeap; import org.apache.hugegraph.memory.consumer.impl.property.HugeVertexPropertyOffHeap; import org.apache.hugegraph.memory.pool.impl.TaskMemoryPool; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.structure.HugeEdgeProperty; import org.apache.hugegraph.structure.HugeElement; import org.apache.hugegraph.structure.HugeVertexProperty; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/BinaryIdOffHeap.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/BinaryIdOffHeap.java index e6444f3061..448c76aa08 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/BinaryIdOffHeap.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/BinaryIdOffHeap.java @@ -20,8 +20,8 @@ import java.util.Collections; import java.util.List; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.serializer.BinaryBackendEntry; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.backend.BinaryId; import org.apache.hugegraph.memory.consumer.OffHeapObject; import org.apache.hugegraph.memory.pool.MemoryPool; import org.apache.hugegraph.util.Bytes; @@ -30,7 +30,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; -public class BinaryIdOffHeap extends BinaryBackendEntry.BinaryId implements OffHeapObject { +public class BinaryIdOffHeap extends BinaryId implements OffHeapObject { private final OffHeapObject originId; private ByteBuf bytesOffHeap; @@ -51,8 +51,8 @@ public void serializeSelfToByteBuf(MemoryPool memoryPool) { } @Override - public BinaryBackendEntry.BinaryId zeroCopyReadFromByteBuf() { - return new BinaryBackendEntry.BinaryId(ByteBufUtil.getBytes(bytesOffHeap), + public BinaryId zeroCopyReadFromByteBuf() { + return new BinaryId(ByteBufUtil.getBytes(bytesOffHeap), (Id) originId.zeroCopyReadFromByteBuf()); } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/EdgeIdOffHeap.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/EdgeIdOffHeap.java index b77de337a8..502e8286e0 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/EdgeIdOffHeap.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/EdgeIdOffHeap.java @@ -22,10 +22,8 @@ import java.util.List; import java.util.Objects; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdUtil; -import org.apache.hugegraph.backend.id.SplicingIdGenerator; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.memory.consumer.OffHeapObject; import org.apache.hugegraph.memory.pool.MemoryPool; import org.apache.hugegraph.structure.HugeVertex; @@ -57,7 +55,7 @@ public EdgeIdOffHeap(HugeVertex ownerVertex, OffHeapObject edgeLabelIdOffHeap, OffHeapObject subLabelIdOffHeap, OffHeapObject otherVertexIdOffHeap) { - super(ownerVertex, direction, edgeLabelId, subLabelId, sortValues, otherVertex); + super(ownerVertex.id(), direction, edgeLabelId, subLabelId, sortValues, otherVertex.id()); this.memoryPool = memoryPool; this.ownerVertexIdOffHeap = ownerVertexIdOffHeap; this.edgeLabelIdOffHeap = edgeLabelIdOffHeap; @@ -220,23 +218,7 @@ public String asString() { this.cacheOffHeap.resetReaderIndex(); } } - String tmpCache; - if (this.directed) { - tmpCache = SplicingIdGenerator.concat( - IdUtil.writeString((Id) this.ownerVertexIdOffHeap.zeroCopyReadFromByteBuf()), - this.direction.type().string(), - IdUtil.writeLong((Id) this.edgeLabelIdOffHeap.zeroCopyReadFromByteBuf()), - IdUtil.writeLong((Id) this.subLabelIdOffHeap.zeroCopyReadFromByteBuf()), - this.sortValues(), - IdUtil.writeString((Id) this.otherVertexIdOffHeap.zeroCopyReadFromByteBuf())); - } else { - tmpCache = SplicingIdGenerator.concat( - IdUtil.writeString((Id) this.ownerVertexIdOffHeap.zeroCopyReadFromByteBuf()), - IdUtil.writeLong((Id) this.edgeLabelIdOffHeap.zeroCopyReadFromByteBuf()), - IdUtil.writeLong((Id) this.subLabelIdOffHeap.zeroCopyReadFromByteBuf()), - this.sortValues(), - IdUtil.writeString((Id) this.otherVertexIdOffHeap.zeroCopyReadFromByteBuf())); - } + String tmpCache = this.formatString(); byte[] tmpCacheBytes = tmpCache.getBytes(StandardCharsets.UTF_8); this.cacheOffHeap = (ByteBuf) memoryPool.requireMemory(tmpCacheBytes.length, memoryPool); this.cacheOffHeap.markReaderIndex(); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/LongIdOffHeap.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/LongIdOffHeap.java index 8d86f84a88..b7e34f28a1 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/LongIdOffHeap.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/LongIdOffHeap.java @@ -17,14 +17,14 @@ package org.apache.hugegraph.memory.consumer.impl.id; -import static org.apache.hugegraph.backend.id.IdGenerator.compareType; +import static org.apache.hugegraph.id.IdGenerator.compareType; import java.util.Collections; import java.util.List; import java.util.Objects; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.memory.consumer.OffHeapObject; import org.apache.hugegraph.memory.pool.MemoryPool; import org.apache.hugegraph.util.NumericUtil; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/ObjectIdOffHeap.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/ObjectIdOffHeap.java index d47d955a4d..16ab09a13b 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/ObjectIdOffHeap.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/ObjectIdOffHeap.java @@ -21,7 +21,7 @@ import java.util.List; import java.util.Objects; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.memory.consumer.OffHeapObject; import org.apache.hugegraph.memory.pool.MemoryPool; import org.apache.hugegraph.memory.util.FurySerializationUtil; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/QueryIdOffHeap.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/QueryIdOffHeap.java index 8a8dd4d1ee..4b7c539b79 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/QueryIdOffHeap.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/QueryIdOffHeap.java @@ -22,8 +22,8 @@ import java.util.List; import org.apache.hugegraph.backend.cache.CachedBackendStore; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.memory.consumer.OffHeapObject; import org.apache.hugegraph.memory.pool.MemoryPool; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/StringIdOffHeap.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/StringIdOffHeap.java index d026583821..cb8295fe31 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/StringIdOffHeap.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/StringIdOffHeap.java @@ -17,14 +17,14 @@ package org.apache.hugegraph.memory.consumer.impl.id; -import static org.apache.hugegraph.backend.id.IdGenerator.compareType; +import static org.apache.hugegraph.id.IdGenerator.compareType; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.memory.consumer.OffHeapObject; import org.apache.hugegraph.memory.pool.MemoryPool; import org.jetbrains.annotations.TestOnly; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/UuidIdOffHeap.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/UuidIdOffHeap.java index ed4b0399b5..e2af7ea1c7 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/UuidIdOffHeap.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/id/UuidIdOffHeap.java @@ -17,16 +17,16 @@ package org.apache.hugegraph.memory.consumer.impl.id; -import static org.apache.hugegraph.backend.id.IdGenerator.compareType; +import static org.apache.hugegraph.id.IdGenerator.compareType; import java.io.IOException; import java.util.Collections; import java.util.List; import java.util.UUID; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.memory.consumer.OffHeapObject; import org.apache.hugegraph.memory.pool.MemoryPool; import org.apache.hugegraph.memory.util.FurySerializationUtil; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/property/HugeEdgePropertyOffHeap.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/property/HugeEdgePropertyOffHeap.java index d2f21a414c..bec26eb672 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/property/HugeEdgePropertyOffHeap.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/property/HugeEdgePropertyOffHeap.java @@ -24,10 +24,11 @@ import org.apache.hugegraph.memory.consumer.OffHeapObject; import org.apache.hugegraph.memory.pool.MemoryPool; import org.apache.hugegraph.memory.util.FurySerializationUtil; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeEdgeProperty; import org.apache.hugegraph.structure.HugeElement; +import org.apache.hugegraph.structure.BaseProperty; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; @@ -53,7 +54,7 @@ public Object zeroCopyReadFromByteBuf() { @Override public void serializeSelfToByteBuf(MemoryPool memoryPool) { - byte[] bytes = FurySerializationUtil.FURY.serialize(this.value); + byte[] bytes = FurySerializationUtil.FURY.serialize(this.property.value()); this.valueOffHeap = (ByteBuf) memoryPool.requireMemory(bytes.length, memoryPool); this.valueOffHeap.markReaderIndex(); this.valueOffHeap.writeBytes(bytes); @@ -61,7 +62,12 @@ public void serializeSelfToByteBuf(MemoryPool memoryPool) { @Override public void releaseOriginalVarsOnHeap() { - this.value = null; + this.property = new BaseProperty(this.pkey, null) { + @Override + public V value() { + return HugeEdgePropertyOffHeap.this.value(); + } + }; } @Override diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/property/HugeVertexPropertyOffHeap.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/property/HugeVertexPropertyOffHeap.java index 1beb759cf0..0c75e44608 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/property/HugeVertexPropertyOffHeap.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/consumer/impl/property/HugeVertexPropertyOffHeap.java @@ -24,8 +24,9 @@ import org.apache.hugegraph.memory.consumer.OffHeapObject; import org.apache.hugegraph.memory.pool.MemoryPool; import org.apache.hugegraph.memory.util.FurySerializationUtil; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.structure.HugeElement; +import org.apache.hugegraph.structure.BaseProperty; import org.apache.hugegraph.structure.HugeVertexProperty; import io.netty.buffer.ByteBuf; @@ -52,7 +53,7 @@ public Object zeroCopyReadFromByteBuf() { @Override public void serializeSelfToByteBuf(MemoryPool memoryPool) { - byte[] bytes = FurySerializationUtil.FURY.serialize(this.value); + byte[] bytes = FurySerializationUtil.FURY.serialize(this.property.value()); this.valueOffHeap = (ByteBuf) memoryPool.requireMemory(bytes.length, memoryPool); this.valueOffHeap.markReaderIndex(); this.valueOffHeap.writeBytes(bytes); @@ -60,7 +61,12 @@ public void serializeSelfToByteBuf(MemoryPool memoryPool) { @Override public void releaseOriginalVarsOnHeap() { - this.value = null; + this.property = new BaseProperty(this.pkey, null) { + @Override + public V value() { + return HugeVertexPropertyOffHeap.this.value(); + } + }; } @Override diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/util/OffHeapMemoryUtil.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/util/OffHeapMemoryUtil.java index a63ddc91b7..3c726dea9a 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/util/OffHeapMemoryUtil.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/util/OffHeapMemoryUtil.java @@ -17,32 +17,16 @@ package org.apache.hugegraph.memory.util; -import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.apache.hugegraph.util.UnsafeUtil; import sun.misc.Unsafe; // NOTE: due to different layout of klass in various versions of JDK, this class may easily crash! public class OffHeapMemoryUtil { - private static final Logger LOG = LoggerFactory.getLogger(OffHeapMemoryUtil.class); - private static final Unsafe UNSAFE; - - static { - Unsafe unsafe; - try { - Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); - unsafeField.setAccessible(true); - unsafe = (Unsafe) unsafeField.get(null); - } catch (Throwable cause) { - LOG.warn("sun.misc.Unsafe.theUnsafe: unavailable.", cause); - throw new UnsupportedOperationException("Unsafe is not supported in this platform."); - } - UNSAFE = unsafe; - } + private static final Unsafe UNSAFE = UnsafeUtil.getUnsafe(); public static long allocateObjectToOffHeap(Object obj) { long size = sizeOf(obj); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/util/OutOfMemoryException.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/util/OutOfMemoryException.java index c770752626..152e2f92cc 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/util/OutOfMemoryException.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/memory/util/OutOfMemoryException.java @@ -16,7 +16,7 @@ */ package org.apache.hugegraph.memory.util; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; public class OutOfMemoryException extends HugeException { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/EtcdMetaDriver.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/EtcdMetaDriver.java index 75042131c8..6af98e0a88 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/EtcdMetaDriver.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/EtcdMetaDriver.java @@ -31,7 +31,7 @@ import java.util.function.Consumer; import org.apache.commons.io.FileUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.meta.lock.EtcdDistributedLock; import org.apache.hugegraph.meta.lock.LockResult; import org.apache.hugegraph.type.define.CollectionType; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/MetaManager.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/MetaManager.java index b30b505d32..0bc917d78d 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/MetaManager.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/MetaManager.java @@ -36,8 +36,8 @@ import org.apache.hugegraph.auth.HugeRole; import org.apache.hugegraph.auth.HugeTarget; import org.apache.hugegraph.auth.HugeUser; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.meta.lock.LockResult; import org.apache.hugegraph.meta.managers.AuthMetaManager; import org.apache.hugegraph.meta.managers.ConfigMetaManager; @@ -49,10 +49,10 @@ import org.apache.hugegraph.meta.managers.ServiceMetaManager; import org.apache.hugegraph.meta.managers.SpaceMetaManager; import org.apache.hugegraph.meta.managers.TaskMetaManager; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.space.GraphSpace; import org.apache.hugegraph.space.SchemaTemplate; import org.apache.hugegraph.space.Service; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/PdMetaDriver.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/PdMetaDriver.java index 18d0ea3fc3..c744e02e8e 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/PdMetaDriver.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/PdMetaDriver.java @@ -23,7 +23,7 @@ import java.util.Map; import java.util.function.Consumer; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.constant.ServiceConstant; import org.apache.hugegraph.meta.lock.LockResult; import org.apache.hugegraph.meta.lock.PdDistributedLock; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/lock/PdDistributedLock.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/lock/PdDistributedLock.java index 3e8c66ea14..2dbbdffdd0 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/lock/PdDistributedLock.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/lock/PdDistributedLock.java @@ -22,7 +22,7 @@ import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.pd.client.KvClient; import org.apache.hugegraph.pd.common.PDException; import org.apache.hugegraph.pd.grpc.kv.LockResponse; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/managers/AbstractMetaManager.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/managers/AbstractMetaManager.java index b7294a36e2..b1930144c0 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/managers/AbstractMetaManager.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/managers/AbstractMetaManager.java @@ -26,11 +26,11 @@ import java.util.function.Consumer; import org.apache.commons.lang3.StringUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.auth.SchemaDefine; import org.apache.hugegraph.meta.MetaDriver; import org.apache.hugegraph.meta.lock.LockResult; -import org.apache.hugegraph.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.SchemaElement; import org.apache.hugegraph.util.JsonUtil; public class AbstractMetaManager { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/managers/AuthMetaManager.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/managers/AuthMetaManager.java index bf801c0849..5e5c3c0bc1 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/managers/AuthMetaManager.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/managers/AuthMetaManager.java @@ -47,8 +47,8 @@ import org.apache.hugegraph.auth.HugeRole; import org.apache.hugegraph.auth.HugeTarget; import org.apache.hugegraph.auth.HugeUser; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.meta.MetaDriver; import org.apache.hugegraph.meta.MetaManager; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/managers/SchemaMetaManager.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/managers/SchemaMetaManager.java index 57e2839837..e832fb50a6 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/managers/SchemaMetaManager.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/managers/SchemaMetaManager.java @@ -33,14 +33,14 @@ import java.util.Map; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.meta.MetaDriver; import org.apache.hugegraph.meta.PdMetaDriver; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.util.JsonUtil; public class SchemaMetaManager extends AbstractMetaManager { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/managers/SchemaTemplateMetaManager.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/managers/SchemaTemplateMetaManager.java index bc2f1448bc..0fa8a0328a 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/managers/SchemaTemplateMetaManager.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/meta/managers/SchemaTemplateMetaManager.java @@ -27,7 +27,7 @@ import java.util.Set; import org.apache.commons.lang3.StringUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.meta.MetaDriver; import org.apache.hugegraph.space.SchemaTemplate; import org.apache.hugegraph.util.JsonUtil; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/plugin/HugeGraphGremlinPlugin.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/plugin/HugeGraphGremlinPlugin.java index 0b3b19ba7e..8ae5c80096 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/plugin/HugeGraphGremlinPlugin.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/plugin/HugeGraphGremlinPlugin.java @@ -22,7 +22,7 @@ import java.util.Iterator; import java.util.Set; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeFactory; import org.apache.hugegraph.util.ReflectionUtil; import org.apache.tinkerpop.gremlin.jsr223.AbstractGremlinPlugin; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/rpc/RpcServiceConfig4Client.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/rpc/RpcServiceConfig4Client.java deleted file mode 100644 index 52c86bb7d7..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/rpc/RpcServiceConfig4Client.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.rpc; - -public interface RpcServiceConfig4Client { - - T serviceProxy(String interfaceId); - - T serviceProxy(String graph, String interfaceId); - - default T serviceProxy(Class clazz) { - return this.serviceProxy(clazz.getName()); - } - - default T serviceProxy(String graph, Class clazz) { - return this.serviceProxy(graph, clazz.getName()); - } - - void removeAllServiceProxy(); -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/rpc/RpcServiceConfig4Server.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/rpc/RpcServiceConfig4Server.java deleted file mode 100644 index 4648244734..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/rpc/RpcServiceConfig4Server.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.rpc; - -public interface RpcServiceConfig4Server { - - String addService(Class clazz, S serviceImpl); - - String addService(String graph, Class clazz, - S serviceImpl); - - void removeService(String serviceId); - - void removeAllService(); -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/EdgeLabel.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/EdgeLabel.java deleted file mode 100644 index da572321c1..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/EdgeLabel.java +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.schema; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import org.apache.commons.lang3.tuple.Pair; -import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.schema.builder.SchemaBuilder; -import org.apache.hugegraph.type.HugeType; -import org.apache.hugegraph.type.define.Directions; -import org.apache.hugegraph.type.define.EdgeLabelType; -import org.apache.hugegraph.type.define.Frequency; -import org.apache.hugegraph.type.define.SchemaStatus; -import org.apache.hugegraph.util.E; - -import com.google.common.base.Objects; - -public class EdgeLabel extends SchemaLabel { - - public static final EdgeLabel NONE = new EdgeLabel(null, NONE_ID, UNDEF); - - private Set> links = new HashSet<>(); - private Id sourceLabel = NONE_ID; - private Id targetLabel = NONE_ID; - private Frequency frequency; - private List sortKeys; - - private EdgeLabelType edgeLabelType = EdgeLabelType.NORMAL; - private Id fatherId; - - public EdgeLabel(final HugeGraph graph, Id id, String name) { - super(graph, id, name); - this.frequency = Frequency.DEFAULT; - this.sortKeys = new ArrayList<>(); - } - - @Override - public HugeType type() { - return HugeType.EDGE_LABEL; - } - - public boolean isFather() { - return this.edgeLabelType.parent(); - } - - public void edgeLabelType(EdgeLabelType type) { - this.edgeLabelType = type; - } - - public EdgeLabelType edgeLabelType() { - return this.edgeLabelType; - } - - public boolean hasFather() { - return this.edgeLabelType.sub(); - } - - public Id fatherId() { - return this.fatherId; - } - - public void fatherId(Id fatherId) { - this.fatherId = fatherId; - } - - public Frequency frequency() { - return this.frequency; - } - - public void frequency(Frequency frequency) { - this.frequency = frequency; - } - - public boolean directed() { - // TODO: implement (do we need this method?) - return true; - } - - public String sourceLabelName() { - E.checkState(this.links.size() == 1, - "Only edge label has single vertex label pair can call " + - "sourceLabelName(), but current edge label got %s", - this.links.size()); - return this.graph.vertexLabelOrNone(this.links.iterator().next().getLeft()).name(); - } - - public List linksIds() { - List ids = new ArrayList<>(this.links.size() * 2); - for (Pair link : this.links) { - ids.add(link.getLeft()); - ids.add(link.getRight()); - } - return ids; - } - - public void linksIds(Id[] ids) { - this.links = new HashSet<>(ids.length / 2); - for (int i = 0; i < ids.length; i += 2) { - this.links.add(Pair.of(ids[i], ids[i + 1])); - } - } - - public Id sourceLabel() { - if (links.size() == 1) { - return links.iterator().next().getLeft(); - } - return NONE_ID; - } - - public void sourceLabel(Id id) { - E.checkArgument(this.links.isEmpty(), - "Not allowed add source label to an edge label which " + - "already has links"); - if (this.targetLabel != NONE_ID) { - this.links.add(Pair.of(id, this.targetLabel)); - this.targetLabel = NONE_ID; - } else { - this.sourceLabel = id; - } - } - - public String targetLabelName() { - E.checkState(this.links.size() == 1, - "Only edge label has single vertex label pair can call " + - "sourceLabelName(), but current edge label got %s", - this.links.size()); - return this.graph.vertexLabelOrNone(this.links.iterator().next().getRight()).name(); - } - - public Id targetLabel() { - if (links.size() == 1) { - return links.iterator().next().getRight(); - } - return NONE_ID; - } - - public void targetLabel(Id id) { - E.checkArgument(this.links.isEmpty(), - "Not allowed add source label to an edge label which " + - "already has links"); - if (this.sourceLabel != NONE_ID) { - this.links.add(Pair.of(this.sourceLabel, id)); - this.sourceLabel = NONE_ID; - } else { - this.targetLabel = id; - } - } - - public boolean linkWithLabel(Id id) { - for (Pair link : this.links) { - if (link.getLeft().equals(id) || link.getRight().equals(id)) { - return true; - } - } - return false; - } - - public boolean linkWithVertexLabel(Id label, Directions dir) { - return this.links.stream().anyMatch(pair -> { - Id sourceLabel = pair.getLeft(); - Id targetLabel = pair.getRight(); - if (dir.equals(Directions.IN)) { - return targetLabel.equals(label); - } else if (dir.equals(Directions.OUT)) { - return sourceLabel.equals(label); - } else if (dir.equals(Directions.BOTH)) { - return targetLabel.equals(label) || sourceLabel.equals(label); - } - return false; - }); - } - - public boolean checkLinkEqual(Id sourceLabel, Id targetLabel) { - return this.links.contains(Pair.of(sourceLabel, targetLabel)); - } - - public Set> links() { - return this.links; - } - - public void links(Pair link) { - if (this.links == null) { - this.links = new HashSet<>(); - } - this.links.add(link); - } - - public boolean existSortKeys() { - return !this.sortKeys.isEmpty(); - } - - public List sortKeys() { - return Collections.unmodifiableList(this.sortKeys); - } - - public void sortKey(Id id) { - this.sortKeys.add(id); - } - - public void sortKeys(Id... ids) { - this.sortKeys.addAll(Arrays.asList(ids)); - } - - public boolean hasSameContent(EdgeLabel other) { - return super.hasSameContent(other) && - this.frequency == other.frequency && - Objects.equal(this.sourceLabelName(), other.sourceLabelName()) && - Objects.equal(this.targetLabelName(), other.targetLabelName()) && - Objects.equal(this.graph.mapPkId2Name(this.sortKeys), - other.graph.mapPkId2Name(other.sortKeys)); - } - - public static EdgeLabel undefined(HugeGraph graph, Id id) { - return new EdgeLabel(graph, id, UNDEF); - } - - public interface Builder extends SchemaBuilder { - - Id rebuildIndex(); - - Builder asBase(); - - Builder withBase(String fatherLabel); - - Builder link(String sourceLabel, String targetLabel); - - @Deprecated - Builder sourceLabel(String label); - - @Deprecated - Builder targetLabel(String label); - - Builder singleTime(); - - Builder multiTimes(); - - Builder sortKeys(String... keys); - - Builder properties(String... properties); - - Builder nullableKeys(String... keys); - - Builder frequency(Frequency frequency); - - Builder ttl(long ttl); - - Builder ttlStartTime(String ttlStartTime); - - Builder enableLabelIndex(boolean enable); - - Builder userdata(String key, Object value); - - Builder userdata(Map userdata); - } - - @Override - public Map asMap() { - Map map = new HashMap<>(); - - if (this.sourceLabel() != null && this.sourceLabel() != NONE_ID) { - map.put(P.SOURCE_LABEL, this.sourceLabel().asString()); - } - - if (this.targetLabel() != null && this.targetLabel() != NONE_ID) { - map.put(P.TARGET_LABEL, this.targetLabel().asString()); - } - - if (this.properties() != null) { - map.put(P.PROPERTIES, this.properties()); - } - - if (this.nullableKeys() != null) { - map.put(P.NULLABLE_KEYS, this.nullableKeys()); - } - - if (this.indexLabels() != null) { - map.put(P.INDEX_LABELS, this.indexLabels()); - } - - if (this.ttlStartTime() != null) { - map.put(P.TT_START_TIME, this.ttlStartTime().asString()); - } - - if (this.sortKeys() != null) { - map.put(P.SORT_KEYS, this.sortKeys); - } - - map.put(P.EDGELABEL_TYPE, this.edgeLabelType); - if (this.fatherId() != null) { - map.put(P.FATHER_ID, this.fatherId().asString()); - } - map.put(P.ENABLE_LABEL_INDEX, this.enableLabelIndex()); - map.put(P.TTL, String.valueOf(this.ttl())); - map.put(P.LINKS, this.links()); - map.put(P.FREQUENCY, this.frequency().toString()); - - return super.asMap(map); - } - - @SuppressWarnings("unchecked") - public static EdgeLabel fromMap(Map map, HugeGraph graph) { - Id id = IdGenerator.of((int) map.get(EdgeLabel.P.ID)); - String name = (String) map.get(EdgeLabel.P.NAME); - EdgeLabel edgeLabel = new EdgeLabel(graph, id, name); - for (Map.Entry entry : map.entrySet()) { - switch (entry.getKey()) { - case P.ID: - case P.NAME: - break; - case P.STATUS: - edgeLabel.status( - SchemaStatus.valueOf(((String) entry.getValue()).toUpperCase())); - break; - case P.USERDATA: - edgeLabel.userdata(new Userdata((Map) entry.getValue())); - break; - case P.PROPERTIES: - Set ids = ((List) entry.getValue()).stream().map( - IdGenerator::of).collect(Collectors.toSet()); - edgeLabel.properties(ids); - break; - case P.NULLABLE_KEYS: - ids = ((List) entry.getValue()).stream().map( - IdGenerator::of).collect(Collectors.toSet()); - edgeLabel.nullableKeys(ids); - break; - case P.INDEX_LABELS: - ids = ((List) entry.getValue()).stream().map( - IdGenerator::of).collect(Collectors.toSet()); - edgeLabel.addIndexLabels(ids.toArray(new Id[0])); - break; - case P.ENABLE_LABEL_INDEX: - boolean enableLabelIndex = (Boolean) entry.getValue(); - edgeLabel.enableLabelIndex(enableLabelIndex); - break; - case P.TTL: - long ttl = Long.parseLong((String) entry.getValue()); - edgeLabel.ttl(ttl); - break; - case P.TT_START_TIME: - long ttlStartTime = - Long.parseLong((String) entry.getValue()); - edgeLabel.ttlStartTime(IdGenerator.of(ttlStartTime)); - break; - case P.LINKS: - // TODO: serialize and deserialize - List list = (List) entry.getValue(); - for (Map m : list) { - for (Object key : m.keySet()) { - Id sid = IdGenerator.of(Long.parseLong((String) key)); - Id tid = IdGenerator.of(Long.parseLong(String.valueOf(m.get(key)))); - edgeLabel.links(Pair.of(sid, tid)); - } - } - break; - case P.SOURCE_LABEL: - long sourceLabel = - Long.parseLong((String) entry.getValue()); - edgeLabel.sourceLabel(IdGenerator.of(sourceLabel)); - break; - case P.TARGET_LABEL: - long targetLabel = - Long.parseLong((String) entry.getValue()); - edgeLabel.targetLabel(IdGenerator.of(targetLabel)); - break; - case P.FATHER_ID: - long fatherId = - Long.parseLong((String) entry.getValue()); - edgeLabel.fatherId(IdGenerator.of(fatherId)); - break; - case P.EDGELABEL_TYPE: - EdgeLabelType edgeLabelType = - EdgeLabelType.valueOf( - ((String) entry.getValue()).toUpperCase()); - edgeLabel.edgeLabelType(edgeLabelType); - break; - case P.FREQUENCY: - Frequency frequency = - Frequency.valueOf(((String) entry.getValue()).toUpperCase()); - edgeLabel.frequency(frequency); - break; - case P.SORT_KEYS: - ids = ((List) entry.getValue()).stream().map( - IdGenerator::of).collect(Collectors.toSet()); - edgeLabel.sortKeys(ids.toArray(new Id[0])); - break; - default: - throw new AssertionError(String.format( - "Invalid key '%s' for edge label", - entry.getKey())); - } - } - return edgeLabel; - } - - public static final class P { - - public static final String ID = "id"; - public static final String NAME = "name"; - - public static final String STATUS = "status"; - public static final String USERDATA = "userdata"; - - public static final String PROPERTIES = "properties"; - public static final String NULLABLE_KEYS = "nullableKeys"; - public static final String INDEX_LABELS = "indexLabels"; - - public static final String ENABLE_LABEL_INDEX = "enableLabelIndex"; - public static final String TTL = "ttl"; - public static final String TT_START_TIME = "ttlStartTime"; - public static final String LINKS = "links"; - public static final String SOURCE_LABEL = "sourceLabel"; - public static final String TARGET_LABEL = "targetLabel"; - public static final String EDGELABEL_TYPE = "edgeLabelType"; - public static final String FATHER_ID = "fatherId"; - public static final String FREQUENCY = "frequency"; - public static final String SORT_KEYS = "sortKeys"; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/IndexLabel.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/IndexLabel.java deleted file mode 100644 index e20a728c2b..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/IndexLabel.java +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.schema; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.schema.builder.SchemaBuilder; -import org.apache.hugegraph.type.HugeType; -import org.apache.hugegraph.type.define.IndexType; -import org.apache.hugegraph.type.define.SchemaStatus; -import org.apache.hugegraph.util.E; - -import com.google.common.base.Objects; - -public class IndexLabel extends SchemaElement { - - private HugeType baseType; - private Id baseValue; - private IndexType indexType; - private List indexFields; - - public IndexLabel(final HugeGraph graph, Id id, String name) { - super(graph, id, name); - this.baseType = HugeType.SYS_SCHEMA; - this.baseValue = NONE_ID; - this.indexType = IndexType.SECONDARY; - this.indexFields = new ArrayList<>(); - } - - protected IndexLabel(long id, String name) { - this(null, IdGenerator.of(id), name); - } - - @Override - public HugeType type() { - return HugeType.INDEX_LABEL; - } - - public HugeType baseType() { - return this.baseType; - } - - public void baseType(HugeType baseType) { - this.baseType = baseType; - } - - public Id baseValue() { - return this.baseValue; - } - - public void baseValue(Id id) { - this.baseValue = id; - } - - public IndexType indexType() { - return this.indexType; - } - - public void indexType(IndexType indexType) { - this.indexType = indexType; - } - - public HugeType queryType() { - switch (this.baseType) { - case VERTEX_LABEL: - return HugeType.VERTEX; - case EDGE_LABEL: - return HugeType.EDGE; - case SYS_SCHEMA: - return HugeType.SYS_SCHEMA; - default: - throw new AssertionError(String.format( - "Query type of index label is either '%s' or '%s', " + - "but '%s' is used", - HugeType.VERTEX_LABEL, HugeType.EDGE_LABEL, - this.baseType)); - } - } - - public List indexFields() { - return Collections.unmodifiableList(this.indexFields); - } - - public void indexFields(Id... ids) { - this.indexFields.addAll(Arrays.asList(ids)); - } - - public void indexField(Id id) { - this.indexFields.add(id); - } - - public Id indexField() { - E.checkState(this.indexFields.size() == 1, - "There should be only one field in %s index label, " + - "but got: %s", this.indexType.string(), this.indexFields); - return this.indexFields.get(0); - } - - public SchemaLabel baseLabel() { - return getBaseLabel(this.graph, this.baseType, this.baseValue); - } - - public boolean hasSameContent(IndexLabel other) { - return super.hasSameContent(other) && - this.indexType == other.indexType && - this.baseType == other.baseType && - Objects.equal(this.graph.mapPkId2Name(this.indexFields), - other.graph.mapPkId2Name(other.indexFields)); - } - - public boolean olap() { - return VertexLabel.OLAP_VL.id().equals(this.baseValue); - } - - public Object validValue(Object value) { - if (!(value instanceof Number)) { - return value; - } - - Number number = (Number) value; - switch (this.indexType()) { - case RANGE_INT: - return number.intValue(); - case RANGE_LONG: - return number.longValue(); - case RANGE_FLOAT: - return number.floatValue(); - case RANGE_DOUBLE: - return number.doubleValue(); - default: - return value; - } - } - - // Label index - private static final IndexLabel VL_IL = new IndexLabel(VL_IL_ID, "~vli"); - private static final IndexLabel EL_IL = new IndexLabel(EL_IL_ID, "~eli"); - - // Schema name index - private static final IndexLabel PKN_IL = new IndexLabel(PKN_IL_ID, "~pkni"); - private static final IndexLabel VLN_IL = new IndexLabel(VLN_IL_ID, "~vlni"); - private static final IndexLabel ELN_IL = new IndexLabel(ELN_IL_ID, "~elni"); - private static final IndexLabel ILN_IL = new IndexLabel(ILN_IL_ID, "~ilni"); - - public static IndexLabel label(HugeType type) { - switch (type) { - case TASK: - case SERVER: - case VERTEX: - return VL_IL; - case EDGE: - case EDGE_OUT: - case EDGE_IN: - return EL_IL; - case PROPERTY_KEY: - return PKN_IL; - case VERTEX_LABEL: - return VLN_IL; - case EDGE_LABEL: - return ELN_IL; - case INDEX_LABEL: - return ILN_IL; - default: - throw new AssertionError(String.format( - "No primitive index label for '%s'", type)); - } - } - - public static IndexLabel label(HugeGraph graph, Id id) { - // Primitive IndexLabel first - if (id.asLong() < 0 && id.asLong() > -NEXT_PRIMITIVE_SYS_ID) { - switch ((int) id.asLong()) { - case VL_IL_ID: - return VL_IL; - case EL_IL_ID: - return EL_IL; - case PKN_IL_ID: - return PKN_IL; - case VLN_IL_ID: - return VLN_IL; - case ELN_IL_ID: - return ELN_IL; - case ILN_IL_ID: - return ILN_IL; - default: - throw new AssertionError(String.format( - "No primitive index label for '%s'", id)); - } - } - return graph.indexLabel(id); - } - - public static SchemaLabel getBaseLabel(HugeGraph graph, - HugeType baseType, - Object baseValue) { - E.checkNotNull(baseType, "base type", "index label"); - E.checkNotNull(baseValue, "base value", "index label"); - E.checkArgument(baseValue instanceof String || baseValue instanceof Id, - "The base value must be instance of String or Id, " + - "but got %s(%s)", baseValue, - baseValue.getClass().getSimpleName()); - - SchemaLabel label; - switch (baseType) { - case VERTEX_LABEL: - if (baseValue instanceof String) { - label = graph.vertexLabel((String) baseValue); - } else { - assert baseValue instanceof Id; - label = graph.vertexLabel((Id) baseValue); - } - break; - case EDGE_LABEL: - if (baseValue instanceof String) { - label = graph.edgeLabel((String) baseValue); - } else { - assert baseValue instanceof Id; - label = graph.edgeLabel((Id) baseValue); - } - break; - default: - throw new AssertionError(String.format( - "Unsupported base type '%s' of index label", - baseType)); - } - - E.checkArgumentNotNull(label, "Can't find the %s with name '%s'", - baseType.readableName(), baseValue); - return label; - } - - public interface Builder extends SchemaBuilder { - - TaskWithSchema createWithTask(); - - Id rebuild(); - - Builder onV(String baseValue); - - Builder onE(String baseValue); - - Builder by(String... fields); - - Builder secondary(); - - Builder range(); - - Builder search(); - - Builder shard(); - - Builder unique(); - - Builder on(HugeType baseType, String baseValue); - - Builder indexType(IndexType indexType); - - Builder userdata(String key, Object value); - - Builder userdata(Map userdata); - - Builder rebuild(boolean rebuild); - } - - @Override - public Map asMap() { - HashMap map = new HashMap<>(); - map.put(P.BASE_TYPE, this.baseType().name()); - map.put(P.BASE_VALUE, this.baseValue().asString()); - map.put(P.INDEX_TYPE, this.indexType().name()); - map.put(P.INDEX_FIELDS, this.indexFields()); - return super.asMap(map); - } - - @SuppressWarnings("unchecked") - public static IndexLabel fromMap(Map map, HugeGraph graph) { - Id id = IdGenerator.of((int) map.get(IndexLabel.P.ID)); - String name = (String) map.get(IndexLabel.P.NAME); - - IndexLabel indexLabel = new IndexLabel(graph, id, name); - for (Map.Entry entry : map.entrySet()) { - switch (entry.getKey()) { - case P.ID: - case P.NAME: - break; - case P.STATUS: - indexLabel.status( - SchemaStatus.valueOf(((String) entry.getValue()).toUpperCase())); - break; - case P.USERDATA: - indexLabel.userdata(new Userdata((Map) entry.getValue())); - break; - case P.BASE_TYPE: - HugeType hugeType = - HugeType.valueOf(((String) entry.getValue()).toUpperCase()); - indexLabel.baseType(hugeType); - break; - case P.BASE_VALUE: - long sourceLabel = - Long.parseLong((String) entry.getValue()); - indexLabel.baseValue(IdGenerator.of(sourceLabel)); - break; - case P.INDEX_TYPE: - IndexType indexType = - IndexType.valueOf(((String) entry.getValue()).toUpperCase()); - indexLabel.indexType(indexType); - break; - case P.INDEX_FIELDS: - List ids = ((List) entry.getValue()).stream().map( - IdGenerator::of).collect(Collectors.toList()); - indexLabel.indexFields(ids.toArray(new Id[0])); - break; - default: - throw new AssertionError(String.format( - "Invalid key '%s' for index label", - entry.getKey())); - } - } - return indexLabel; - } - - public static final class P { - - public static final String ID = "id"; - public static final String NAME = "name"; - - public static final String STATUS = "status"; - public static final String USERDATA = "userdata"; - - public static final String BASE_TYPE = "baseType"; - public static final String BASE_VALUE = "baseValue"; - public static final String INDEX_TYPE = "indexType"; - public static final String INDEX_FIELDS = "indexFields"; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/PropertyKey.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/PropertyKey.java deleted file mode 100644 index 5bf34ea530..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/PropertyKey.java +++ /dev/null @@ -1,514 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.schema; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.exception.NotSupportException; -import org.apache.hugegraph.schema.builder.SchemaBuilder; -import org.apache.hugegraph.type.HugeType; -import org.apache.hugegraph.type.Propertiable; -import org.apache.hugegraph.type.define.AggregateType; -import org.apache.hugegraph.type.define.Cardinality; -import org.apache.hugegraph.type.define.DataType; -import org.apache.hugegraph.type.define.SchemaStatus; -import org.apache.hugegraph.type.define.WriteType; -import org.apache.hugegraph.util.E; -import org.apache.hugegraph.util.LongEncoding; - -public class PropertyKey extends SchemaElement implements Propertiable { - - private DataType dataType; - private Cardinality cardinality; - private AggregateType aggregateType; - private WriteType writeType; - - public PropertyKey(final HugeGraph graph, Id id, String name) { - super(graph, id, name); - this.dataType = DataType.TEXT; - this.cardinality = Cardinality.SINGLE; - this.aggregateType = AggregateType.NONE; - this.writeType = WriteType.OLTP; - } - - @Override - public HugeType type() { - return HugeType.PROPERTY_KEY; - } - - public DataType dataType() { - return this.dataType; - } - - public void dataType(DataType dataType) { - this.dataType = dataType; - } - - public Cardinality cardinality() { - return this.cardinality; - } - - public void cardinality(Cardinality cardinality) { - this.cardinality = cardinality; - } - - public AggregateType aggregateType() { - return this.aggregateType; - } - - public void aggregateType(AggregateType aggregateType) { - this.aggregateType = aggregateType; - } - - public void writeType(WriteType writeType) { - this.writeType = writeType; - } - - public WriteType writeType() { - return this.writeType; - } - - public boolean oltp() { - return this.writeType.oltp(); - } - - public boolean olap() { - return this.writeType.olap(); - } - - @Override - public Set properties() { - return Collections.emptySet(); - } - - public PropertyKey properties(Id... properties) { - if (properties.length > 0) { - throw new NotSupportException("PropertyKey.properties(Id)"); - } - return this; - } - - public void defineDefaultValue(Object value) { - // TODO add a field default_value - this.userdata().put(Userdata.DEFAULT_VALUE, value); - } - - public Object defaultValue() { - // TODO add a field default_value - Object value = this.userdata().get(Userdata.DEFAULT_VALUE); - if (value == null) { - return null; - } - - // Userdata is reloaded from JSON as a raw Map, so a typed default - // value (e.g. Date) comes back as a String. Normalize it to the - // runtime type expected by this property key's data type. Idempotent - // for values already of the expected type. - Object raw = value; - if (this.cardinality == Cardinality.SET && value instanceof Collection && - !(value instanceof Set)) { - raw = new LinkedHashSet<>((Collection) value); - } - - return this.validValueOrThrow(raw); - } - - public boolean hasSameContent(PropertyKey other) { - return super.hasSameContent(other) && - this.dataType == other.dataType() && - this.cardinality == other.cardinality() && - this.aggregateType == other.aggregateType() && - this.writeType == other.writeType(); - } - - public String clazz() { - String dataType = this.dataType().clazz().getSimpleName(); - switch (this.cardinality) { - case SINGLE: - return dataType; - // A set of values: Set - case SET: - return String.format("Set<%s>", dataType); - // A list of values: List - case LIST: - return String.format("List<%s>", dataType); - default: - throw new AssertionError(String.format( - "Unsupported cardinality: '%s'", this.cardinality)); - } - } - - public Class implementClazz() { - Class cls; - switch (this.cardinality) { - case SINGLE: - cls = this.dataType().clazz(); - break; - // A set of values: Set - case SET: - cls = LinkedHashSet.class; - break; - // A list of values: List - case LIST: - cls = ArrayList.class; - break; - default: - throw new AssertionError(String.format( - "Unsupported cardinality: '%s'", this.cardinality)); - } - return cls; - } - - @SuppressWarnings("unchecked") - public T newValue() { - switch (this.cardinality) { - case SET: - return (T) new LinkedHashSet<>(); - case LIST: - return (T) new ArrayList<>(); - default: - // pass - break; - } - - try { - return (T) this.implementClazz().newInstance(); - } catch (Exception e) { - throw new HugeException("Failed to new instance of %s: %s", - this.implementClazz(), e.toString()); - } - } - - /** - * Check property value valid - * - * @param value the property value to be checked data type and cardinality - * @param the property value class - * @return true if data type and cardinality satisfy requirements, - * otherwise false - */ - public boolean checkValueType(V value) { - boolean valid; - - switch (this.cardinality) { - case SINGLE: - valid = this.checkDataType(value); - break; - case SET: - valid = value instanceof Set; - valid = valid && this.checkDataType((Set) value); - break; - case LIST: - valid = value instanceof List; - valid = valid && this.checkDataType((List) value); - break; - default: - throw new AssertionError(String.format( - "Unsupported cardinality: '%s'", this.cardinality)); - } - return valid; - } - - /** - * Check type of the value valid - * - * @param value the property value to be checked data type - * @param the property value original data type - * @return true if the value is or can convert to the data type, - * otherwise false - */ - private boolean checkDataType(V value) { - return this.dataType().clazz().isInstance(value); - } - - /** - * Check type of all the values(maybe some list properties) valid - * - * @param values the property values to be checked data type - * @param the property value class - * @return true if all the values are or can convert to the data type, - * otherwise false - */ - private boolean checkDataType(Collection values) { - boolean valid = true; - for (Object o : values) { - if (!this.checkDataType(o)) { - valid = false; - break; - } - } - return valid; - } - - public Object serialValue(V value, boolean encodeNumber) { - V validValue = this.validValue(value); - E.checkArgument(validValue != null, - "Invalid property value '%s' for key '%s'", - value, this.name()); - E.checkArgument(this.cardinality.single(), - "The cardinality can't be '%s' for navigation key '%s'", - this.cardinality, this.name()); - if (this.dataType.isNumber() || this.dataType.isDate()) { - if (encodeNumber) { - return LongEncoding.encodeNumber(validValue); - } else { - return validValue.toString(); - } - } - return validValue; - } - - public V validValueOrThrow(V value) { - V validValue = this.validValue(value); - if (validValue == null) { - E.checkArgument(false, - "Invalid property value '%s' for key '%s', " + - "expect a value of type %s, actual type %s", - value, this.name(), this.clazz(), - value.getClass().getSimpleName()); - } - return validValue; - } - - public V validValue(V value) { - try { - return this.convValue(value); - } catch (RuntimeException e) { - throw new IllegalArgumentException(String.format( - "Invalid property value '%s' for key '%s': %s", - value, this.name(), e.getMessage())); - } - } - - @SuppressWarnings("unchecked") - private V convValue(V value) { - if (value == null) { - return null; - } - if (this.checkValueType(value)) { - // Same as expected type, no conversion required - return value; - } - - V validValue = null; - Collection validValues; - if (this.cardinality.single()) { - validValue = this.convSingleValue(value); - } else if (value instanceof Collection) { - assert this.cardinality.multiple(); - Collection collection = (Collection) value; - if (value instanceof Set) { - validValues = new LinkedHashSet<>(collection.size()); - } else { - assert value instanceof List; - validValues = new ArrayList<>(collection.size()); - } - for (T element : collection) { - element = this.convSingleValue(element); - if (element == null) { - validValues = null; - break; - } - validValues.add(element); - } - validValue = (V) validValues; - } else { - assert this.cardinality.multiple(); - E.checkArgument(false, - "Property value must be %s, but got '%s'(%s)", - this.cardinality, value, - value.getClass().getSimpleName()); - } - return validValue; - } - - private V convSingleValue(V value) { - if (value == null) { - return null; - } - if (this.dataType().isNumber()) { - @SuppressWarnings("unchecked") - V number = (V) this.dataType().valueToNumber(value); - return number; - } else if (this.dataType().isDate()) { - @SuppressWarnings("unchecked") - V date = (V) this.dataType().valueToDate(value); - return date; - } else if (this.dataType().isUUID()) { - @SuppressWarnings("unchecked") - V uuid = (V) this.dataType().valueToUUID(value); - return uuid; - } else if (this.dataType().isBlob()) { - @SuppressWarnings("unchecked") - V blob = (V) this.dataType().valueToBlob(value); - return blob; - } - - if (this.checkDataType(value)) { - return value; - } - return null; - } - - public interface Builder extends SchemaBuilder { - - TaskWithSchema createWithTask(); - - Builder asText(); - - Builder asInt(); - - Builder asDate(); - - Builder asUUID(); - - Builder asBoolean(); - - Builder asByte(); - - Builder asBlob(); - - Builder asDouble(); - - Builder asFloat(); - - Builder asLong(); - - Builder valueSingle(); - - Builder valueList(); - - Builder valueSet(); - - Builder calcMax(); - - Builder calcMin(); - - Builder calcSum(); - - Builder calcOld(); - - Builder calcSet(); - - Builder calcList(); - - Builder writeType(WriteType writeType); - - Builder cardinality(Cardinality cardinality); - - Builder dataType(DataType dataType); - - Builder aggregateType(AggregateType aggregateType); - - Builder userdata(String key, Object value); - - Builder userdata(Map userdata); - } - - @Override - public Map asMap() { - Map map = new HashMap<>(); - - if (this.dataType != null) { - map.put(P.DATA_TYPE, this.dataType.string()); - } - - if (this.cardinality != null) { - map.put(P.CARDINALITY, this.cardinality.string()); - } - - if (this.aggregateType != null) { - map.put(P.AGGREGATE_TYPE, this.aggregateType.string()); - } - - if (this.writeType != null) { - map.put(P.WRITE_TYPE, this.writeType.string()); - } - - return super.asMap(map); - } - - @SuppressWarnings("unchecked") - public static PropertyKey fromMap(Map map, HugeGraph graph) { - Id id = IdGenerator.of((int) map.get(P.ID)); - String name = (String) map.get(P.NAME); - - PropertyKey propertyKey = new PropertyKey(graph, id, name); - for (Map.Entry entry : map.entrySet()) { - switch (entry.getKey()) { - case P.ID: - case P.NAME: - break; - case P.STATUS: - propertyKey.status( - SchemaStatus.valueOf(((String) entry.getValue()).toUpperCase())); - break; - case P.USERDATA: - propertyKey.userdata(new Userdata((Map) entry.getValue())); - break; - case P.AGGREGATE_TYPE: - propertyKey.aggregateType( - AggregateType.valueOf(((String) entry.getValue()).toUpperCase())); - break; - case P.WRITE_TYPE: - propertyKey.writeType( - WriteType.valueOf(((String) entry.getValue()).toUpperCase())); - break; - case P.DATA_TYPE: - propertyKey.dataType( - DataType.valueOf(((String) entry.getValue()).toUpperCase())); - break; - case P.CARDINALITY: - propertyKey.cardinality( - Cardinality.valueOf(((String) entry.getValue()).toUpperCase())); - break; - default: - throw new AssertionError(String.format( - "Invalid key '%s' for property key", - entry.getKey())); - } - } - return propertyKey; - } - - public static final class P { - - public static final String ID = "id"; - public static final String NAME = "name"; - - public static final String STATUS = "status"; - public static final String USERDATA = "userdata"; - - public static final String DATA_TYPE = "data_type"; - public static final String CARDINALITY = "cardinality"; - - public static final String AGGREGATE_TYPE = "aggregate_type"; - public static final String WRITE_TYPE = "write_type"; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/SchemaElement.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/SchemaElement.java deleted file mode 100644 index c36eeaf632..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/SchemaElement.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.schema; - -import java.util.Collections; -import java.util.Map; - -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.type.Nameable; -import org.apache.hugegraph.type.Typeable; -import org.apache.hugegraph.type.define.SchemaStatus; -import org.apache.hugegraph.util.E; -import org.apache.tinkerpop.gremlin.structure.Graph; - -import com.google.common.base.Objects; - -public abstract class SchemaElement implements Nameable, Typeable, - Cloneable { - - public static final int MAX_PRIMITIVE_SYS_ID = 32; - public static final int NEXT_PRIMITIVE_SYS_ID = 8; - - // ABS of system schema id must be below MAX_PRIMITIVE_SYS_ID - protected static final int VL_IL_ID = -1; - protected static final int EL_IL_ID = -2; - protected static final int PKN_IL_ID = -3; - protected static final int VLN_IL_ID = -4; - protected static final int ELN_IL_ID = -5; - protected static final int ILN_IL_ID = -6; - protected static final int OLAP_VL_ID = -7; - - // OLAP_ID means all of vertex label ids - public static final Id OLAP_ID = IdGenerator.of(-7); - // OLAP means all of vertex label names - public static final String OLAP = "~olap"; - - public static final Id NONE_ID = IdGenerator.ZERO; - - public static final String UNDEF = "~undefined"; - - protected final HugeGraph graph; - - private final Id id; - private final String name; - private final Userdata userdata; - private SchemaStatus status; - - public SchemaElement(final HugeGraph graph, Id id, String name) { - E.checkArgumentNotNull(id, "SchemaElement id can't be null"); - E.checkArgumentNotNull(name, "SchemaElement name can't be null"); - this.graph = graph; - this.id = id; - this.name = name; - this.userdata = new Userdata(); - this.status = SchemaStatus.CREATED; - } - - public HugeGraph graph() { - E.checkState(this.graph != null, - "Graph is null of schema '%s'", this.name); - return this.graph; - } - - public Id id() { - return this.id; - } - - public long longId() { - return this.id.asLong(); - } - - @Override - public String name() { - return this.name; - } - - public Map userdata() { - return Collections.unmodifiableMap(this.userdata); - } - - /** - * Add userdata. String values of {@link Userdata#CREATE_TIME} are - * normalized to {@link java.util.Date} and malformed strings are rejected. - */ - public void userdata(String key, Object value) { - E.checkArgumentNotNull(key, "userdata key"); - E.checkArgumentNotNull(value, "userdata value"); - this.userdata.put(key, value); - } - - /** - * Add userdata in bulk. String values of {@link Userdata#CREATE_TIME} are - * normalized to {@link java.util.Date} and malformed strings are rejected. - */ - public void userdata(Userdata userdata) { - E.checkArgumentNotNull(userdata, "userdata"); - this.userdata.putAll(userdata); - } - - public void removeUserdata(String key) { - E.checkArgumentNotNull(key, "The userdata key can't be null"); - this.userdata.remove(key); - } - - public void removeUserdata(Userdata userdata) { - E.checkArgumentNotNull(userdata, "userdata"); - for (String key : userdata.keySet()) { - this.userdata.remove(key); - } - } - - public SchemaStatus status() { - return this.status; - } - - public void status(SchemaStatus status) { - this.status = status; - } - - public boolean system() { - return this.longId() < 0L; - } - - public boolean primitive() { - long id = this.longId(); - return -MAX_PRIMITIVE_SYS_ID <= id && id < 0L; - } - - public boolean hidden() { - return Graph.Hidden.isHidden(this.name()); - } - - public SchemaElement copy() { - try { - return (SchemaElement) super.clone(); - } catch (CloneNotSupportedException e) { - throw new HugeException("Failed to clone schema", e); - } - } - - public boolean hasSameContent(SchemaElement other) { - return Objects.equal(this.name(), other.name()) && - Objects.equal(this.userdata(), other.userdata()); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof SchemaElement)) { - return false; - } - - SchemaElement other = (SchemaElement) obj; - return this.type() == other.type() && this.id.equals(other.id()); - } - - @Override - public int hashCode() { - return this.type().hashCode() ^ this.id.hashCode(); - } - - @Override - public String toString() { - return String.format("%s(id=%s)", this.name, this.id); - } - - public static int schemaId(Id id) { - long l = id.asLong(); - // Currently we limit the schema id to within 4 bytes - E.checkArgument(Integer.MIN_VALUE <= l && l <= Integer.MAX_VALUE, - "Schema id is out of bound: %s", l); - return (int) l; - } - - public static class TaskWithSchema { - - private SchemaElement schemaElement; - private Id task; - - public TaskWithSchema(SchemaElement schemaElement, Id task) { - E.checkNotNull(schemaElement, "schema element"); - this.schemaElement = schemaElement; - this.task = task; - } - - public void propertyKey(PropertyKey propertyKey) { - E.checkNotNull(propertyKey, "property key"); - this.schemaElement = propertyKey; - } - - public void indexLabel(IndexLabel indexLabel) { - E.checkNotNull(indexLabel, "index label"); - this.schemaElement = indexLabel; - } - - public PropertyKey propertyKey() { - E.checkState(this.schemaElement instanceof PropertyKey, - "Expect property key, but actual schema type is " + - "'%s'", this.schemaElement.getClass()); - return (PropertyKey) this.schemaElement; - } - - public IndexLabel indexLabel() { - E.checkState(this.schemaElement instanceof IndexLabel, - "Expect index label, but actual schema type is " + - "'%s'", this.schemaElement.getClass()); - return (IndexLabel) this.schemaElement; - } - - public SchemaElement schemaElement() { - return this.schemaElement; - } - - public Id task() { - return this.task; - } - } - - public abstract Map asMap(); - - public Map asMap(Map map) { - E.checkState(this.id != null, - "Property key id can't be null"); - E.checkState(this.name != null, - "Property key name can't be null"); - E.checkState(this.status != null, - "Property status can't be null"); - - map.put(P.ID, this.id); - map.put(P.NAME, this.name); - map.put(P.STATUS, this.status.string()); - map.put(P.USERDATA, this.userdata); - - return map; - } - - public static final class P { - - public static final String ID = "id"; - public static final String NAME = "name"; - - public static final String STATUS = "status"; - public static final String USERDATA = "userdata"; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/SchemaLabel.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/SchemaLabel.java deleted file mode 100644 index 09de43e2d8..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/SchemaLabel.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.schema; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.type.HugeType; -import org.apache.hugegraph.type.Indexable; -import org.apache.hugegraph.type.Propertiable; -import org.apache.hugegraph.util.E; - -import com.google.common.base.Objects; - -public abstract class SchemaLabel extends SchemaElement - implements Indexable, Propertiable { - - private final Set properties; - private final Set nullableKeys; - private final Set indexLabels; - private boolean enableLabelIndex; - private long ttl; - private Id ttlStartTime; - - public SchemaLabel(final HugeGraph graph, Id id, String name) { - super(graph, id, name); - this.properties = new HashSet<>(); - this.nullableKeys = new HashSet<>(); - this.indexLabels = new HashSet<>(); - this.enableLabelIndex = true; - this.ttl = 0L; - this.ttlStartTime = NONE_ID; - } - - @Override - public Set properties() { - return Collections.unmodifiableSet(this.properties); - } - - public void properties(Set properties) { - this.properties.addAll(properties); - } - - public SchemaLabel properties(Id... ids) { - this.properties.addAll(Arrays.asList(ids)); - return this; - } - - public void property(Id id) { - this.properties.add(id); - } - - public Set nullableKeys() { - return Collections.unmodifiableSet(this.nullableKeys); - } - - public void nullableKey(Id id) { - this.nullableKeys.add(id); - } - - public void nullableKeys(Id... ids) { - this.nullableKeys.addAll(Arrays.asList(ids)); - } - - public void nullableKeys(Set nullableKeys) { - this.nullableKeys.addAll(nullableKeys); - } - - @Override - public Set indexLabels() { - return Collections.unmodifiableSet(this.indexLabels); - } - - public void addIndexLabel(Id id) { - this.indexLabels.add(id); - } - - public void addIndexLabels(Id... ids) { - this.indexLabels.addAll(Arrays.asList(ids)); - } - - public boolean existsIndexLabel() { - return !this.indexLabels().isEmpty(); - } - - public void removeIndexLabel(Id id) { - this.indexLabels.remove(id); - } - - public boolean enableLabelIndex() { - return this.enableLabelIndex; - } - - public void enableLabelIndex(boolean enable) { - this.enableLabelIndex = enable; - } - - public boolean undefined() { - return this.name() == UNDEF; - } - - public void ttl(long ttl) { - assert ttl >= 0L; - this.ttl = ttl; - } - - public long ttl() { - assert this.ttl >= 0L; - return this.ttl; - } - - public void ttlStartTime(Id id) { - this.ttlStartTime = id; - } - - public Id ttlStartTime() { - return this.ttlStartTime; - } - - public String ttlStartTimeName() { - return NONE_ID.equals(this.ttlStartTime) ? null : - this.graph.propertyKey(this.ttlStartTime).name(); - } - - public boolean hasSameContent(SchemaLabel other) { - return super.hasSameContent(other) && this.ttl == other.ttl && - this.enableLabelIndex == other.enableLabelIndex && - Objects.equal(this.graph.mapPkId2Name(this.properties), - other.graph.mapPkId2Name(other.properties)) && - Objects.equal(this.graph.mapPkId2Name(this.nullableKeys), - other.graph.mapPkId2Name(other.nullableKeys)) && - Objects.equal(this.graph.mapIlId2Name(this.indexLabels), - other.graph.mapIlId2Name(other.indexLabels)) && - Objects.equal(this.ttlStartTimeName(), other.ttlStartTimeName()); - } - - public static Id getLabelId(HugeGraph graph, HugeType type, Object label) { - E.checkNotNull(graph, "graph"); - E.checkNotNull(type, "type"); - E.checkNotNull(label, "label"); - if (label instanceof Number) { - return IdGenerator.of(((Number) label).longValue()); - } else if (label instanceof String) { - if (type.isVertex()) { - return graph.vertexLabel((String) label).id(); - } else if (type.isEdge()) { - return graph.edgeLabel((String) label).id(); - } else { - throw new HugeException( - "Not support query from '%s' with label '%s'", - type, label); - } - } else { - throw new HugeException( - "The label type must be number or string, but got '%s'", - label.getClass()); - } - } - - public static Id getVertexLabelId(HugeGraph graph, Object label) { - return SchemaLabel.getLabelId(graph, HugeType.VERTEX, label); - } - - public static Id getEdgeLabelId(HugeGraph graph, Object label) { - return SchemaLabel.getLabelId(graph, HugeType.EDGE, label); - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/SchemaManager.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/SchemaManager.java index 7ea46b0d7b..0663f194d9 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/SchemaManager.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/SchemaManager.java @@ -27,6 +27,11 @@ import org.apache.hugegraph.schema.builder.IndexLabelBuilder; import org.apache.hugegraph.schema.builder.PropertyKeyBuilder; import org.apache.hugegraph.schema.builder.VertexLabelBuilder; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.util.E; import org.apache.tinkerpop.gremlin.structure.Graph; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/Userdata.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/Userdata.java deleted file mode 100644 index 9d2b9dbd19..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/Userdata.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.schema; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.hugegraph.exception.NotAllowException; -import org.apache.hugegraph.type.define.Action; -import org.apache.hugegraph.util.DateUtil; - -public class Userdata extends HashMap { - - private static final long serialVersionUID = -1235451175617197049L; - - public static final String CREATE_TIME = "~create_time"; - public static final String DEFAULT_VALUE = "~default_value"; - - public Userdata() { - } - - public Userdata(Map map) { - this.putAll(map); - } - - /** - * Normalizes the value before storing so the {@link #CREATE_TIME}-is-Date - * invariant holds regardless of how entries are added. - */ - @Override - public Object put(String key, Object value) { - return super.put(key, normalizeValue(key, value)); - } - - @Override - public void putAll(Map map) { - for (Map.Entry e : map.entrySet()) { - this.put(e.getKey(), e.getValue()); - } - } - - /** - * Normalize internal userdata values whose runtime type can diverge from - * their serialized form. The only such key today is {@link #CREATE_TIME}: - * it is written as a {@link java.util.Date} but persisted as a formatted - * JSON string by the backend serializers, and Jackson cannot re-type a - * value to {@code Date} when the target is a raw {@code Map}. This method - * restores the original type after deserialization. Idempotent for values - * already of the expected type. - *

- * An empty string is passed through unchanged: it is the key-only - * placeholder used by the {@code eliminate()}/{@code DELETE} builder flow - * (e.g. {@code .userdata(CREATE_TIME, "").eliminate()}), where the value is - * ignored and only the key drives {@code removeUserdata}. Parsing it would - * fail before the eliminate path can apply its key-only semantics. - */ - public static Object normalizeValue(String key, Object value) { - if (CREATE_TIME.equals(key) && value instanceof String && - !((String) value).isEmpty()) { - try { - return DateUtil.parse((String) value); - } catch (RuntimeException e) { - throw new IllegalArgumentException(String.format( - "Invalid userdata '%s' value: '%s'", - CREATE_TIME, value), e); - } - } - return value; - } - - public static void check(Userdata userdata, Action action) { - if (userdata == null) { - return; - } - switch (action) { - case INSERT: - case APPEND: - for (Map.Entry e : userdata.entrySet()) { - if (e.getValue() == null) { - throw new NotAllowException( - "Not allowed to pass null userdata value " + - "when create or append schema"); - } - } - break; - case ELIMINATE: - case DELETE: - // pass - break; - default: - throw new AssertionError(String.format( - "Unknown schema action '%s'", action)); - } - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/VertexLabel.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/VertexLabel.java deleted file mode 100644 index 3f62df8631..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/VertexLabel.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.schema; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.schema.builder.SchemaBuilder; -import org.apache.hugegraph.type.HugeType; -import org.apache.hugegraph.type.define.IdStrategy; -import org.apache.hugegraph.type.define.SchemaStatus; - -import com.google.common.base.Objects; - -public class VertexLabel extends SchemaLabel { - - public static final VertexLabel NONE = new VertexLabel(null, NONE_ID, UNDEF); - - // OLAP_VL_ID means all of vertex label ids - private static final Id OLAP_VL_ID = IdGenerator.of(SchemaLabel.OLAP_VL_ID); - // OLAP_VL_NAME means all of vertex label names - private static final String OLAP_VL_NAME = "*olap"; - // OLAP_VL means all of vertex labels - public static final VertexLabel OLAP_VL = new VertexLabel(null, OLAP_VL_ID, - OLAP_VL_NAME); - - private IdStrategy idStrategy; - private List primaryKeys; - - public VertexLabel(final HugeGraph graph, Id id, String name) { - super(graph, id, name); - this.idStrategy = IdStrategy.DEFAULT; - this.primaryKeys = new ArrayList<>(); - } - - @Override - public HugeType type() { - return HugeType.VERTEX_LABEL; - } - - public boolean olap() { - return VertexLabel.OLAP_VL.id().equals(this.id()); - } - - public IdStrategy idStrategy() { - return this.idStrategy; - } - - public void idStrategy(IdStrategy idStrategy) { - this.idStrategy = idStrategy; - } - - public List primaryKeys() { - return Collections.unmodifiableList(this.primaryKeys); - } - - public void primaryKey(Id id) { - this.primaryKeys.add(id); - } - - public void primaryKeys(Id... ids) { - this.primaryKeys.addAll(Arrays.asList(ids)); - } - - public boolean existsLinkLabel() { - return this.graph().existsLinkLabel(this.id()); - } - - public boolean hasSameContent(VertexLabel other) { - return super.hasSameContent(other) && - this.idStrategy == other.idStrategy && - Objects.equal(this.graph.mapPkId2Name(this.primaryKeys), - other.graph.mapPkId2Name(other.primaryKeys)); - } - - public static VertexLabel undefined(HugeGraph graph) { - return new VertexLabel(graph, NONE_ID, UNDEF); - } - - public static VertexLabel undefined(HugeGraph graph, Id id) { - return new VertexLabel(graph, id, UNDEF); - } - - public interface Builder extends SchemaBuilder { - - Id rebuildIndex(); - - Builder idStrategy(IdStrategy idStrategy); - - Builder useAutomaticId(); - - Builder usePrimaryKeyId(); - - Builder useCustomizeStringId(); - - Builder useCustomizeNumberId(); - - Builder useCustomizeUuidId(); - - Builder properties(String... properties); - - Builder primaryKeys(String... keys); - - Builder nullableKeys(String... keys); - - Builder ttl(long ttl); - - Builder ttlStartTime(String ttlStartTime); - - Builder enableLabelIndex(boolean enable); - - Builder userdata(String key, Object value); - - Builder userdata(Map userdata); - } - - @Override - public Map asMap() { - HashMap map = new HashMap(); - - map.put(P.PROPERTIES, this.properties()); - - map.put(P.NULLABLE_KEYS, this.nullableKeys()); - - map.put(P.INDEX_LABELS, this.indexLabels()); - - map.put(P.ENABLE_LABEL_INDEX, this.enableLabelIndex()); - - map.put(P.TTL, String.valueOf(this.ttl())); - - map.put(P.TT_START_TIME, this.ttlStartTime().asString()); - - map.put(P.ID_STRATEGY, this.idStrategy().string()); - - map.put(P.PRIMARY_KEYS, this.primaryKeys()); - - return super.asMap(map); - } - - @SuppressWarnings("unchecked") - public static VertexLabel fromMap(Map map, HugeGraph graph) { - Id id = IdGenerator.of((int) map.get(VertexLabel.P.ID)); - String name = (String) map.get(VertexLabel.P.NAME); - - VertexLabel vertexLabel = new VertexLabel(graph, id, name); - for (Map.Entry entry : map.entrySet()) { - switch (entry.getKey()) { - case P.ID: - case P.NAME: - break; - case P.STATUS: - vertexLabel.status( - SchemaStatus.valueOf(((String) entry.getValue()).toUpperCase())); - break; - case P.USERDATA: - vertexLabel.userdata(new Userdata((Map) entry.getValue())); - break; - case P.PROPERTIES: - Set ids = ((List) entry.getValue()).stream().map( - IdGenerator::of).collect(Collectors.toSet()); - vertexLabel.properties(ids); - break; - case P.NULLABLE_KEYS: - ids = ((List) entry.getValue()).stream().map( - IdGenerator::of).collect(Collectors.toSet()); - vertexLabel.nullableKeys(ids); - break; - case P.INDEX_LABELS: - ids = ((List) entry.getValue()).stream().map( - IdGenerator::of).collect(Collectors.toSet()); - vertexLabel.addIndexLabels(ids.toArray(new Id[0])); - break; - case P.ENABLE_LABEL_INDEX: - boolean enableLabelIndex = (Boolean) entry.getValue(); - vertexLabel.enableLabelIndex(enableLabelIndex); - break; - case P.TTL: - long ttl = Long.parseLong((String) entry.getValue()); - vertexLabel.ttl(ttl); - break; - case P.TT_START_TIME: - long ttlStartTime = - Long.parseLong((String) entry.getValue()); - vertexLabel.ttlStartTime(IdGenerator.of(ttlStartTime)); - break; - case P.ID_STRATEGY: - IdStrategy idStrategy = - IdStrategy.valueOf(((String) entry.getValue()).toUpperCase()); - vertexLabel.idStrategy(idStrategy); - break; - case P.PRIMARY_KEYS: - ids = ((List) entry.getValue()).stream().map( - IdGenerator::of).collect(Collectors.toSet()); - vertexLabel.primaryKeys(ids.toArray(new Id[0])); - break; - default: - throw new AssertionError(String.format( - "Invalid key '%s' for vertex label", - entry.getKey())); - } - } - return vertexLabel; - } - - public static final class P { - - public static final String ID = "id"; - public static final String NAME = "name"; - - public static final String STATUS = "status"; - public static final String USERDATA = "userdata"; - - public static final String PROPERTIES = "properties"; - public static final String NULLABLE_KEYS = "nullableKeys"; - public static final String INDEX_LABELS = "indexLabels"; - - public static final String ENABLE_LABEL_INDEX = "enableLabelIndex"; - public static final String TTL = "ttl"; - public static final String TT_START_TIME = "ttlStartTime"; - public static final String ID_STRATEGY = "idStrategy"; - public static final String PRIMARY_KEYS = "primaryKeys"; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/AbstractBuilder.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/AbstractBuilder.java index 0e0e95256c..2baaf8130b 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/AbstractBuilder.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/AbstractBuilder.java @@ -21,15 +21,15 @@ import java.util.function.Function; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; import org.apache.hugegraph.backend.tx.ISchemaTransaction; import org.apache.hugegraph.exception.ExistedException; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.GraphMode; import org.apache.hugegraph.type.define.SchemaStatus; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/EdgeLabelBuilder.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/EdgeLabelBuilder.java index 32937a2cf0..e46d4c2f2a 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/EdgeLabelBuilder.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/EdgeLabelBuilder.java @@ -28,16 +28,17 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.tuple.Pair; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.HugeGraphSupplier; import org.apache.hugegraph.backend.tx.ISchemaTransaction; import org.apache.hugegraph.exception.ExistedException; import org.apache.hugegraph.exception.NotAllowException; import org.apache.hugegraph.exception.NotFoundException; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.Userdata; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.Userdata; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Action; import org.apache.hugegraph.type.define.EdgeLabelType; @@ -91,7 +92,7 @@ public EdgeLabelBuilder(ISchemaTransaction transaction, HugeGraph graph, EdgeLabel copy) { super(transaction, graph); E.checkNotNull(copy, "copy"); - HugeGraph origin = copy.graph(); + HugeGraphSupplier origin = copy.graph(); this.id = null; this.name = copy.name(); this.links = mapPairId2Name(origin, copy.links()); @@ -206,7 +207,6 @@ public EdgeLabel create() { this.checkNullableKeys(Action.INSERT); Userdata.check(this.userdata, Action.INSERT); this.checkTTL(); - this.checkUserdata(Action.INSERT); edgeLabel = this.build(); assert edgeLabel.name().equals(name); @@ -731,42 +731,26 @@ private void checkTTL() { "but got '%s(%s)'", this.ttlStartTime, pkey.dataType()); } - private void checkUserdata(Action action) { - switch (action) { - case INSERT: - case APPEND: - for (Map.Entry e : this.userdata.entrySet()) { - if (e.getValue() == null) { - throw new NotAllowException( - "Not allowed pass null userdata value when " + - "create or append edge label"); - } - } - break; - case ELIMINATE: - case DELETE: - // pass - break; - default: - throw new AssertionError(String.format( - "Unknown schema action '%s'", action)); - } - } - private static Set mapPkId2Name(HugeGraph graph, Set ids) { + private static Set mapPkId2Name(HugeGraphSupplier graph, Set ids) { return new HashSet<>(graph.mapPkId2Name(ids)); } - private static List mapPkId2Name(HugeGraph graph, List ids) { + private static List mapPkId2Name(HugeGraphSupplier graph, List ids) { return graph.mapPkId2Name(ids); } - private static String mapElId2Name(HugeGraph graph, Id fatherId) { - return graph.mapElId2Name(ImmutableList.of(fatherId)).get(0); + private static String mapElId2Name(HugeGraphSupplier graph, Id fatherId) { + return graph.edgeLabel(fatherId).name(); } - private static Set> mapPairId2Name(HugeGraph graph, + private static Set> mapPairId2Name(HugeGraphSupplier graph, Set> pairs) { - return graph.mapPairId2Name(pairs); + Set> names = new HashSet<>(); + for (Pair pair : pairs) { + names.add(Pair.of(graph.vertexLabel(pair.getLeft()).name(), + graph.vertexLabel(pair.getRight()).name())); + } + return names; } } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/IndexLabelBuilder.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/IndexLabelBuilder.java index 397df66229..abb4ca8fbd 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/IndexLabelBuilder.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/IndexLabelBuilder.java @@ -25,21 +25,21 @@ import java.util.concurrent.TimeoutException; import java.util.function.BiPredicate; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; import org.apache.hugegraph.backend.tx.ISchemaTransaction; import org.apache.hugegraph.config.CoreOptions; import org.apache.hugegraph.exception.ExistedException; import org.apache.hugegraph.exception.NotAllowException; import org.apache.hugegraph.exception.NotFoundException; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.schema.SchemaLabel; -import org.apache.hugegraph.schema.Userdata; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.SchemaLabel; +import org.apache.hugegraph.struct.schema.Userdata; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Action; import org.apache.hugegraph.type.define.CollectionType; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/PropertyKeyBuilder.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/PropertyKeyBuilder.java index a50b426d1d..d971fd5aeb 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/PropertyKeyBuilder.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/PropertyKeyBuilder.java @@ -20,19 +20,19 @@ import java.util.Map; import java.util.concurrent.TimeoutException; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; import org.apache.hugegraph.backend.tx.ISchemaTransaction; import org.apache.hugegraph.config.CoreOptions; import org.apache.hugegraph.exception.ExistedException; import org.apache.hugegraph.exception.NotAllowException; import org.apache.hugegraph.exception.NotFoundException; import org.apache.hugegraph.exception.NotSupportException; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.schema.Userdata; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.Userdata; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Action; import org.apache.hugegraph.type.define.AggregateType; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/SchemaBuilder.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/SchemaBuilder.java deleted file mode 100644 index 28ef0c15f5..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/SchemaBuilder.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.schema.builder; - -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.schema.SchemaElement; - -public interface SchemaBuilder { - - SchemaBuilder id(long id); - - T build(); - - T create(); - - T append(); - - T eliminate(); - - Id remove(); - - SchemaBuilder ifNotExist(); - - SchemaBuilder checkExist(boolean checkExist); -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/VertexLabelBuilder.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/VertexLabelBuilder.java index 4962646209..95b14b2697 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/VertexLabelBuilder.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/VertexLabelBuilder.java @@ -27,15 +27,16 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.HugeGraphSupplier; import org.apache.hugegraph.backend.tx.ISchemaTransaction; import org.apache.hugegraph.exception.ExistedException; import org.apache.hugegraph.exception.NotAllowException; import org.apache.hugegraph.exception.NotFoundException; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.Userdata; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.Userdata; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Action; import org.apache.hugegraph.type.define.IdStrategy; @@ -79,7 +80,7 @@ public VertexLabelBuilder(ISchemaTransaction transaction, HugeGraph graph, VertexLabel copy) { super(transaction, graph); E.checkNotNull(copy, "copy"); - HugeGraph origin = copy.graph(); + HugeGraphSupplier origin = copy.graph(); this.id = null; this.name = copy.name(); this.idStrategy = copy.idStrategy(); @@ -138,7 +139,6 @@ public VertexLabel create() { this.checkNullableKeys(Action.INSERT); Userdata.check(this.userdata, Action.INSERT); this.checkTTL(); - this.checkUserdata(Action.INSERT); vertexLabel = this.build(); assert vertexLabel.name().equals(name); @@ -586,32 +586,12 @@ private void checkTTL() { "but got '%s(%s)'", this.ttlStartTime, pkey.dataType()); } - private void checkUserdata(Action action) { - switch (action) { - case INSERT: - case APPEND: - for (Map.Entry e : this.userdata.entrySet()) { - if (e.getValue() == null) { - throw new NotAllowException( - "Not allowed pass null userdata value when " + - "create or append edge label"); - } - } - break; - case ELIMINATE: - case DELETE: - // pass - break; - default: - throw new AssertionError(String.format("Unknown schema action '%s'", action)); - } - } - private static Set mapPkId2Name(HugeGraph graph, Set ids) { + private static Set mapPkId2Name(HugeGraphSupplier graph, Set ids) { return new HashSet<>(graph.mapPkId2Name(ids)); } - private static List mapPkId2Name(HugeGraph graph, List ids) { + private static List mapPkId2Name(HugeGraphSupplier graph, List ids) { return graph.mapPkId2Name(ids); } } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/space/GraphSpace.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/space/GraphSpace.java index f821809b63..d78415c691 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/space/GraphSpace.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/space/GraphSpace.java @@ -24,7 +24,7 @@ import java.util.Map; import org.apache.commons.lang.StringUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.util.E; public class GraphSpace { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/GraphType.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/GraphType.java deleted file mode 100644 index 7cf5ee3b4d..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/GraphType.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.structure; - -import org.apache.hugegraph.type.Nameable; -import org.apache.hugegraph.type.Typeable; - -public interface GraphType extends Nameable, Typeable { - -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeEdge.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeEdge.java index 5bf7011a6f..9ba85a9baa 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeEdge.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeEdge.java @@ -22,24 +22,21 @@ import java.util.List; import org.apache.commons.lang3.tuple.Pair; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.query.QueryResults; -import org.apache.hugegraph.backend.serializer.BytesBuffer; import org.apache.hugegraph.backend.tx.GraphTransaction; import org.apache.hugegraph.perf.PerfUtil.Watched; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Cardinality; import org.apache.hugegraph.type.define.Directions; import org.apache.hugegraph.type.define.HugeKeys; import org.apache.hugegraph.util.E; -import org.apache.logging.log4j.util.Strings; import org.apache.tinkerpop.gremlin.structure.Direction; import org.apache.tinkerpop.gremlin.structure.Edge; import org.apache.tinkerpop.gremlin.structure.Property; @@ -47,17 +44,14 @@ import org.apache.tinkerpop.gremlin.structure.util.StringFactory; import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyProperty; -import com.google.common.collect.ImmutableList; public class HugeEdge extends HugeElement implements Edge, Cloneable { - private Id id; - private final EdgeLabel label; - private String name; + private BaseEdge element; private HugeVertex sourceVertex; private HugeVertex targetVertex; - private boolean isOutEdge; + public HugeEdge(HugeVertex owner, Id id, EdgeLabel label, HugeVertex other) { @@ -70,52 +64,69 @@ public HugeEdge(final HugeGraph graph, Id id, EdgeLabel label) { super(graph); E.checkArgumentNotNull(label, "Edge label can't be null"); - this.label = label; - - this.id = id; - this.name = null; + this.element = new BaseEdge(id, label); + this.element.isOutEdge(true); this.sourceVertex = null; this.targetVertex = null; - this.isOutEdge = true; + } + + /** Adopt decoded shared state and attach engine endpoint wrappers. */ + public HugeEdge(final HugeGraph graph, BaseEdge element) { + this(graph, element, null); + } + + public HugeEdge(final HugeGraph graph, BaseEdge element, HugeVertex owner) { + super(graph); + E.checkArgumentNotNull(element, "Edge element can't be null"); + E.checkArgumentNotNull(element.schemaLabel(), "Edge label can't be null"); + this.element = element; + BaseVertex source = element.sourceVertex(); + BaseVertex target = element.targetVertex(); + this.sourceVertex = this.wrapVertex(graph, source, owner); + this.targetVertex = target == source ? this.sourceVertex : this.wrapVertex(graph, target, owner); + } + + private HugeVertex wrapVertex(HugeGraph graph, BaseVertex vertex, HugeVertex owner) { + if (vertex == null) { + return null; + } + return owner != null && owner.element() == vertex ? owner : new HugeVertex(graph, vertex); + } + + @Override + public BaseEdge element() { + return this.element; } @Override public HugeType type() { // NOTE: we optimize the edge type that let it include direction - return this.isOutEdge ? HugeType.EDGE_OUT : HugeType.EDGE_IN; + return this.element.isOutEdge() ? HugeType.EDGE_OUT : HugeType.EDGE_IN; } @Override public EdgeId id() { - return (EdgeId) this.id; + return (EdgeId) this.element.id(); } @Override public EdgeLabel schemaLabel() { - assert this.graph().sameAs(this.label.graph()); - return this.label; + assert this.graph().sameAs(this.element.schemaLabel().graph()); + return this.element.schemaLabel(); } @Override public String name() { - if (this.name == null) { - List sortValues = this.sortValues(); - if (sortValues.isEmpty()) { - this.name = Strings.EMPTY; - } else { - this.name = ConditionQuery.concatValues(sortValues); - } - } - return this.name; + return this.element.name(); } public void name(String name) { - this.name = name; + this.element.name(name); } @Override public String label() { - return this.label.name(); + return this.element.schemaLabel().name(); } public boolean selfLoop() { @@ -124,7 +135,7 @@ public boolean selfLoop() { } public Directions direction() { - return this.isOutEdge ? Directions.OUT : Directions.IN; + return this.element.isOutEdge() ? Directions.OUT : Directions.IN; } public boolean matchDirection(Directions direction) { @@ -135,60 +146,25 @@ public boolean matchDirection(Directions direction) { } public boolean isDirection(Directions direction) { - return this.isOutEdge && direction == Directions.OUT || - !this.isOutEdge && direction == Directions.IN; + return this.element.isOutEdge() && direction == Directions.OUT || + !this.element.isOutEdge() && direction == Directions.IN; } @Watched(prefix = "edge") public void assignId() { - // Generate an id and assign - if (this.schemaLabel().hasFather()) { - this.id = new EdgeId(this.ownerVertex(), this.direction(), - this.schemaLabel().fatherId(), - this.schemaLabel().id(), - this.name(), - this.otherVertex()); - } else { - this.id = new EdgeId(this.ownerVertex(), this.direction(), - this.schemaLabel().id(), - this.schemaLabel().id(), - this.name(), this.otherVertex()); - } - - if (this.fresh()) { - int len = this.id.length(); - E.checkArgument(len <= BytesBuffer.EID_LEN_MAX, - "The max length of edge id is %s, but got %s {%s}", - BytesBuffer.EID_LEN_MAX, len, this.id); - } + this.element.assignId(); } @Watched(prefix = "edge") public EdgeId idWithDirection() { - return ((EdgeId) this.id).directed(true); + return this.element.idWithDirection(); } @Watched(prefix = "edge") protected List sortValues() { - List sortKeys = this.schemaLabel().sortKeys(); - if (sortKeys.isEmpty()) { - return ImmutableList.of(); - } - List propValues = new ArrayList<>(sortKeys.size()); - for (Id sk : sortKeys) { - HugeProperty property = this.getProperty(sk); - E.checkState(property != null, - "The value of sort key '%s' can't be null", sk); - Object propValue = property.serialValue(true); - if (Strings.EMPTY.equals(propValue)) { - propValue = ConditionQuery.INDEX_VALUE_EMPTY; - } - propValues.add(propValue); - } - return propValues; + return this.element.sortValues(); } - @Watched(prefix = "edge") @Override public void remove() { this.removed(true); @@ -208,7 +184,7 @@ public void remove() { public Property property(String key, V value) { PropertyKey propertyKey = this.graph().propertyKey(key); // Check key in edge label - E.checkArgument(this.label.properties().contains(propertyKey.id()), + E.checkArgument(this.element.schemaLabel().properties().contains(propertyKey.id()), "Invalid property '%s' for edge label '%s'", key, this.label()); if (value == null) { @@ -238,6 +214,11 @@ protected HugeEdgeProperty newProperty(PropertyKey pkey, V val) { return new HugeEdgeProperty<>(this, pkey, val); } + @Override + protected HugeEdgeProperty wrapProperty(BaseProperty property) { + return new HugeEdgeProperty<>(this, property); + } + @Watched(prefix = "edge") @Override protected void onUpdateProperty(Cardinality cardinality, @@ -275,7 +256,7 @@ protected boolean ensureFilledProperties(boolean throwIfNotExist) { if (edge == null && !throwIfNotExist) { return false; } - E.checkState(edge != null, "Edge '%s' does not exist", this.id); + E.checkState(edge != null, "Edge '%s' does not exist", this.element.id()); this.copyProperties((HugeEdge) edge); this.updateToDefaultValueIfNone(); return true; @@ -319,31 +300,7 @@ public Iterator> properties(String... keys) { @Override public Object sysprop(HugeKeys key) { - switch (key) { - case ID: - return this.id(); - case OWNER_VERTEX: - return this.ownerVertex().id(); - case LABEL: - if (this.schemaLabel().hasFather()) { - return this.schemaLabel().fatherId(); - } else { - return this.schemaLabel().id(); - } - case DIRECTION: - return this.direction(); - case SUB_LABEL: - return this.schemaLabel().id(); - case OTHER_VERTEX: - return this.otherVertex().id(); - case SORT_VALUES: - return this.name(); - case PROPERTIES: - return this.getPropertiesMap(); - default: - E.checkArgument(false, "Invalid system property '%s' of Edge", key); - return null; - } + return this.element.sysprop(key); } @Override @@ -380,7 +337,7 @@ public Vertex inVertex() { public void vertices(HugeVertex owner, HugeVertex other) { Id ownerLabel = owner.schemaLabel().id(); Id otherLabel = other.schemaLabel().id(); - for (Pair link : this.label.links()) { + for (Pair link : this.element.schemaLabel().links()) { if (ownerLabel.equals(link.getLeft()) && otherLabel.equals(link.getRight())) { this.vertices(true, owner, other); @@ -392,8 +349,8 @@ public void vertices(HugeVertex owner, HugeVertex other) { } public void vertices(boolean outEdge, HugeVertex owner, HugeVertex other) { - this.isOutEdge = outEdge; - if (this.isOutEdge) { + this.element.vertices(outEdge, owner.element(), other.element()); + if (this.element.isOutEdge()) { this.sourceVertex = owner; this.targetVertex = other; } else { @@ -404,10 +361,7 @@ public void vertices(boolean outEdge, HugeVertex owner, HugeVertex other) { @Watched public HugeEdge switchOwner() { - HugeEdge edge = this.clone(); - edge.isOutEdge = !edge.isOutEdge; - edge.id = ((EdgeId) edge.id).switchDirection(); - return edge; + return this.cloneWithElement(this.element.switchOwner()); } public HugeEdge switchToOutDirection() { @@ -418,7 +372,7 @@ public HugeEdge switchToOutDirection() { } public HugeVertex ownerVertex() { - return this.isOutEdge ? this.sourceVertex() : this.targetVertex(); + return this.element.isOutEdge() ? this.sourceVertex() : this.targetVertex(); } public HugeVertex sourceVertex() { @@ -428,6 +382,7 @@ public HugeVertex sourceVertex() { public void sourceVertex(HugeVertex sourceVertex) { this.sourceVertex = sourceVertex; + this.element.sourceVertex(sourceVertex.element()); } public HugeVertex targetVertex() { @@ -437,6 +392,7 @@ public HugeVertex targetVertex() { public void targetVertex(HugeVertex targetVertex) { this.targetVertex = targetVertex; + this.element.targetVertex(targetVertex.element()); } private void checkAdjacentVertexExist(HugeVertex vertex) { @@ -477,7 +433,7 @@ public HugeVertex otherVertex(HugeVertex vertex) { } public HugeVertex otherVertex() { - return this.isOutEdge ? this.targetVertex() : this.sourceVertex(); + return this.element.isOutEdge() ? this.targetVertex() : this.sourceVertex(); } /** @@ -501,8 +457,14 @@ public HugeEdge copy() { @Override protected HugeEdge clone() { + return this.cloneWithElement(this.element.clone()); + } + + private HugeEdge cloneWithElement(BaseEdge element) { try { - return (HugeEdge) super.clone(); + HugeEdge edge = (HugeEdge) super.clone(); + edge.element = element; + return edge; } catch (CloneNotSupportedException e) { throw new HugeException("Failed to clone HugeEdge", e); } @@ -528,36 +490,21 @@ public static HugeEdge constructEdge(HugeVertex ownerVertex, EdgeLabel edgeLabel, String sortValues, Id otherVertexId) { - HugeGraph graph = ownerVertex.graph(); - VertexLabel srcLabel = graph.vertexLabelOrNone(edgeLabel.sourceLabel()); - VertexLabel tgtLabel = graph.vertexLabelOrNone(edgeLabel.targetLabel()); - - VertexLabel otherVertexLabel; - if (isOutEdge) { - ownerVertex.correctVertexLabel(srcLabel); - otherVertexLabel = tgtLabel; - } else { - ownerVertex.correctVertexLabel(tgtLabel); - otherVertexLabel = srcLabel; - } - HugeVertex otherVertex = new HugeVertex(graph, otherVertexId, otherVertexLabel); - - ownerVertex.propNotLoaded(); - otherVertex.propNotLoaded(); - - HugeEdge edge = new HugeEdge(graph, null, edgeLabel); - edge.name(sortValues); - edge.vertices(isOutEdge, ownerVertex, otherVertex); - edge.assignId(); + BaseEdge element = BaseEdge.createEdge(ownerVertex.graph(), ownerVertex.element(), isOutEdge, + edgeLabel, sortValues, otherVertexId); + return attachEdge(ownerVertex, element); + } - if (isOutEdge) { + private static HugeEdge attachEdge(HugeVertex ownerVertex, BaseEdge element) { + HugeEdge edge = new HugeEdge(ownerVertex.graph(), element, ownerVertex); + HugeVertex otherVertex = edge.otherVertex(); + if (element.isOutEdge()) { ownerVertex.addOutEdge(edge); otherVertex.addInEdge(edge.switchOwner()); } else { ownerVertex.addInEdge(edge); otherVertex.addOutEdge(edge.switchOwner()); } - return edge; } @@ -566,25 +513,11 @@ public static HugeEdge constructEdgeWithoutLabel(HugeVertex ownerVertex, String sortValues, Id otherVertexId) { HugeGraph graph = ownerVertex.graph(); - HugeVertex otherVertex = new HugeVertex(graph, otherVertexId, - VertexLabel.NONE); - ownerVertex.propNotLoaded(); - otherVertex.propNotLoaded(); - - HugeEdge edge = new HugeEdge(graph, null, EdgeLabel.NONE); - edge.name(sortValues); - edge.vertices(isOutEdge, ownerVertex, otherVertex); - edge.assignId(); - - if (isOutEdge) { - ownerVertex.addOutEdge(edge); - otherVertex.addInEdge(edge.switchOwner()); - } else { - ownerVertex.addInEdge(edge); - otherVertex.addOutEdge(edge.switchOwner()); - } - - return edge; + EdgeLabel label = EdgeLabel.undefined(graph, EdgeLabel.NONE.id()); + VertexLabel otherLabel = VertexLabel.undefined(graph); + BaseEdge element = BaseEdge.createEdge(ownerVertex.element(), isOutEdge, label, + sortValues, otherVertexId, otherLabel); + return attachEdge(ownerVertex, element); } public static HugeEdge constructEdgeWithoutGraph(HugeVertex ownerVertex, @@ -592,37 +525,8 @@ public static HugeEdge constructEdgeWithoutGraph(HugeVertex ownerVertex, EdgeLabel edgeLabel, String sortValues, Id otherVertexId) { - Id ownerLabelId = edgeLabel.sourceLabel(); - Id otherLabelId = edgeLabel.targetLabel(); - VertexLabel srcLabel = new VertexLabel(null, ownerLabelId, "UNDEF"); - VertexLabel tgtLabel = new VertexLabel(null, otherLabelId, "UNDEF"); - - VertexLabel otherVertexLabel; - if (isOutEdge) { - ownerVertex.correctVertexLabel(srcLabel); - otherVertexLabel = tgtLabel; - } else { - ownerVertex.correctVertexLabel(tgtLabel); - otherVertexLabel = srcLabel; - } - HugeVertex otherVertex = new HugeVertex(null, otherVertexId, - otherVertexLabel); - ownerVertex.propNotLoaded(); - otherVertex.propNotLoaded(); - - HugeEdge edge = new HugeEdge(null, null, edgeLabel); - edge.name(sortValues); - edge.vertices(isOutEdge, ownerVertex, otherVertex); - edge.assignId(); - - if (isOutEdge) { - ownerVertex.addOutEdge(edge); - otherVertex.addInEdge(edge.switchOwner()); - } else { - ownerVertex.addInEdge(edge); - otherVertex.addOutEdge(edge.switchOwner()); - } - - return edge; + BaseEdge element = BaseEdge.createEdgeWithoutSchema(ownerVertex.graph(), ownerVertex.element(), + isOutEdge, edgeLabel, sortValues, otherVertexId); + return attachEdge(ownerVertex, element); } } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeEdgeProperty.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeEdgeProperty.java index f89e4f0cf4..ab3d87587b 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeEdgeProperty.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeEdgeProperty.java @@ -17,8 +17,8 @@ package org.apache.hugegraph.structure; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.util.E; import org.apache.tinkerpop.gremlin.structure.Property; @@ -30,6 +30,10 @@ public HugeEdgeProperty(HugeElement owner, PropertyKey key, V value) { super(owner, key, value); } + public HugeEdgeProperty(HugeElement owner, BaseProperty property) { + super(owner, property); + } + @Override public HugeType type() { return this.pkey.aggregateType().isNone() ? @@ -68,6 +72,6 @@ public int hashCode() { public HugeEdgeProperty switchEdgeOwner() { assert this.owner instanceof HugeEdge; return new HugeEdgeProperty<>(((HugeEdge) this.owner).switchOwner(), - this.pkey, this.value); + this.baseProperty()); } } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeElement.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeElement.java index adb12f31bc..b3f46c46d3 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeElement.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeElement.java @@ -17,66 +17,55 @@ package org.apache.hugegraph.structure; -import java.util.ArrayList; +import java.util.AbstractCollection; import java.util.Collection; -import java.util.Date; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; -import java.util.function.Supplier; +import java.util.function.Consumer; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.tx.GraphTransaction; import org.apache.hugegraph.perf.PerfUtil.Watched; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.SchemaLabel; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; +import org.apache.hugegraph.type.GraphType; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.Idfiable; import org.apache.hugegraph.type.define.Cardinality; import org.apache.hugegraph.type.define.HugeKeys; -import org.apache.hugegraph.util.CollectionUtil; import org.apache.hugegraph.util.E; import org.apache.hugegraph.util.InsertionOrderUtil; -import org.apache.hugegraph.util.collection.CollectionFactory; import org.apache.tinkerpop.gremlin.structure.Element; import org.apache.tinkerpop.gremlin.structure.T; import org.apache.tinkerpop.gremlin.structure.util.ElementHelper; import org.eclipse.collections.api.iterator.IntIterator; -import org.eclipse.collections.api.map.primitive.MutableIntObjectMap; public abstract class HugeElement implements Element, GraphType, Idfiable, Comparable { - private static final MutableIntObjectMap> EMPTY_MAP = - CollectionFactory.newIntObjectMap(); - private final HugeGraph graph; - private MutableIntObjectMap> properties; - // TODO: move into properties to keep small object - private long expiredTime; - - private boolean removed; - private boolean fresh; - private boolean propLoaded; - private boolean defaultValueUpdated; public HugeElement(final HugeGraph graph) { E.checkArgument(graph != null, "HugeElement graph can't be null"); this.graph = graph; - this.properties = EMPTY_MAP; - this.expiredTime = 0L; - this.removed = false; - this.fresh = false; - this.propLoaded = true; - this.defaultValueUpdated = false; } + /** + * Shared state for internal adapters and codecs. As with setProperty(), mutations + * through this view bypass transaction callbacks; application callers must use + * the graph/TinkerPop mutation APIs to update persisted elements and indexes. + */ + public abstract BaseElement element(); + + protected abstract HugeProperty wrapProperty(BaseProperty property); + public abstract SchemaLabel schemaLabel(); protected abstract GraphTransaction tx(); @@ -89,22 +78,7 @@ protected abstract void onUpdateProperty(Cardinality cardinality, protected abstract boolean ensureFilledProperties(boolean throwIfNotExist); protected void updateToDefaultValueIfNone() { - if (this.fresh() || this.defaultValueUpdated) { - return; - } - this.defaultValueUpdated = true; - // Set default value if needed - for (Id pkeyId : this.schemaLabel().properties()) { - if (this.properties.containsKey(intFromId(pkeyId))) { - continue; - } - PropertyKey pkey = this.graph().propertyKey(pkeyId); - Object value = pkey.defaultValue(); - if (value != null) { - this.setProperty(this.newProperty(pkey, value)); - } - } - this.defaultValueUpdated = true; + this.element().updateDefaultValues(this.graph()::propertyKey); } @Override @@ -113,31 +87,31 @@ public HugeGraph graph() { } protected void removed(boolean removed) { - this.removed = removed; + this.element().removed(removed); } public boolean removed() { - return this.removed; + return this.element().removed(); } protected void fresh(boolean fresh) { - this.fresh = fresh; + this.element().fresh(fresh); } public boolean fresh() { - return this.fresh; + return this.element().fresh(); } public boolean isPropLoaded() { - return this.propLoaded; + return this.element().propLoaded(); } protected void propLoaded() { - this.propLoaded = true; + this.element().propLoaded(true); } public void propNotLoaded() { - this.propLoaded = false; + this.element().propLoaded(false); } public void forceLoad() { @@ -145,59 +119,38 @@ public void forceLoad() { } public void committed() { - this.fresh = false; + this.element().fresh(false); // Set expired time this.setExpiredTimeIfNeeded(); } public void setExpiredTimeIfNeeded() { - SchemaLabel label = this.schemaLabel(); - if (label.ttl() == 0L) { - return; - } - long now = this.graph.now(); - if (SchemaLabel.NONE_ID.equals(label.ttlStartTime())) { - this.expiredTime(now + label.ttl()); - return; - } - Date date = this.getPropertyValue(label.ttlStartTime()); - if (date == null) { - this.expiredTime(now + label.ttl()); - return; - } - long expired = date.getTime() + label.ttl(); - E.checkArgument(expired > now, - "The expired time '%s' of '%s' is prior to now: %s", - new Date(expired), this, now); - this.expiredTime(expired); + this.element().setExpiredTimeIfNeeded(this.graph.now()); } public long expiredTime() { - return this.expiredTime; + return this.element().expiredTime(); } public void expiredTime(long expiredTime) { - this.expiredTime = expiredTime; + this.element().expiredTime(expiredTime); } public boolean expired() { - return 0L < this.expiredTime && this.expiredTime < this.graph.now(); + return 0L < this.expiredTime() && this.expiredTime() < this.graph.now(); } public long ttl() { - if (this.expiredTime == 0L || this.expiredTime < this.graph.now()) { - return 0L; - } - return this.expiredTime - this.graph.now(); + return this.element().ttl(this.graph.now()); } public boolean hasTtl() { - return this.schemaLabel().ttl() > 0L; + return this.element().hasTtl(); } public Set getPropertyKeys() { Set propKeys = InsertionOrderUtil.newSet(); - IntIterator keys = this.properties.keysView().intIterator(); + IntIterator keys = this.element().properties().keysView().intIterator(); while (keys.hasNext()) { propKeys.add(IdGenerator.of(keys.next())); } @@ -205,7 +158,39 @@ public Set getPropertyKeys() { } public Collection> getProperties() { - return this.properties.values(); + Collection> properties = this.element().properties().values(); + return new AbstractCollection>() { + @Override + public Iterator> iterator() { + Iterator> iterator = properties.iterator(); + return new Iterator>() { + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public HugeProperty next() { + return HugeElement.this.wrapProperty(iterator.next()); + } + + @Override + public void remove() { + iterator.remove(); + } + }; + } + + @Override + public int size() { + return properties.size(); + } + + @Override + public void clear() { + properties.clear(); + } + }; } public Collection> getFilledProperties() { @@ -214,17 +199,12 @@ public Collection> getFilledProperties() { } public Map getPropertiesMap() { - Map props = InsertionOrderUtil.newMap(); - for (HugeProperty prop : this.properties.values()) { - props.put(prop.propertyKey().id(), prop.value()); - } - // TODO: return MutableIntObjectMap for this method? - return props; + return this.element().getPropertiesMap(); } public Collection> getAggregateProperties() { List> aggrProps = InsertionOrderUtil.newList(); - for (HugeProperty prop : this.properties.values()) { + for (HugeProperty prop : this.getProperties()) { if (prop.type().isAggregateProperty()) { aggrProps.add(prop); } @@ -232,59 +212,40 @@ public Collection> getAggregateProperties() { return aggrProps; } - @SuppressWarnings("unchecked") public HugeProperty getProperty(Id key) { - return (HugeProperty) this.properties.get(intFromId(key)); + BaseProperty property = this.element().getProperty(key); + return property == null ? null : this.wrapProperty(property); } - @SuppressWarnings("unchecked") public V getPropertyValue(Id key) { - HugeProperty prop = this.properties.get(intFromId(key)); - if (prop == null) { - return null; - } - return (V) prop.value(); + return this.element().getPropertyValue(key); } public boolean hasProperty(Id key) { - return this.properties.containsKey(intFromId(key)); + return this.element().hasProperty(key); } public boolean hasProperties() { - return !this.properties.isEmpty(); + return this.element().hasProperties(); } public int sizeOfProperties() { - return this.properties.size(); + return this.element().sizeOfProperties(); } public int sizeOfSubProperties() { - int size = 0; - for (HugeProperty p : this.properties.values()) { - size++; - if (p.propertyKey().cardinality() != Cardinality.SINGLE && - p.value() instanceof Collection) { - size += ((Collection) p.value()).size(); - } - } - return size; + return this.element().sizeOfSubProperties(); } @Watched(prefix = "element") public HugeProperty setProperty(HugeProperty prop) { - if (this.properties == EMPTY_MAP) { - this.properties = CollectionFactory.newIntObjectMap(); - } - PropertyKey pkey = prop.propertyKey(); - - E.checkArgument(this.properties.containsKey(intFromId(pkey.id())) || - this.properties.size() < BytesBuffer.MAX_PROPERTIES, - "Exceeded the maximum number of properties"); - return this.properties.put(intFromId(pkey.id()), prop); + BaseProperty previous = this.element().addProperty(prop.baseProperty()); + return previous == null ? null : this.wrapProperty(previous); } public HugeProperty removeProperty(Id key) { - return this.properties.remove(intFromId(key)); + BaseProperty previous = this.element().removeProperty(key); + return previous == null ? null : this.wrapProperty(previous); } public HugeProperty addProperty(PropertyKey pkey, V value) { @@ -292,92 +253,30 @@ public HugeProperty addProperty(PropertyKey pkey, V value) { } @Watched(prefix = "element") - public HugeProperty addProperty(PropertyKey pkey, V value, - boolean notify) { - HugeProperty prop = null; - switch (pkey.cardinality()) { - case SINGLE: - prop = this.newProperty(pkey, value); - if (notify) { - /* - * NOTE: this method should be called before setProperty() - * because tx need to delete index without the new property - */ - this.onUpdateProperty(pkey.cardinality(), prop); - } - this.setProperty(prop); - break; - case SET: - prop = this.addProperty(pkey, value, HashSet::new); - if (notify) { - this.onUpdateProperty(pkey.cardinality(), prop); - } - break; - case LIST: - prop = this.addProperty(pkey, value, ArrayList::new); - if (notify) { - this.onUpdateProperty(pkey.cardinality(), prop); - } - break; - default: - assert false; - break; - } - return prop; - } - - @Watched(prefix = "element") - @SuppressWarnings({"rawtypes", "unchecked"}) - private HugeProperty addProperty(PropertyKey pkey, V value, - Supplier> supplier) { - assert pkey.cardinality().multiple(); - HugeProperty> property; - if (this.hasProperty(pkey.id())) { - property = this.getProperty(pkey.id()); - } else { - property = this.newProperty(pkey, supplier.get()); - this.setProperty(property); - } - - Collection values; - if (pkey.cardinality() == Cardinality.SET) { - if (value instanceof Set) { - values = (Set) value; - } else { - values = CollectionUtil.toSet(value); - } - } else { - assert pkey.cardinality() == Cardinality.LIST; - if (value instanceof List) { - values = (List) value; - } else { - values = CollectionUtil.toList(value); + public HugeProperty addProperty(PropertyKey pkey, V value, boolean notify) { + Consumer> callback = property -> { + if (notify) { + this.onUpdateProperty(pkey.cardinality(), this.wrapProperty(property)); } - } - property.value().addAll(pkey.validValueOrThrow(values)); - - // Any better ways? - return (HugeProperty) property; + }; + BaseProperty property = this.element().addProperty( + pkey, value, (key, val) -> this.newProperty(key, val).baseProperty(), + callback, callback); + return this.wrapProperty(property); } public void resetProperties() { - this.properties = CollectionFactory.newIntObjectMap(); - this.propLoaded = false; + this.element().resetProperties(); + this.element().propLoaded(false); } protected void copyProperties(HugeElement element) { - if (element.properties == EMPTY_MAP) { - this.properties = EMPTY_MAP; - } else { - this.properties = CollectionFactory.newIntObjectMap( - element.properties); - } - this.propLoaded = true; + this.element().copyProperties(element.element()); } public HugeElement copyAsFresh() { HugeElement elem = this.copy(); - elem.fresh = true; + elem.fresh(true); return elem; } @@ -512,9 +411,7 @@ public static final Object getLabelValue(Object... keyValues) { } public static int intFromId(Id id) { - E.checkArgument(id instanceof IdGenerator.LongId, - "Can't get number from %s(%s)", id, id.getClass()); - return ((IdGenerator.LongId) id).intValue(); + return BaseElement.intFromId(id); } public static final class ElementKeys { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeFeatures.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeFeatures.java index 49be0ecbe9..52b0345ebe 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeFeatures.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeFeatures.java @@ -20,7 +20,7 @@ import java.util.UUID; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.config.CoreOptions; import org.apache.tinkerpop.gremlin.structure.Graph; import org.apache.tinkerpop.gremlin.structure.VertexProperty; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeIndex.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeIndex.java deleted file mode 100644 index 6e76913935..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeIndex.java +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.structure; - -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.Id.IdType; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.id.SplicingIdGenerator; -import org.apache.hugegraph.backend.serializer.BytesBuffer; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.type.HugeType; -import org.apache.hugegraph.type.define.DataType; -import org.apache.hugegraph.util.E; -import org.apache.hugegraph.util.HashUtil; -import org.apache.hugegraph.util.InsertionOrderUtil; -import org.apache.hugegraph.util.NumericUtil; - -public class HugeIndex implements GraphType, Cloneable { - - private final HugeGraph graph; - private Object fieldValues; - private IndexLabel indexLabel; - private Set elementIds; - private static final int HUGE_TYPE_CODE_LENGTH = 1; - - public HugeIndex(HugeGraph graph, IndexLabel indexLabel) { - E.checkNotNull(graph, "graph"); - E.checkNotNull(indexLabel, "label"); - E.checkNotNull(indexLabel.id(), "label id"); - this.graph = graph; - this.indexLabel = indexLabel; - this.elementIds = new LinkedHashSet<>(); - this.fieldValues = null; - } - - @Override - public String name() { - return this.indexLabel.name(); - } - - @Override - public HugeType type() { - if (this.indexLabel == IndexLabel.label(HugeType.VERTEX)) { - return HugeType.VERTEX_LABEL_INDEX; - } else if (this.indexLabel == IndexLabel.label(HugeType.EDGE)) { - return HugeType.EDGE_LABEL_INDEX; - } - return this.indexLabel.indexType().type(); - } - - public HugeGraph graph() { - return this.graph; - } - - public Id id() { - return formatIndexId(type(), this.indexLabelId(), this.fieldValues()); - } - - public Id hashId() { - return formatIndexHashId(type(), this.indexLabelId(), this.fieldValues()); - } - - public Object fieldValues() { - return this.fieldValues; - } - - public void fieldValues(Object fieldValues) { - this.fieldValues = fieldValues; - } - - public Id indexLabelId() { - return this.indexLabel.id(); - } - - public IndexLabel indexLabel() { - return this.indexLabel; - } - - public IdWithExpiredTime elementIdWithExpiredTime() { - E.checkState(this.elementIds.size() == 1, - "Expect one element id, actual %s", - this.elementIds.size()); - return this.elementIds.iterator().next(); - } - - public Id elementId() { - return this.elementIdWithExpiredTime().id(); - } - - public Set elementIds() { - Set ids = InsertionOrderUtil.newSet(this.elementIds.size()); - for (IdWithExpiredTime idWithExpiredTime : this.elementIds) { - ids.add(idWithExpiredTime.id()); - } - return Collections.unmodifiableSet(ids); - } - - public Set expiredElementIds() { - long now = this.graph.now(); - Set expired = InsertionOrderUtil.newSet(); - for (IdWithExpiredTime id : this.elementIds) { - if (0L < id.expiredTime && id.expiredTime < now) { - expired.add(id); - } - } - this.elementIds.removeAll(expired); - return expired; - } - - public void elementIds(Id elementId) { - this.elementIds(elementId, 0L); - } - - public void elementIds(Id elementId, long expiredTime) { - this.elementIds.add(new IdWithExpiredTime(elementId, expiredTime)); - } - - public void resetElementIds() { - this.elementIds = new LinkedHashSet<>(); - } - - public long expiredTime() { - return this.elementIdWithExpiredTime().expiredTime(); - } - - public boolean hasTtl() { - if (this.indexLabel.system()) { - return false; - } - return this.indexLabel.baseLabel().ttl() > 0L; - } - - public long ttl() { - return this.expiredTime() - this.graph.now(); - } - - @Override - public HugeIndex clone() { - try { - return (HugeIndex) super.clone(); - } catch (CloneNotSupportedException e) { - throw new HugeException("Failed to clone HugeIndex", e); - } - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof HugeIndex)) { - return false; - } - - HugeIndex other = (HugeIndex) obj; - return this.id().equals(other.id()); - } - - @Override - public int hashCode() { - return this.id().hashCode(); - } - - @Override - public String toString() { - return String.format("{label=%s<%s>, fieldValues=%s, elementIds=%s}", - this.indexLabel.name(), - this.indexLabel.indexType().string(), - this.fieldValues, this.elementIds); - } - - public static Id formatIndexHashId(HugeType type, Id indexLabel, - Object fieldValues) { - E.checkState(!type.isRangeIndex(), - "RangeIndex can't return a hash id"); - String value = fieldValues == null ? "" : fieldValues.toString(); - return formatIndexId(type, indexLabel, HashUtil.hash(value)); - } - - public static Id formatIndexId(HugeType type, Id indexLabelId, - Object fieldValues) { - if (type.isStringIndex()) { - String value = ""; - if (fieldValues instanceof Id) { - value = IdGenerator.asStoredString((Id) fieldValues); - } else if (fieldValues != null) { - value = fieldValues.toString(); - } - /* - * Modify order between index label and field-values to put the - * index label in front(hugegraph-1317) - */ - String strIndexLabelId = IdGenerator.asStoredString(indexLabelId); - return SplicingIdGenerator.splicing(type.string(), strIndexLabelId, value); - } else { - assert type.isRangeIndex(); - int length = type.isRange4Index() ? 4 : 8; - BytesBuffer buffer = BytesBuffer.allocate(HUGE_TYPE_CODE_LENGTH + 4 + length); - buffer.write(type.code()); - buffer.writeInt(SchemaElement.schemaId(indexLabelId)); - if (fieldValues != null) { - E.checkState(fieldValues instanceof Number, - "Field value of range index must be number:" + - " %s", fieldValues.getClass().getSimpleName()); - byte[] bytes = number2bytes((Number) fieldValues); - buffer.write(bytes); - } - return buffer.asId(); - } - } - - public static HugeIndex parseIndexId(HugeGraph graph, HugeType type, - byte[] id) { - Object values; - IndexLabel indexLabel; - if (type.isStringIndex()) { - Id idObject = IdGenerator.of(id, IdType.STRING); - String[] parts = SplicingIdGenerator.parse(idObject); - E.checkState(parts.length == 3, "Invalid secondary index id"); - Id label = IdGenerator.ofStoredString(parts[1], IdType.LONG); - indexLabel = IndexLabel.label(graph, label); - values = parts[2]; - } else { - assert type.isRange4Index() || type.isRange8Index(); - final int labelLength = 4; - E.checkState(id.length > labelLength, "Invalid range index id"); - BytesBuffer buffer = BytesBuffer.wrap(id); - buffer.read(HUGE_TYPE_CODE_LENGTH); - Id label = IdGenerator.of(buffer.readInt()); - indexLabel = IndexLabel.label(graph, label); - List fields = indexLabel.indexFields(); - E.checkState(fields.size() == 1, "Invalid range index fields"); - DataType dataType = graph.propertyKey(fields.get(0)).dataType(); - E.checkState(dataType.isNumber() || dataType.isDate(), - "Invalid range index field type"); - Class clazz = dataType.isNumber() ? - dataType.clazz() : DataType.LONG.clazz(); - values = bytes2number(buffer.read(id.length - labelLength - HUGE_TYPE_CODE_LENGTH), - clazz); - } - HugeIndex index = new HugeIndex(graph, indexLabel); - index.fieldValues(values); - return index; - } - - public static byte[] number2bytes(Number number) { - if (number instanceof Byte) { - // Handle byte as integer to store as 4 bytes in RANGE4_INDEX - number = number.intValue(); - } - return NumericUtil.numberToSortableBytes(number); - } - - public static Number bytes2number(byte[] bytes, Class clazz) { - return NumericUtil.sortableBytesToNumber(bytes, clazz); - } - - public static class IdWithExpiredTime { - - private Id id; - private long expiredTime; - - public IdWithExpiredTime(Id id, long expiredTime) { - this.id = id; - this.expiredTime = expiredTime; - } - - public Id id() { - return this.id; - } - - public long expiredTime() { - return this.expiredTime; - } - - @Override - public String toString() { - return String.format("%s(%s)", this.id, this.expiredTime); - } - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeProperty.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeProperty.java index 65472e148b..9cc41db401 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeProperty.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeProperty.java @@ -19,8 +19,9 @@ import java.util.NoSuchElementException; -import org.apache.hugegraph.backend.id.SplicingIdGenerator; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.id.SplicingIdGenerator; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.type.GraphType; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.util.E; import org.apache.tinkerpop.gremlin.structure.Property; @@ -31,7 +32,7 @@ public abstract class HugeProperty implements Property, GraphType { protected final HugeElement owner; protected final PropertyKey pkey; - protected V value; + protected BaseProperty property; public HugeProperty(HugeElement owner, PropertyKey pkey, V value) { E.checkArgument(owner != null, "Property owner can't be null"); @@ -40,7 +41,19 @@ public HugeProperty(HugeElement owner, PropertyKey pkey, V value) { this.owner = owner; this.pkey = pkey; - this.value = pkey.validValueOrThrow(value); + this.property = new BaseProperty<>(pkey, pkey.validValueOrThrow(value)); + } + + protected HugeProperty(HugeElement owner, BaseProperty property) { + E.checkArgument(owner != null, "Property owner can't be null"); + E.checkArgument(property != null, "Property can't be null"); + this.owner = owner; + this.pkey = property.propertyKey(); + this.property = property; + } + + public BaseProperty baseProperty() { + return this.property; } public PropertyKey propertyKey() { @@ -68,16 +81,16 @@ public String key() { @Override public V value() throws NoSuchElementException { - return this.value; + return this.property.value(); } public Object serialValue(boolean encodeNumber) { - return this.pkey.serialValue(this.value, encodeNumber); + return this.property.serialValue(encodeNumber); } @Override public boolean isPresent() { - return null != this.value; + return null != this.value(); } public boolean isAggregateType() { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeVertex.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeVertex.java index 573e2f948e..e33cd1d77c 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeVertex.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeVertex.java @@ -17,46 +17,42 @@ package org.apache.hugegraph.structure; +import java.util.AbstractCollection; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import java.util.IdentityHashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.Set; +import java.util.Map; import org.apache.commons.collections.CollectionUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.id.SnowflakeIdGenerator; -import org.apache.hugegraph.backend.id.SplicingIdGenerator; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.SplicingIdGenerator; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.query.QueryResults; -import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.backend.tx.GraphTransaction; import org.apache.hugegraph.config.CoreOptions; import org.apache.hugegraph.perf.PerfUtil.Watched; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.VertexLabel; -import org.apache.hugegraph.task.HugeTask; -import org.apache.hugegraph.task.HugeTaskResult; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Cardinality; -import org.apache.hugegraph.type.define.CollectionType; import org.apache.hugegraph.type.define.Directions; import org.apache.hugegraph.type.define.HugeKeys; import org.apache.hugegraph.type.define.IdStrategy; import org.apache.hugegraph.util.E; -import org.apache.hugegraph.util.collection.CollectionFactory; -import org.apache.logging.log4j.util.Strings; +import org.apache.hugegraph.util.TinkerPopUtil; import org.apache.tinkerpop.gremlin.structure.Direction; import org.apache.tinkerpop.gremlin.structure.Edge; -import org.apache.tinkerpop.gremlin.structure.Graph; import org.apache.tinkerpop.gremlin.structure.T; import org.apache.tinkerpop.gremlin.structure.Vertex; import org.apache.tinkerpop.gremlin.structure.VertexProperty; @@ -64,32 +60,20 @@ import org.apache.tinkerpop.gremlin.structure.util.StringFactory; import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyVertexProperty; -import com.google.common.collect.ImmutableList; public class HugeVertex extends HugeElement implements Vertex, Cloneable { - private static final List EMPTY_LIST = ImmutableList.of(); - - /* - * Labels of the removed server info and role election vertices. Graphs - * created by older versions may still store them. - */ - private static final String LEGACY_SERVER_LABEL = Graph.Hidden.hide("server"); - private static final String LEGACY_ROLE_DATA_LABEL = Graph.Hidden.hide("role_data"); - - private Id id; - private VertexLabel label; - protected Collection edges; + private BaseVertex element; + private Map edgeWrappers; public HugeVertex(final HugeGraph graph, Id id, VertexLabel label) { super(graph); E.checkArgumentNotNull(label, "Vertex label can't be null"); - this.label = label; - - this.id = id; - this.edges = EMPTY_LIST; - if (this.id != null) { + this.element = new BaseVertex(id, label, BaseVertex.TypeContext.ENGINE); + this.element.encodeNumber(this.graph().option(CoreOptions.VERTEX_ENCODE_PK_NUMBER)); + this.edgeWrappers = new IdentityHashMap<>(); + if (this.element.id() != null) { if (label.idStrategy() == IdStrategy.CUSTOMIZE_UUID) { this.assignId(id); } else { @@ -98,56 +82,45 @@ public HugeVertex(final HugeGraph graph, Id id, VertexLabel label) { } } + /** Adopt decoded shared state without copying its property values. */ + public HugeVertex(final HugeGraph graph, BaseVertex element) { + super(graph); + E.checkArgumentNotNull(element, "Vertex element can't be null"); + E.checkArgumentNotNull(element.schemaLabel(), "Vertex label can't be null"); + this.element = element; + this.element.typeContext(BaseVertex.TypeContext.ENGINE); + this.element.encodeNumber(this.graph().option(CoreOptions.VERTEX_ENCODE_PK_NUMBER)); + this.edgeWrappers = new IdentityHashMap<>(); + if (element.id() != null) { + this.checkIdLength(); + } + } + @Override public HugeType type() { - if (label != null && - (label.name().equals(HugeTask.P.TASK) || - label.name().equals(HugeTaskResult.P.TASKRESULT))) { - return HugeType.TASK; - } - if (label != null && - (label.name().equals(LEGACY_SERVER_LABEL) || - label.name().equals(LEGACY_ROLE_DATA_LABEL))) { - return HugeType.SERVER; - } - return HugeType.VERTEX; + return this.element.type(); } @Override public Id id() { - return this.id; + return this.element.id(); } @Override public VertexLabel schemaLabel() { - assert VertexLabel.OLAP_VL.equals(this.label) || - this.graph().sameAs(this.label.graph()); - return this.label; + assert VertexLabel.OLAP_VL.equals(this.element.schemaLabel()) || + this.graph().sameAs(this.element.schemaLabel().graph()); + return this.element.schemaLabel(); } @Override public String name() { - E.checkState(this.label.idStrategy() == IdStrategy.PRIMARY_KEY, - "Only primary key vertex has name, " + - "but got '%s' with id strategy '%s'", - this, this.label.idStrategy()); - String name; - if (this.id != null) { - String[] parts = SplicingIdGenerator.parse(this.id); - E.checkState(parts.length == 2, - "Invalid primary key vertex id '%s'", this.id); - name = parts[1]; - } else { - assert this.id == null; - List propValues = this.primaryValues(); - E.checkState(!propValues.isEmpty(), - "Primary values must not be empty " + - "(has properties %s)", hasProperties()); - name = ConditionQuery.concatValues(propValues); - E.checkArgument(!name.isEmpty(), - "The value of primary key can't be empty"); - } - return name; + return this.element.name(); + } + + @Override + public BaseVertex element() { + return this.element; } public void assignId(Id id) { @@ -156,31 +129,31 @@ public void assignId(Id id) { @Watched(prefix = "vertex") public void assignId(Id id, boolean force) { - IdStrategy strategy = this.label.idStrategy(); + IdStrategy strategy = this.element.schemaLabel().idStrategy(); // Generate an id and assign switch (strategy) { case CUSTOMIZE_STRING: assert !id.number(); - this.id = id; + this.element.id(id); break; case CUSTOMIZE_NUMBER: assert id.number(); - this.id = id; + this.element.id(id); break; case CUSTOMIZE_UUID: - this.id = id.uuid() ? id : IdGenerator.of(id.asString(), true); + this.element.id(id.uuid() ? id : IdGenerator.of(id.asString(), true)); break; case PRIMARY_KEY: - this.id = SplicingIdGenerator.instance().generate(this); + this.element.id(SplicingIdGenerator.instance().generate(this.element())); break; case AUTOMATIC: if (force) { // Resume id for AUTOMATIC id strategy in restoring mode assert id.number(); - this.id = id; + this.element.id(id); } else { - this.id = SnowflakeIdGenerator.instance(this.graph()) - .generate(this); + this.element.id(SnowflakeIdGenerator.instance(this.graph()) + .generate(this.element())); } break; default: @@ -190,14 +163,14 @@ public void assignId(Id id, boolean force) { } protected void checkIdLength() { - assert this.id != null; - int len = this.id.asBytes().length; + assert this.element.id() != null; + int len = this.element.id().asBytes().length; if (len <= BytesBuffer.ID_LEN_MAX) { return; } E.checkArgument(false, "The max length of vertex id is %s, but got %s {%s}", - BytesBuffer.ID_LEN_MAX, len, this.id); + BytesBuffer.ID_LEN_MAX, len, this.element.id()); } @Override @@ -206,67 +179,67 @@ public String label() { } public void correctVertexLabel(VertexLabel correctLabel) { - E.checkArgumentNotNull(correctLabel, "Vertex label can't be null"); - if (this.label != null && !this.label.undefined() && - !correctLabel.undefined()) { - E.checkArgument(this.label.equals(correctLabel), - "Vertex label can't be changed from '%s' to '%s'", - this.label, correctLabel); - } - this.label = correctLabel; + this.element.correctVertexLabel(correctLabel); } @Watched(prefix = "vertex") protected List primaryValues() { - E.checkArgument(this.label.idStrategy() == IdStrategy.PRIMARY_KEY, - "The id strategy '%s' don't have primary keys", - this.label.idStrategy()); - List primaryKeys = this.label.primaryKeys(); - E.checkArgument(!primaryKeys.isEmpty(), - "Primary key can't be empty for id strategy '%s'", - IdStrategy.PRIMARY_KEY); - - boolean encodeNumber = this.graph() - .option(CoreOptions.VERTEX_ENCODE_PK_NUMBER); - List propValues = new ArrayList<>(primaryKeys.size()); - for (Id pk : primaryKeys) { - HugeProperty property = this.getProperty(pk); - E.checkState(property != null, - "The value of primary key '%s' can't be null", - this.graph().propertyKey(pk).name()); - Object propValue = property.serialValue(encodeNumber); - if (Strings.EMPTY.equals(propValue)) { - propValue = ConditionQuery.INDEX_VALUE_EMPTY; - } - propValues.add(propValue); - } - return propValues; + return this.element.primaryValues(); } public boolean existsEdges() { - return !this.edges.isEmpty(); + return !this.element.edges().isEmpty(); } public Collection getEdges() { - return Collections.unmodifiableCollection(this.edges); + Collection edges = this.element.edges(); + return Collections.unmodifiableCollection(new AbstractCollection() { + @Override + public Iterator iterator() { + Iterator iterator = edges.iterator(); + return new Iterator() { + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public HugeEdge next() { + BaseEdge edge = iterator.next(); + return HugeVertex.this.edgeWrappers.computeIfAbsent( + edge, value -> new HugeEdge(HugeVertex.this.graph(), value, + HugeVertex.this)); + } + }; + } + + @Override + public int size() { + return edges.size(); + } + }); } public void resetEdges() { - /* - * Use List to hold edges to reduce memory usage and operation time. - */ - this.edges = newList(); + this.resetEdges(false); + } + + protected void resetEdges(boolean unique) { + this.element.resetEdges(unique); + this.edgeWrappers.clear(); } public void removeEdge(HugeEdge edge) { - this.edges.remove(edge); + BaseEdge removed = this.element.removeEdge(edge.element()); + if (removed != null) { + this.edgeWrappers.remove(removed); + } } public void addEdge(HugeEdge edge) { - if (this.edges == EMPTY_LIST) { - this.edges = newList(); + if (this.element.addEdge(edge.element())) { + this.edgeWrappers.put(edge.element(), edge); } - this.edges.add(edge); } /** @@ -381,7 +354,7 @@ public void addInEdge(HugeEdge edge) { public Iterator getEdges(Directions direction, String... edgeLabels) { List list = new LinkedList<>(); - for (HugeEdge edge : this.edges) { + for (HugeEdge edge : this.getEdges()) { if (edge.matchDirection(direction) && edge.belongToLabels(edgeLabels)) { list.add(edge); @@ -404,7 +377,7 @@ public Iterator getVertices(Directions direction, @Watched(prefix = "vertex") @Override public Iterator edges(Direction tinkerpopDir, String... edgeLabels) { - Directions direction = Directions.convert(tinkerpopDir); + Directions direction = TinkerPopUtil.direction(tinkerpopDir); Id[] edgeLabelIds = this.graph().mapElName2Id(edgeLabels); Query query = GraphTransaction.constructEdgesQuery(this.id(), direction, edgeLabelIds); @@ -463,17 +436,17 @@ public VertexProperty property(VertexProperty.Cardinality cardinality, */ if (cardinality != VertexProperty.Cardinality.single) { E.checkArgument(propertyKey.cardinality() == - Cardinality.convert(cardinality), + TinkerPopUtil.cardinality(cardinality), "Invalid cardinality '%s' for property key '%s', " + "expect '%s'", cardinality, key, propertyKey.cardinality().string()); } // Check key in vertex label - E.checkArgument(VertexLabel.OLAP_VL.equals(this.label) || - this.label.properties().contains(propertyKey.id()), + E.checkArgument(VertexLabel.OLAP_VL.equals(this.element.schemaLabel()) || + this.element.schemaLabel().properties().contains(propertyKey.id()), "Invalid property '%s' for vertex label '%s'", - key, this.label); + key, this.element.schemaLabel()); // Primary-Keys can only be set once if (this.schemaLabel().primaryKeys().contains(propertyKey.id())) { E.checkArgument(!this.hasProperty(propertyKey.id()), @@ -501,6 +474,11 @@ protected HugeVertexProperty newProperty(PropertyKey pkey, V val) { return new HugeVertexProperty<>(this, pkey, val); } + @Override + protected HugeVertexProperty wrapProperty(BaseProperty property) { + return new HugeVertexProperty<>(this, property); + } + @Watched(prefix = "vertex") @Override protected void onUpdateProperty(Cardinality cardinality, @@ -543,7 +521,7 @@ protected boolean ensureFilledProperties(boolean throwIfNotExist) { if (vertex == null && !throwIfNotExist) { return false; } - E.checkState(vertex != null, "Vertex '%s' does not exist", this.id); + E.checkState(vertex != null, "Vertex '%s' does not exist", this.element.id()); if (vertex.schemaLabel().undefined() || !vertex.schemaLabel().equals(this.schemaLabel())) { // Update vertex label of dangling edge to undefined @@ -596,20 +574,7 @@ public Iterator> properties(String... keys) { @Override public Object sysprop(HugeKeys key) { - switch (key) { - case ID: - return this.id(); - case LABEL: - return this.schemaLabel().id(); - case PRIMARY_VALUES: - return this.name(); - case PROPERTIES: - return this.getPropertiesMap(); - default: - E.checkArgument(false, - "Invalid system property '%s' of Vertex", key); - return null; - } + return this.element.sysprop(key); } public boolean valid() { @@ -622,14 +587,12 @@ public boolean valid() { } /** - * Clear edges/properties of the cloned vertex, and set `removed` true + * Clear edges/properties of the cloned vertex, and set `removed` true. * * @return a new vertex */ public HugeVertex prepareRemoved() { - // NOTE: clear edges/properties of the cloned vertex and return HugeVertex vertex = this.clone(); - // Remove self vertex.removed(true); vertex.resetEdges(); vertex.resetProperties(); @@ -637,7 +600,7 @@ public HugeVertex prepareRemoved() { } public boolean olap() { - return this.label.olap(); + return this.element.schemaLabel().olap(); } @Override @@ -650,7 +613,10 @@ public HugeVertex copy() { @Override protected HugeVertex clone() { try { - return (HugeVertex) super.clone(); + HugeVertex vertex = (HugeVertex) super.clone(); + vertex.element = (BaseVertex) this.element.clone(); + vertex.edgeWrappers = new IdentityHashMap<>(this.edgeWrappers); + return vertex; } catch (CloneNotSupportedException e) { throw new HugeException("Failed to clone HugeVertex", e); } @@ -675,13 +641,7 @@ public static HugeVertex create(final GraphTransaction tx, return new HugeVertex4Insert(tx, id, label); } - private static Set newSet() { - return CollectionFactory.newSet(CollectionType.EC); - } - private static List newList() { - return CollectionFactory.newList(CollectionType.EC); - } private static final class HugeVertex4Insert extends HugeVertex { @@ -694,22 +654,14 @@ public HugeVertex4Insert(final GraphTransaction tx, * Use Set to hold edges inserted into vertex * to avoid duplicated edges */ - this.edges = newSet(); + this.resetEdges(true); this.tx = tx; this.fresh(true); } @Override public void resetEdges() { - this.edges = newSet(); - } - - @Override - public void addEdge(HugeEdge edge) { - if (this.edges == EMPTY_LIST) { - this.edges = newSet(); - } - this.edges.add(edge); + this.resetEdges(true); } @Override diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeVertexProperty.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeVertexProperty.java index 4cef519799..8ef5cca262 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeVertexProperty.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeVertexProperty.java @@ -20,8 +20,8 @@ import java.util.Iterator; import org.apache.hugegraph.exception.NotSupportException; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.util.E; import org.apache.tinkerpop.gremlin.structure.Element; @@ -36,6 +36,10 @@ public HugeVertexProperty(HugeElement owner, PropertyKey key, V value) { super(owner, key, value); } + public HugeVertexProperty(HugeElement owner, BaseProperty property) { + super(owner, property); + } + @Override public HugeType type() { return this.pkey.aggregateType().isNone() ? diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/DistributedTaskScheduler.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/DistributedTaskScheduler.java index 4e9e0b13a4..802049eb04 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/DistributedTaskScheduler.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/DistributedTaskScheduler.java @@ -32,10 +32,10 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.config.CoreOptions; import org.apache.hugegraph.exception.ConnectionException; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/EphemeralJobQueue.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/EphemeralJobQueue.java index c7c840a882..0b2debb553 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/EphemeralJobQueue.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/EphemeralJobQueue.java @@ -25,7 +25,7 @@ import java.util.concurrent.atomic.AtomicReference; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.tx.GraphTransaction; import org.apache.hugegraph.job.EphemeralJob; import org.apache.hugegraph.job.EphemeralJobBuilder; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/HugeTask.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/HugeTask.java index f63d4c0762..6d36212f56 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/HugeTask.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/HugeTask.java @@ -17,6 +17,7 @@ package org.apache.hugegraph.task; +import java.io.InterruptedIOException; import java.util.ArrayList; import java.util.Collections; import java.util.Date; @@ -29,11 +30,11 @@ import java.util.stream.Collector; import java.util.stream.Collectors; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.config.CoreOptions; import org.apache.hugegraph.exception.LimitExceedException; import org.apache.hugegraph.exception.NotFoundException; @@ -52,6 +53,7 @@ import org.apache.tinkerpop.gremlin.structure.Graph.Hidden; import org.apache.tinkerpop.gremlin.structure.T; import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalInterruptedException; import org.apache.tinkerpop.gremlin.structure.VertexProperty; import org.slf4j.Logger; @@ -346,9 +348,16 @@ public boolean cancel(boolean mayInterruptIfRunning) { return cancelled; } + private static boolean isInterrupted(Throwable error) { + Throwable cause = HugeException.rootCause(error); + return cause instanceof InterruptedException || + cause instanceof TraversalInterruptedException || + cause instanceof InterruptedIOException; + } + public boolean fail(Throwable e) { E.checkNotNull(e, "exception"); - if (!(this.cancelled() && HugeException.isInterrupted(e))) { + if (!(this.cancelled() && isInterrupted(e))) { LOG.warn("An exception occurred when running task: {}", this.id(), e); // Update status to FAILED if exception occurred(not interrupted) diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/HugeTaskResult.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/HugeTaskResult.java index 1c47ee9da5..9f01d60acc 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/HugeTaskResult.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/HugeTaskResult.java @@ -21,7 +21,7 @@ import java.util.Iterator; import java.util.List; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.util.Blob; import org.apache.hugegraph.util.E; import org.apache.hugegraph.util.Log; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/ServerInfoManager.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/ServerInfoManager.java index 3d3585caf4..7155913fef 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/ServerInfoManager.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/ServerInfoManager.java @@ -18,8 +18,8 @@ package org.apache.hugegraph.task; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.masterelection.GlobalMasterInfo; import org.apache.hugegraph.type.define.NodeRole; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/StandardTaskScheduler.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/StandardTaskScheduler.java index 3367572580..9c0d3e9d18 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/StandardTaskScheduler.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/StandardTaskScheduler.java @@ -28,13 +28,13 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeoutException; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.page.PageInfo; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.backend.store.BackendStore; import org.apache.hugegraph.config.CoreOptions; @@ -43,8 +43,8 @@ import org.apache.hugegraph.iterator.ExtendableIterator; import org.apache.hugegraph.iterator.MapperIterator; import org.apache.hugegraph.job.EphemeralJob; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.task.HugeTask.P; import org.apache.hugegraph.task.TaskCallable.SysTaskCallable; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskAndResultScheduler.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskAndResultScheduler.java index ffb54c71b6..70ccf10ed3 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskAndResultScheduler.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskAndResultScheduler.java @@ -23,16 +23,16 @@ import java.util.Map; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.backend.store.BackendStore; import org.apache.hugegraph.exception.NotFoundException; import org.apache.hugegraph.iterator.ListIterator; import org.apache.hugegraph.iterator.MapperIterator; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.HugeKeys; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskAndResultTransaction.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskAndResultTransaction.java index c39ae23615..c9f766f2ef 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskAndResultTransaction.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskAndResultTransaction.java @@ -20,13 +20,13 @@ import java.util.ArrayList; import java.util.List; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.HugeGraphParams; import org.apache.hugegraph.backend.store.BackendStore; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.type.define.Cardinality; import org.apache.hugegraph.type.define.DataType; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskCallable.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskCallable.java index 4e0550f5c9..5872acd9dd 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskCallable.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskCallable.java @@ -21,7 +21,7 @@ import java.util.Set; import java.util.concurrent.Callable; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.HugeGraphParams; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskManager.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskManager.java index cbdc1948c2..e529897a7d 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskManager.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskManager.java @@ -25,7 +25,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraphParams; import org.apache.hugegraph.concurrent.PausableScheduledThreadPool; import org.apache.hugegraph.util.Consumers; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskScheduler.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskScheduler.java index ea10cd006d..a4f8cbd56e 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskScheduler.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskScheduler.java @@ -24,7 +24,7 @@ import java.util.concurrent.TimeoutException; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; public interface TaskScheduler { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskTransaction.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskTransaction.java index 9dd4a46aa0..74e96cd18b 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskTransaction.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/TaskTransaction.java @@ -21,17 +21,17 @@ import java.util.Iterator; import java.util.List; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.HugeGraphParams; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.backend.store.BackendStore; import org.apache.hugegraph.backend.tx.GraphTransaction; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.VertexLabel; -import org.apache.hugegraph.structure.HugeIndex; +import org.apache.hugegraph.struct.schema.VertexLabel; +import org.apache.hugegraph.structure.Index; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Cardinality; @@ -96,7 +96,7 @@ private void removeLabelIndex(HugeVertex vertex) { return; } - HugeIndex index = new HugeIndex(this.graph(), + Index index = new Index(this.graph(), IndexLabel.label(vertex.type())); index.fieldValues(vertex.schemaLabel().id()); index.elementIds(vertex.id(), vertex.expiredTime()); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/CollectionPathsTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/CollectionPathsTraverser.java index c2a5ba4f79..d820dd03b4 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/CollectionPathsTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/CollectionPathsTraverser.java @@ -24,7 +24,7 @@ import java.util.Set; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.traversal.algorithm.steps.EdgeStep; import org.apache.hugegraph.traversal.algorithm.strategy.TraverseStrategy; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/CountTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/CountTraverser.java index 1b9defac46..442dbaeb31 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/CountTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/CountTraverser.java @@ -23,7 +23,7 @@ import org.apache.commons.lang.mutable.MutableLong; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.iterator.FilterIterator; import org.apache.hugegraph.iterator.FlatMapperIterator; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/CustomizePathsTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/CustomizePathsTraverser.java index b639df2d4c..dab3d79f70 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/CustomizePathsTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/CustomizePathsTraverser.java @@ -23,7 +23,7 @@ import java.util.Map; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.traversal.algorithm.steps.WeightedEdgeStep; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/CustomizedCrosspointsTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/CustomizedCrosspointsTraverser.java index be3a244eb2..4c0ede0806 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/CustomizedCrosspointsTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/CustomizedCrosspointsTraverser.java @@ -25,7 +25,7 @@ import java.util.stream.Collectors; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.traversal.algorithm.steps.EdgeStep; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java index 98fbfbd9d9..d47f987e0a 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java @@ -20,10 +20,10 @@ import java.util.Iterator; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.ConditionQuery; import org.apache.hugegraph.iterator.FilterIterator; -import org.apache.hugegraph.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Directions; import org.apache.hugegraph.type.define.HugeKeys; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/FusiformSimilarityTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/FusiformSimilarityTraverser.java index 741a6ef6fe..87dd7c8876 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/FusiformSimilarityTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/FusiformSimilarityTraverser.java @@ -24,8 +24,8 @@ import org.apache.commons.lang3.mutable.MutableInt; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.schema.EdgeLabel; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.struct.schema.EdgeLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.type.define.Directions; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/HugeTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/HugeTraverser.java index fe8fa05687..a7bbdb9723 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/HugeTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/HugeTraverser.java @@ -34,13 +34,13 @@ import java.util.stream.Collectors; import org.apache.commons.collections.CollectionUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.Aggregate; -import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.Aggregate; +import org.apache.hugegraph.query.ConditionQuery; import org.apache.hugegraph.backend.query.EdgesQueryIterator; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.backend.tx.GraphTransaction; import org.apache.hugegraph.config.CoreOptions; @@ -50,7 +50,7 @@ import org.apache.hugegraph.iterator.LimitIterator; import org.apache.hugegraph.iterator.MapperIterator; import org.apache.hugegraph.perf.PerfUtil.Watched; -import org.apache.hugegraph.schema.SchemaLabel; +import org.apache.hugegraph.struct.schema.SchemaLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.traversal.algorithm.iterator.NestedIterator; @@ -483,7 +483,7 @@ private Iterator edgesOfVertex(Id source, EdgeStep edgeStep, if (filter != null) { ConditionQuery finalFilter = filter; edges = new FilterIterator<>(edges, (e) -> { - return finalFilter.test((HugeEdge) e); + return finalFilter.test(((HugeEdge) e).element()); }); } return edgeStep.skipSuperNodeIfNeeded(edges); @@ -544,7 +544,7 @@ private Boolean validateVertex(Map conditions, ConditionQuery cq = conditions.get(sourceV.schemaLabel().id()); if (cq != null) { sourceV = (HugeVertex) this.graph.vertex(sourceV.id()); - if (!cq.test(sourceV)) { + if (!cq.test(sourceV.element())) { return false; } } @@ -552,7 +552,7 @@ private Boolean validateVertex(Map conditions, cq = conditions.get(targetV.schemaLabel().id()); if (cq != null) { targetV = (HugeVertex) this.graph.vertex(targetV.id()); - return cq.test(targetV); + return cq.test(targetV.element()); } return true; } @@ -565,7 +565,7 @@ private Boolean validateEdge(Map conditions, ConditionQuery cq = conditions.get(edge.schemaLabel().id()); if (cq != null) { - return cq.test(edge); + return cq.test(edge.element()); } return true; } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/JaccardSimilarTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/JaccardSimilarTraverser.java index 296e89ad40..37f639390d 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/JaccardSimilarTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/JaccardSimilarTraverser.java @@ -22,9 +22,9 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.traversal.algorithm.steps.EdgeStep; import org.apache.hugegraph.type.define.Directions; import org.apache.hugegraph.util.CollectionUtil; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/KneighborTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/KneighborTraverser.java index 2b284b26a0..a9563ee0b0 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/KneighborTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/KneighborTraverser.java @@ -21,8 +21,8 @@ import java.util.function.Consumer; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.traversal.algorithm.records.KneighborRecords; import org.apache.hugegraph.traversal.algorithm.steps.Steps; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/KoutTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/KoutTraverser.java index 8cf3c15b7e..909457be26 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/KoutTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/KoutTraverser.java @@ -22,11 +22,11 @@ import java.util.Set; import java.util.function.Consumer; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.traversal.algorithm.records.KoutRecords; import org.apache.hugegraph.traversal.algorithm.steps.Steps; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/MultiNodeShortestPathTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/MultiNodeShortestPathTraverser.java index 38f899c7f3..846317d438 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/MultiNodeShortestPathTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/MultiNodeShortestPathTraverser.java @@ -26,7 +26,7 @@ import org.apache.commons.lang3.tuple.Pair; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.traversal.algorithm.steps.EdgeStep; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/NeighborRankTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/NeighborRankTraverser.java index 914309a780..8a7149318e 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/NeighborRankTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/NeighborRankTraverser.java @@ -23,7 +23,7 @@ import java.util.Set; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.traversal.algorithm.steps.EdgeStep; import org.apache.hugegraph.type.define.Directions; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/OltpTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/OltpTraverser.java index 44f9cf8692..6e9bae5397 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/OltpTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/OltpTraverser.java @@ -30,8 +30,8 @@ import org.apache.commons.lang3.tuple.Pair; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.query.EdgesQueryIterator; import org.apache.hugegraph.config.CoreOptions; import org.apache.hugegraph.iterator.FilterIterator; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/PathTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/PathTraverser.java index 01a075bea7..34ddf54a10 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/PathTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/PathTraverser.java @@ -26,7 +26,7 @@ import java.util.Set; import java.util.function.BiConsumer; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.traversal.algorithm.HugeTraverser.EdgeRecord; import org.apache.hugegraph.traversal.algorithm.steps.EdgeStep; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/PathsTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/PathsTraverser.java index 5746533a50..763c6b48fa 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/PathsTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/PathsTraverser.java @@ -20,7 +20,7 @@ import java.util.Iterator; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.perf.PerfUtil.Watched; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.traversal.algorithm.records.PathsRecords; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/PersonalRankTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/PersonalRankTraverser.java index 2c3bafa238..cd957e42ab 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/PersonalRankTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/PersonalRankTraverser.java @@ -24,9 +24,9 @@ import java.util.function.BiFunction; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.type.define.Directions; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/PredictionTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/PredictionTraverser.java index 4b2cb69e57..c7aa916bc4 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/PredictionTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/PredictionTraverser.java @@ -20,7 +20,7 @@ import java.util.Set; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.traversal.algorithm.steps.EdgeStep; import org.apache.hugegraph.type.define.Directions; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/SameNeighborTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/SameNeighborTraverser.java index af16231015..45257afd22 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/SameNeighborTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/SameNeighborTraverser.java @@ -23,7 +23,7 @@ import java.util.Set; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.type.define.Directions; import org.apache.hugegraph.util.CollectionUtil; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/ShortestPathTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/ShortestPathTraverser.java index f69fd7da50..bb0ae2ba87 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/ShortestPathTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/ShortestPathTraverser.java @@ -23,7 +23,7 @@ import java.util.Set; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.perf.PerfUtil.Watched; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.traversal.algorithm.records.ShortestPathRecords; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/SingleSourceShortestPathTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/SingleSourceShortestPathTraverser.java index 0c67228abf..f751621287 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/SingleSourceShortestPathTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/SingleSourceShortestPathTraverser.java @@ -27,7 +27,7 @@ import java.util.Set; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.type.define.Directions; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/SubGraphTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/SubGraphTraverser.java index f76f3e3771..07f1892a04 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/SubGraphTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/SubGraphTraverser.java @@ -23,7 +23,7 @@ import java.util.Set; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.type.define.Directions; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/TemplatePathsTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/TemplatePathsTraverser.java index e2e99fb87c..2ad40885c4 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/TemplatePathsTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/TemplatePathsTraverser.java @@ -24,7 +24,7 @@ import java.util.Set; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.traversal.algorithm.steps.EdgeStep; import org.apache.hugegraph.traversal.algorithm.steps.RepeatEdgeStep; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/iterator/NestedIterator.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/iterator/NestedIterator.java index 09d206e30d..db0109740f 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/iterator/NestedIterator.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/iterator/NestedIterator.java @@ -24,7 +24,7 @@ import java.util.Map; import java.util.Set; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.iterator.WrappedIterator; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.traversal.algorithm.HugeTraverser; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/AbstractRecords.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/AbstractRecords.java index 74f3db5ffa..08764eca29 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/AbstractRecords.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/AbstractRecords.java @@ -17,8 +17,8 @@ package org.apache.hugegraph.traversal.algorithm.records; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.perf.PerfUtil.Watched; import org.apache.hugegraph.traversal.algorithm.records.record.Record; import org.apache.hugegraph.traversal.algorithm.records.record.RecordFactory; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/DoubleWayMultiPathsRecords.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/DoubleWayMultiPathsRecords.java index 33224dc92c..a958608411 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/DoubleWayMultiPathsRecords.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/DoubleWayMultiPathsRecords.java @@ -22,7 +22,7 @@ import java.util.Stack; import org.apache.commons.collections.CollectionUtils; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.perf.PerfUtil.Watched; import org.apache.hugegraph.traversal.algorithm.HugeTraverser.Path; import org.apache.hugegraph.traversal.algorithm.HugeTraverser.PathSet; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/KneighborRecords.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/KneighborRecords.java index 2a4e5abb66..89940ce762 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/KneighborRecords.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/KneighborRecords.java @@ -24,7 +24,7 @@ import java.util.Set; import java.util.Stack; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.traversal.algorithm.HugeTraverser.PathSet; import org.apache.hugegraph.traversal.algorithm.records.record.Record; import org.apache.hugegraph.traversal.algorithm.records.record.RecordType; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/KoutRecords.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/KoutRecords.java index bd637ce1d4..1db6e41c2c 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/KoutRecords.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/KoutRecords.java @@ -22,7 +22,7 @@ import java.util.List; import java.util.Stack; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.traversal.algorithm.HugeTraverser.PathSet; import org.apache.hugegraph.traversal.algorithm.records.record.Record; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/PathsRecords.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/PathsRecords.java index 96e04204b9..32bbb2ffe6 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/PathsRecords.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/PathsRecords.java @@ -19,7 +19,7 @@ import java.util.function.Function; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.perf.PerfUtil.Watched; import org.apache.hugegraph.traversal.algorithm.HugeTraverser.PathSet; import org.apache.hugegraph.traversal.algorithm.records.record.RecordType; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/Records.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/Records.java index d7d4e69316..889f3e60df 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/Records.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/Records.java @@ -19,7 +19,7 @@ import java.util.function.Function; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.traversal.algorithm.HugeTraverser.PathSet; public interface Records { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/ShortestPathRecords.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/ShortestPathRecords.java index 61c081cd2d..cb7633fa9a 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/ShortestPathRecords.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/ShortestPathRecords.java @@ -22,7 +22,7 @@ import java.util.Stack; import java.util.function.Function; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.traversal.algorithm.HugeTraverser.Path; import org.apache.hugegraph.traversal.algorithm.HugeTraverser.PathSet; import org.apache.hugegraph.traversal.algorithm.records.record.Int2IntRecord; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/SingleWayMultiPathsRecords.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/SingleWayMultiPathsRecords.java index 7c3a4fd1bb..377b477670 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/SingleWayMultiPathsRecords.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/records/SingleWayMultiPathsRecords.java @@ -23,8 +23,8 @@ import java.util.Stack; import java.util.function.Function; -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.exception.HugeException; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.perf.PerfUtil.Watched; import org.apache.hugegraph.traversal.algorithm.HugeTraverser.EdgeRecord; import org.apache.hugegraph.traversal.algorithm.HugeTraverser.Path; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/steps/EdgeStep.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/steps/EdgeStep.java index caff267b7d..859cbfe9b3 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/steps/EdgeStep.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/steps/EdgeStep.java @@ -26,8 +26,8 @@ import java.util.Map; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.schema.EdgeLabel; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.struct.schema.EdgeLabel; import org.apache.hugegraph.traversal.algorithm.HugeTraverser; import org.apache.hugegraph.traversal.optimize.TraversalUtil; import org.apache.hugegraph.type.define.Directions; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/steps/Steps.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/steps/Steps.java index cc4cdfacf2..7c19b4ac43 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/steps/Steps.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/steps/Steps.java @@ -25,9 +25,9 @@ import java.util.Map; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.traversal.algorithm.HugeTraverser; import org.apache.hugegraph.traversal.optimize.TraversalUtil; import org.apache.hugegraph.type.define.Directions; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/steps/WeightedEdgeStep.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/steps/WeightedEdgeStep.java index b288420ff2..3385d38720 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/steps/WeightedEdgeStep.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/steps/WeightedEdgeStep.java @@ -25,7 +25,7 @@ import java.util.Map; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.type.define.Directions; import org.apache.hugegraph.util.E; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/strategy/ConcurrentTraverseStrategy.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/strategy/ConcurrentTraverseStrategy.java index 235a3c2d98..6dd10c21f0 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/strategy/ConcurrentTraverseStrategy.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/strategy/ConcurrentTraverseStrategy.java @@ -24,7 +24,7 @@ import java.util.function.BiConsumer; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.traversal.algorithm.OltpTraverser; import org.apache.hugegraph.traversal.algorithm.steps.EdgeStep; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/strategy/SingleTraverseStrategy.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/strategy/SingleTraverseStrategy.java index 8516645cdd..680da6324d 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/strategy/SingleTraverseStrategy.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/strategy/SingleTraverseStrategy.java @@ -23,7 +23,7 @@ import java.util.function.BiConsumer; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.traversal.algorithm.HugeTraverser; import org.apache.hugegraph.traversal.algorithm.OltpTraverser; import org.apache.hugegraph.traversal.algorithm.steps.EdgeStep; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/strategy/TraverseStrategy.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/strategy/TraverseStrategy.java index 7440133038..819d9a8f6c 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/strategy/TraverseStrategy.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/strategy/TraverseStrategy.java @@ -23,7 +23,7 @@ import java.util.function.BiConsumer; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.traversal.algorithm.HugeTraverser; import org.apache.hugegraph.traversal.algorithm.steps.EdgeStep; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/ConditionP.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/ConditionP.java index 2ef93114f1..387bfab0fc 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/ConditionP.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/ConditionP.java @@ -17,7 +17,7 @@ package org.apache.hugegraph.traversal.optimize; -import org.apache.hugegraph.backend.query.Condition; +import org.apache.hugegraph.query.Condition; import org.apache.tinkerpop.gremlin.process.traversal.P; import org.apache.tinkerpop.gremlin.process.traversal.PBiPredicate; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeCountStepStrategy.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeCountStepStrategy.java index 2dbae3bacb..2765427861 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeCountStepStrategy.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeCountStepStrategy.java @@ -22,7 +22,7 @@ import java.util.List; import java.util.Set; -import org.apache.hugegraph.backend.query.Aggregate; +import org.apache.hugegraph.query.Aggregate; import org.apache.tinkerpop.gremlin.process.traversal.Step; import org.apache.tinkerpop.gremlin.process.traversal.Traversal; import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy.ProviderOptimizationStrategy; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeGraphStep.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeGraphStep.java index 4b7624de63..9e8b407fee 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeGraphStep.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeGraphStep.java @@ -24,8 +24,8 @@ import java.util.List; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.util.Log; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeScriptTraversal.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeScriptTraversal.java index 0ccb48a54a..4f9233211f 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeScriptTraversal.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeScriptTraversal.java @@ -25,7 +25,7 @@ import javax.script.ScriptEngine; import javax.script.ScriptException; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.tinkerpop.gremlin.jsr223.SingleGremlinScriptEngineManager; import org.apache.tinkerpop.gremlin.process.traversal.Traversal; import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeVertexStep.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeVertexStep.java index 33ee8570b5..1912c7b574 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeVertexStep.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeVertexStep.java @@ -17,6 +17,8 @@ package org.apache.hugegraph.traversal.optimize; +import org.apache.hugegraph.util.TinkerPopUtil; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -24,12 +26,12 @@ import java.util.List; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.backend.tx.GraphTransaction; -import org.apache.hugegraph.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; import org.apache.hugegraph.type.define.Directions; import org.apache.hugegraph.util.Log; import org.apache.tinkerpop.gremlin.process.traversal.Traverser; @@ -132,7 +134,7 @@ protected ConditionQuery constructEdgesQuery( boolean withVertexCond = this.withVertexCondition(); Id vertex = (Id) traverser.get().id(); - Directions direction = Directions.convert(this.getDirection()); + Directions direction = TinkerPopUtil.direction(this.getDirection()); EdgeLabel[] els = graph.mapElName2El(this.getEdgeLabels()); LOG.debug("HugeVertexStep.edges(): vertex={}, direction={}, " + diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeVertexStepByBatch.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeVertexStepByBatch.java index 62d6a2b921..a6fce4682d 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeVertexStepByBatch.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeVertexStepByBatch.java @@ -20,9 +20,9 @@ import java.util.Iterator; import java.util.List; -import org.apache.hugegraph.backend.query.BatchConditionQuery; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.BatchConditionQuery; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.iterator.BatchMapperIterator; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.HugeKeys; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/QueryHolder.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/QueryHolder.java index eaa03ecc3a..10934d749f 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/QueryHolder.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/QueryHolder.java @@ -19,8 +19,8 @@ import java.util.Iterator; -import org.apache.hugegraph.backend.query.Aggregate; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Aggregate; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.iterator.Metadatable; import org.apache.tinkerpop.gremlin.process.traversal.Order; import org.apache.tinkerpop.gremlin.process.traversal.step.HasContainerHolder; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/Text.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/Text.java index fc1d06cce4..508eac70fd 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/Text.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/Text.java @@ -17,8 +17,8 @@ package org.apache.hugegraph.traversal.optimize; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; public class Text { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/TraversalUtil.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/TraversalUtil.java index e426ee7819..d85015c97c 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/TraversalUtil.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/TraversalUtil.java @@ -29,24 +29,24 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.apache.hugegraph.HugeException; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.exception.HugeException; +import org.apache.hugegraph.exception.BackendException; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.page.PageInfo; import org.apache.hugegraph.backend.page.PageState; -import org.apache.hugegraph.backend.query.Aggregate; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Aggregate; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.exception.NotFoundException; import org.apache.hugegraph.exception.NotSupportException; import org.apache.hugegraph.iterator.FilterIterator; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.SchemaLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeElement; import org.apache.hugegraph.structure.HugeProperty; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/HugeType.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/HugeType.java deleted file mode 100644 index 122036ae38..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/HugeType.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.type; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.hugegraph.type.define.SerialEnum; - -public enum HugeType implements SerialEnum { - - UNKNOWN(0, "UNKNOWN"), - - /* Schema types */ - VERTEX_LABEL(1, "VL"), - EDGE_LABEL(2, "EL"), - PROPERTY_KEY(3, "PK"), - INDEX_LABEL(4, "IL"), - - META(40, "M"), - COUNTER(50, "C"), - - /* Data types */ - VERTEX(101, "V"), - // System meta - SYS_PROPERTY(102, "S"), - // Property - PROPERTY(103, "U"), - // Vertex aggregate property - AGGR_PROPERTY_V(104, "VP"), - // Edge aggregate property - AGGR_PROPERTY_E(105, "EP"), - // Olap property - OLAP(106, "AP"), - // Edge - EDGE(120, "E"), - // Edge's direction is OUT for the specified vertex - EDGE_OUT(130, "O"), - // Edge's direction is IN for the specified vertex - EDGE_IN(140, "I"), - - SECONDARY_INDEX(150, "SI"), - VERTEX_LABEL_INDEX(151, "VI"), - EDGE_LABEL_INDEX(152, "EI"), - RANGE_INT_INDEX(160, "II"), - RANGE_FLOAT_INDEX(161, "FI"), - RANGE_LONG_INDEX(162, "LI"), - RANGE_DOUBLE_INDEX(163, "DI"), - SEARCH_INDEX(170, "AI"), - SHARD_INDEX(175, "HI"), - UNIQUE_INDEX(178, "UI"), - - TASK(180, "T"), - SERVER(181, "SERVER"), - - VARIABLE(185, "VA"), - - KV_TYPE(200, "KV"), - KV_RAW(201, "KVR"), - - // System schema - SYS_SCHEMA(250, "SS"), - - MAX_TYPE(255, "~"); - - private byte type = 0; - private final String name; - - private static final Map ALL_NAME = new HashMap<>(); - - static { - SerialEnum.register(HugeType.class); - for (HugeType type : values()) { - ALL_NAME.put(type.name, type); - } - } - - HugeType(int type, String name) { - assert type < 256; - this.type = (byte) type; - this.name = name; - } - - @Override - public byte code() { - return this.type; - } - - public String string() { - return this.name; - } - - public String readableName() { - return this.name().replace('_', ' ').toLowerCase(); - } - - public boolean isSchema() { - return this == HugeType.VERTEX_LABEL || - this == HugeType.EDGE_LABEL || - this == HugeType.PROPERTY_KEY || - this == HugeType.INDEX_LABEL; - } - - public boolean isGraph() { - return this.isVertex() || this.isEdge(); - } - - public boolean isVertex() { - return this == HugeType.VERTEX || this == HugeType.TASK || this == HugeType.SERVER || - this == HugeType.VARIABLE; - } - - public boolean isEdge() { - return this == EDGE || this == EDGE_OUT || this == EDGE_IN; - } - - public boolean isEdgeLabel() { - return this == EDGE_LABEL; - } - - public boolean isIndex() { - return this == VERTEX_LABEL_INDEX || this == EDGE_LABEL_INDEX || - this == SECONDARY_INDEX || this == SEARCH_INDEX || - this == RANGE_INT_INDEX || this == RANGE_FLOAT_INDEX || - this == RANGE_LONG_INDEX || this == RANGE_DOUBLE_INDEX || - this == SHARD_INDEX || this == UNIQUE_INDEX; - } - - public boolean isLabelIndex() { - return this == VERTEX_LABEL_INDEX || this == EDGE_LABEL_INDEX; - } - - public boolean isStringIndex() { - return this == VERTEX_LABEL_INDEX || this == EDGE_LABEL_INDEX || - this == SECONDARY_INDEX || this == SEARCH_INDEX || - this == SHARD_INDEX || this == UNIQUE_INDEX; - } - - public boolean isNumericIndex() { - return this == RANGE_INT_INDEX || this == RANGE_FLOAT_INDEX || - this == RANGE_LONG_INDEX || this == RANGE_DOUBLE_INDEX || - this == SHARD_INDEX; - } - - public boolean isSecondaryIndex() { - return this == VERTEX_LABEL_INDEX || this == EDGE_LABEL_INDEX || - this == SECONDARY_INDEX; - } - - public boolean isSearchIndex() { - return this == SEARCH_INDEX; - } - - public boolean isRangeIndex() { - return this == RANGE_INT_INDEX || this == RANGE_FLOAT_INDEX || - this == RANGE_LONG_INDEX || this == RANGE_DOUBLE_INDEX; - } - - public boolean isRange4Index() { - return this == RANGE_INT_INDEX || this == RANGE_FLOAT_INDEX; - } - - public boolean isRange8Index() { - return this == RANGE_LONG_INDEX || this == RANGE_DOUBLE_INDEX; - } - - public boolean isShardIndex() { - return this == SHARD_INDEX; - } - - public boolean isUniqueIndex() { - return this == UNIQUE_INDEX; - } - - public boolean isVertexAggregateProperty() { - return this == AGGR_PROPERTY_V; - } - - public boolean isEdgeAggregateProperty() { - return this == AGGR_PROPERTY_E; - } - - public boolean isAggregateProperty() { - return this.isVertexAggregateProperty() || - this.isEdgeAggregateProperty(); - } - - public static HugeType fromString(String type) { - return ALL_NAME.get(type); - } - - public static HugeType fromCode(byte code) { - return SerialEnum.fromCode(HugeType.class, code); - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/Idfiable.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/Idfiable.java deleted file mode 100644 index 865ad50ad0..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/Idfiable.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.type; - -import org.apache.hugegraph.backend.id.Id; - -public interface Idfiable { - - Id id(); -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/Indexable.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/Indexable.java deleted file mode 100644 index ff3330a567..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/Indexable.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.type; - -import java.util.Set; - -import org.apache.hugegraph.backend.id.Id; - -public interface Indexable { - - Set indexLabels(); -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/Nameable.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/Nameable.java deleted file mode 100644 index cf8e71e6d7..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/Nameable.java +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2017 JanusGraph Authors -// -// 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.apache.hugegraph.type; - -/** - * Represents an entity that can be uniquely identified by a String name. - * - * @author Matthias Broecheler (me@matthiasb.com) - */ -public interface Nameable { - - /** - * Returns the unique name of this entity. - * - * @return Name of this entity. - */ - String name(); - -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/Propertiable.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/Propertiable.java deleted file mode 100644 index e26a356bf6..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/Propertiable.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.type; - -import java.util.Set; - -import org.apache.hugegraph.backend.id.Id; - -public interface Propertiable { - - Set properties(); -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/Typeable.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/Typeable.java deleted file mode 100644 index 95a1a11d49..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/Typeable.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.type; - -public interface Typeable { - - // Return schema/data type - HugeType type(); -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/Action.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/Action.java deleted file mode 100644 index 9561d52181..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/Action.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.type.define; - -public enum Action implements SerialEnum { - - INSERT(1, "insert"), - - APPEND(2, "append"), - - ELIMINATE(3, "eliminate"), - - DELETE(4, "delete"), - - UPDATE_IF_PRESENT(5, "update_if_present"), - - UPDATE_IF_ABSENT(6, "update_if_absent"); - - private final byte code; - private final String name; - - static { - SerialEnum.register(Action.class); - } - - Action(int code, String name) { - assert code < 256; - this.code = (byte) code; - this.name = name; - } - - @Override - public byte code() { - return this.code; - } - - public String string() { - return this.name; - } - - public static Action fromCode(byte code) { - switch (code) { - case 1: - return INSERT; - case 2: - return APPEND; - case 3: - return ELIMINATE; - case 4: - return DELETE; - case 5: - return UPDATE_IF_PRESENT; - case 6: - return UPDATE_IF_ABSENT; - default: - throw new AssertionError("Unsupported action code: " + code); - } - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/AggregateType.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/AggregateType.java deleted file mode 100644 index 31c0f6212d..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/AggregateType.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.type.define; - -public enum AggregateType implements SerialEnum { - - NONE(0, "none"), - MAX(1, "max"), - MIN(2, "min"), - SUM(3, "sum"), - OLD(4, "old"), - SET(5, "set"), - LIST(6, "list"); - - private final byte code; - private final String name; - - static { - SerialEnum.register(AggregateType.class); - } - - AggregateType(int code, String name) { - assert code < 256; - this.code = (byte) code; - this.name = name; - } - - @Override - public byte code() { - return this.code; - } - - public String string() { - return this.name; - } - - public boolean isNone() { - return this == NONE; - } - - public boolean isMax() { - return this == MAX; - } - - public boolean isMin() { - return this == MIN; - } - - public boolean isSum() { - return this == SUM; - } - - public boolean isNumber() { - return this.isMax() || this.isMin() || this.isSum(); - } - - public boolean isOld() { - return this == OLD; - } - - public boolean isSet() { - return this == SET; - } - - public boolean isList() { - return this == LIST; - } - - public boolean isUnion() { - return this == SET || this == LIST; - } - - public boolean isIndexable() { - return this == NONE || this == MAX || this == MIN || this == OLD; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/Cardinality.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/Cardinality.java deleted file mode 100644 index e9d6b59bf6..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/Cardinality.java +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2017 JanusGraph Authors -// -// 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.apache.hugegraph.type.define; - -import org.apache.tinkerpop.gremlin.structure.VertexProperty; - -/** - * The cardinality of the values associated with given key for a particular element. - * - * @author Matthias Broecheler (me@matthiasb.com) - */ -public enum Cardinality implements SerialEnum { - - /** - * Only a single value may be associated with the given key. - */ - SINGLE(1, "single"), - - /** - * Multiple values and duplicate values may be associated with the given - * key. - */ - LIST(2, "list"), - - /** - * Multiple but distinct values may be associated with the given key. - */ - SET(3, "set"); - - private final byte code; - private final String name; - - static { - SerialEnum.register(Cardinality.class); - } - - Cardinality(int code, String name) { - assert code < 256; - this.code = (byte) code; - this.name = name; - } - - @Override - public byte code() { - return this.code; - } - - public String string() { - return this.name; - } - - public boolean single() { - return this == SINGLE; - } - - public boolean multiple() { - return this == LIST || this == SET; - } - - public static Cardinality convert(VertexProperty.Cardinality cardinality) { - switch (cardinality) { - case single: - return SINGLE; - case list: - return LIST; - case set: - return SET; - default: - throw new AssertionError(String.format("Unrecognized cardinality: '%s'", - cardinality)); - } - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/CollectionType.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/CollectionType.java deleted file mode 100644 index e8a4cd3547..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/CollectionType.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.type.define; - -public enum CollectionType implements SerialEnum { - - // Java Collection Framework - JCF(1, "jcf"), - - // Eclipse Collection - EC(2, "ec"), - - // FastUtil - FU(3, "fu"); - - private final byte code; - private final String name; - - static { - SerialEnum.register(CollectionType.class); - } - - CollectionType(int code, String name) { - assert code < 256; - this.code = (byte) code; - this.name = name; - } - - @Override - public byte code() { - return this.code; - } - - public String string() { - return this.name; - } - - public static CollectionType fromCode(byte code) { - switch (code) { - case 1: - return JCF; - case 2: - return EC; - case 3: - return FU; - default: - throw new AssertionError( - "Unsupported collection code: " + code); - } - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/DataType.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/DataType.java deleted file mode 100644 index bc4448908d..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/DataType.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.type.define; - -import java.nio.ByteBuffer; -import java.time.OffsetDateTime; -import java.util.Date; -import java.util.List; -import java.util.UUID; - -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.backend.serializer.BytesBuffer; -import org.apache.hugegraph.util.Blob; -import org.apache.hugegraph.util.Bytes; -import org.apache.hugegraph.util.DateUtil; -import org.apache.hugegraph.util.JsonUtil; -import org.apache.hugegraph.util.StringEncoding; - -public enum DataType implements SerialEnum { - - UNKNOWN(0, "unknown", Object.class), - OBJECT(1, "object", Object.class), - BOOLEAN(2, "boolean", Boolean.class), - BYTE(3, "byte", Byte.class), - INT(4, "int", Integer.class), - LONG(5, "long", Long.class), - FLOAT(6, "float", Float.class), - DOUBLE(7, "double", Double.class), - TEXT(8, "text", String.class), - BLOB(9, "blob", Blob.class), - DATE(10, "date", Date.class), - UUID(11, "uuid", UUID.class); - - private final byte code; - private final String name; - private final Class clazz; - - static { - SerialEnum.register(DataType.class); - } - - DataType(int code, String name, Class clazz) { - assert code < 256; - this.code = (byte) code; - this.name = name; - this.clazz = clazz; - } - - @Override - public byte code() { - return this.code; - } - - public String string() { - return this.name; - } - - public Class clazz() { - return this.clazz; - } - - public boolean isText() { - return this == DataType.TEXT; - } - - public boolean isNumber() { - return this == BYTE || this == INT || this == LONG || - this == FLOAT || this == DOUBLE; - } - - public boolean isNumber4() { - // Store index value of Byte using 4 bytes - return this == BYTE || this == INT || this == FLOAT; - } - - public boolean isNumber8() { - return this == LONG || this == DOUBLE; - } - - public boolean isBlob() { - return this == DataType.BLOB; - } - - public boolean isDate() { - return this == DataType.DATE; - } - - public boolean isUUID() { - return this == DataType.UUID; - } - - public Number valueToNumber(V value) { - if (!(this.isNumber() && value instanceof Number) && - !JsonUtil.isInfinityOrNaN(value)) { - return null; - } - if (this.clazz.isInstance(value)) { - return (Number) value; - } - - Number number; - try { - switch (this) { - case BYTE: - number = Byte.valueOf(value.toString()); - break; - case INT: - number = Integer.valueOf(value.toString()); - break; - case LONG: - number = Long.valueOf(value.toString()); - break; - case FLOAT: - number = Float.valueOf(value.toString()); - break; - case DOUBLE: - number = Double.valueOf(value.toString()); - break; - default: - throw new AssertionError(String.format( - "Number type only contains Byte, Integer, " + - "Long, Float, Double, but got %s", this.clazz())); - } - } catch (NumberFormatException e) { - throw new IllegalArgumentException(String.format( - "Can't read '%s' as %s: %s", - value, this.name, e.getMessage())); - } - return number; - } - - public Date valueToDate(V value) { - if (!this.isDate()) { - return null; - } - if (value instanceof Date) { - return (Date) value; - } else if (value instanceof OffsetDateTime) { - return Date.from(((OffsetDateTime) value).toInstant()); - } else if (value instanceof Integer) { - return new Date(((Number) value).intValue()); - } else if (value instanceof Long) { - return new Date(((Number) value).longValue()); - } else if (value instanceof String) { - return DateUtil.parse((String) value); - } - return null; - } - - public UUID valueToUUID(V value) { - if (!this.isUUID()) { - return null; - } - if (value instanceof UUID) { - return (UUID) value; - } else if (value instanceof String) { - return StringEncoding.uuid((String) value); - } - return null; - } - - public Blob valueToBlob(V value) { - if (!this.isBlob()) { - return null; - } - if (value instanceof Blob) { - return (Blob) value; - } else if (value instanceof byte[]) { - return Blob.wrap((byte[]) value); - } else if (value instanceof ByteBuffer) { - return Blob.wrap(((ByteBuffer) value).array()); - } else if (value instanceof BytesBuffer) { - return Blob.wrap(((BytesBuffer) value).bytes()); - } else if (value instanceof String) { - // Only base64 string or hex string accepted - String str = ((String) value); - if (str.startsWith("0x")) { - return Blob.wrap(Bytes.fromHex(str.substring(2))); - } - return Blob.wrap(StringEncoding.decodeBase64(str)); - } else if (value instanceof List) { - List values = (List) value; - byte[] bytes = new byte[values.size()]; - for (int i = 0; i < bytes.length; i++) { - Object v = values.get(i); - if (v instanceof Byte || v instanceof Integer) { - bytes[i] = ((Number) v).byteValue(); - } else { - throw new IllegalArgumentException(String.format( - "expect byte or int value, but got '%s'", v)); - } - } - return Blob.wrap(bytes); - } - return null; - } - - public static DataType fromClass(Class clazz) { - for (DataType type : DataType.values()) { - if (type.clazz() == clazz) { - return type; - } - } - throw new HugeException("Unknown clazz '%s' for DataType", clazz); - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/Directions.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/Directions.java deleted file mode 100644 index 1309cd89df..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/Directions.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.type.define; - -import org.apache.hugegraph.type.HugeType; -import org.apache.tinkerpop.gremlin.structure.Direction; - -public enum Directions implements SerialEnum { - - // TODO: add NONE enum for non-directional edges - - BOTH(0, "both"), - - OUT(1, "out"), - - IN(2, "in"); - - private byte code = 0; - private String name = null; - - static { - SerialEnum.register(Directions.class); - } - - Directions(int code, String name) { - assert code < 256; - this.code = (byte) code; - this.name = name; - } - - @Override - public byte code() { - return this.code; - } - - public String string() { - return this.name; - } - - public HugeType type() { - switch (this) { - case OUT: - return HugeType.EDGE_OUT; - case IN: - return HugeType.EDGE_IN; - default: - throw new IllegalArgumentException(String.format( - "Can't convert direction '%s' to HugeType", this)); - } - } - - public Directions opposite() { - if (this.equals(OUT)) { - return IN; - } else { - return this.equals(IN) ? OUT : BOTH; - } - } - - public Direction direction() { - switch (this) { - case OUT: - return Direction.OUT; - case IN: - return Direction.IN; - case BOTH: - return Direction.BOTH; - default: - throw new AssertionError(String.format( - "Unrecognized direction: '%s'", this)); - } - } - - public static Directions convert(Direction direction) { - switch (direction) { - case OUT: - return OUT; - case IN: - return IN; - case BOTH: - return BOTH; - default: - throw new AssertionError(String.format( - "Unrecognized direction: '%s'", direction)); - } - } - - public static Directions convert(HugeType edgeType) { - switch (edgeType) { - case EDGE_OUT: - return OUT; - case EDGE_IN: - return IN; - default: - throw new IllegalArgumentException(String.format( - "Can't convert type '%s' to Direction", edgeType)); - } - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/EdgeLabelType.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/EdgeLabelType.java deleted file mode 100644 index 2857c6e3b3..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/EdgeLabelType.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package org.apache.hugegraph.type.define; - -public enum EdgeLabelType implements SerialEnum { - - NORMAL(1, "NORMAL"), - - PARENT(2, "PARENT"), - - SUB(3, "SUB"), - ; - - static { - SerialEnum.register(EdgeLabelType.class); - } - - private final byte code; - private final String name; - - EdgeLabelType(int code, String name) { - assert code < 256; - this.code = (byte) code; - this.name = name; - } - - @Override - public byte code() { - return this.code; - } - - public String string() { - return this.name; - } - - public boolean normal() { - return this == NORMAL; - } - - public boolean parent() { - return this == PARENT; - } - - public boolean sub() { - return this == SUB; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/HugeKeys.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/HugeKeys.java deleted file mode 100644 index 0e3536b011..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/HugeKeys.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.type.define; - -public enum HugeKeys { - - UNKNOWN(0, "undefined"), - - /* Column names of schema type (common) */ - ID(1, "id"), - NAME(2, "name"), - TIMESTAMP(3, "timestamp"), - SCHEMA_TYPE(4, "schema_type"), - VALUE(5, "value"), - VERSION(6, "version"), - - USER_DATA(10, "user_data"), - STATUS(11, "status"), - - /* Column names of schema type (VertexLabel) */ - ID_STRATEGY(50, "id_strategy"), - PROPERTIES(51, "properties"), - PRIMARY_KEYS(52, "primary_keys"), - INDEX_LABELS(53, "index_labels"), - NULLABLE_KEYS(54, "nullable_keys"), - ENABLE_LABEL_INDEX(55, "enable_label_index"), - - /* Column names of schema type (EdgeLabel) */ - LINKS(80, "links"), - FREQUENCY(81, "frequency"), - SOURCE_LABEL(82, "source_label"), - TARGET_LABEL(83, "target_label"), - SORT_KEYS(84, "sort_keys"), - TTL(85, "ttl"), - TTL_START_TIME(86, "ttl_start_time"), - EDGELABEL_TYPE(87, "edgelabel_type"), - PARENT_LABEL(89, "parent_label"), - - /* Column names of schema type (PropertyKey) */ - DATA_TYPE(120, "data_type"), - CARDINALITY(121, "cardinality"), - AGGREGATE_TYPE(122, "aggregate_type"), - WRITE_TYPE(123, "write_type"), - - /* Column names of schema type (IndexLabel) */ - BASE_TYPE(150, "base_type"), - BASE_VALUE(151, "base_value"), - INDEX_TYPE(152, "index_type"), - FIELDS(153, "fields"), - - /* Column names of index data */ - INDEX_NAME(180, "index_name"), - FIELD_VALUES(181, "field_values"), - INDEX_LABEL_ID(182, "index_label_id"), - ELEMENT_IDS(183, "element_ids"), - - /* Column names of data type (Vertex/Edge) */ - LABEL(200, "label"), - OWNER_VERTEX(201, "owner_vertex"), - OTHER_VERTEX(202, "other_vertex"), - PROPERTY_KEY(203, "property_key"), - PROPERTY_VALUE(204, "property_value"), - DIRECTION(205, "direction"), - SORT_VALUES(206, "sort_values"), - PRIMARY_VALUES(207, "primary_values"), - EXPIRED_TIME(208, "expired_time"), - SUB_LABEL(211, "sub_label"), - - PROPERTY_TYPE(249, "property_type"), - AGGREGATE_PROPERTIES(250, "aggregate_properties"); - - public static final long NORMAL_PROPERTY_ID = 0L; - - /* HugeKeys define */ - private byte code = 0; - private String name = null; - - HugeKeys(int code, String name) { - assert code < 256; - this.code = (byte) code; - this.name = name; - } - - public byte code() { - return this.code; - } - - public String string() { - return this.name; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/IdStrategy.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/IdStrategy.java deleted file mode 100644 index da9f51313c..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/IdStrategy.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.type.define; - -public enum IdStrategy implements SerialEnum { - - DEFAULT(0, "default"), - - AUTOMATIC(1, "automatic"), - - PRIMARY_KEY(2, "primary_key"), - - CUSTOMIZE_STRING(3, "customize_string"), - - CUSTOMIZE_NUMBER(4, "customize_number"), - - CUSTOMIZE_UUID(5, "customize_uuid"); - - private byte code = 0; - private String name = null; - - static { - SerialEnum.register(IdStrategy.class); - } - - IdStrategy(int code, String name) { - assert code < 256; - this.code = (byte) code; - this.name = name; - } - - @Override - public byte code() { - return this.code; - } - - public String string() { - return this.name; - } - - public boolean isAutomatic() { - return this == AUTOMATIC; - } - - public boolean isPrimaryKey() { - return this == PRIMARY_KEY; - } - - public boolean isCustomized() { - return this == CUSTOMIZE_STRING || - this == CUSTOMIZE_NUMBER || - this == CUSTOMIZE_UUID; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/IndexType.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/IndexType.java deleted file mode 100644 index 019ac98df9..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/IndexType.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.type.define; - -import org.apache.hugegraph.type.HugeType; - -public enum IndexType implements SerialEnum { - - // For secondary query - SECONDARY(1, "secondary"), - - // For range query - RANGE(2, "range"), - RANGE_INT(21, "range_int"), - RANGE_FLOAT(22, "range_float"), - RANGE_LONG(23, "range_long"), - RANGE_DOUBLE(24, "range_double"), - - // For full-text query (not supported now) - SEARCH(3, "search"), - - // For prefix + range query - SHARD(4, "shard"), - - // For unique index - UNIQUE(5, "unique"); - - private byte code = 0; - private String name = null; - - static { - SerialEnum.register(IndexType.class); - } - - IndexType(int code, String name) { - assert code < 256; - this.code = (byte) code; - this.name = name; - } - - @Override - public byte code() { - return this.code; - } - - public String string() { - return this.name; - } - - public HugeType type() { - switch (this) { - case SECONDARY: - return HugeType.SECONDARY_INDEX; - case RANGE_INT: - return HugeType.RANGE_INT_INDEX; - case RANGE_FLOAT: - return HugeType.RANGE_FLOAT_INDEX; - case RANGE_LONG: - return HugeType.RANGE_LONG_INDEX; - case RANGE_DOUBLE: - return HugeType.RANGE_DOUBLE_INDEX; - case SEARCH: - return HugeType.SEARCH_INDEX; - case SHARD: - return HugeType.SHARD_INDEX; - case UNIQUE: - return HugeType.UNIQUE_INDEX; - default: - throw new AssertionError(String.format( - "Unknown index type '%s'", this)); - } - } - - public boolean isString() { - return this == SECONDARY || this == SEARCH || - this == SHARD || this == UNIQUE; - } - - public boolean isNumeric() { - return this == RANGE_INT || this == RANGE_FLOAT || - this == RANGE_LONG || this == RANGE_DOUBLE || - this == SHARD; - } - - public boolean isSecondary() { - return this == SECONDARY; - } - - public boolean isRange() { - return this == RANGE_INT || this == RANGE_FLOAT || - this == RANGE_LONG || this == RANGE_DOUBLE; - } - - public boolean isSearch() { - return this == SEARCH; - } - - public boolean isShard() { - return this == SHARD; - } - - public boolean isUnique() { - return this == UNIQUE; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/SchemaStatus.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/SchemaStatus.java deleted file mode 100644 index 4a80a6a68c..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/SchemaStatus.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.type.define; - -public enum SchemaStatus implements SerialEnum { - - CREATED(1, "created"), - - CREATING(2, "creating"), - - REBUILDING(3, "rebuilding"), - - DELETING(4, "deleting"), - - UNDELETED(5, "undeleted"), - - INVALID(6, "invalid"); - - private byte code = 0; - private String name = null; - - static { - SerialEnum.register(SchemaStatus.class); - } - - SchemaStatus(int code, String name) { - assert code < 256; - this.code = (byte) code; - this.name = name; - } - - public boolean ok() { - return this == CREATED; - } - - public boolean deleting() { - return this == DELETING || this == UNDELETED; - } - - @Override - public byte code() { - return this.code; - } - - public String string() { - return this.name; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/SerialEnum.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/SerialEnum.java deleted file mode 100644 index 471c0c2d70..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/SerialEnum.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.type.define; - -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.type.HugeType; -import org.apache.hugegraph.util.CollectionUtil; -import org.apache.hugegraph.util.E; - -import com.google.common.collect.HashBasedTable; -import com.google.common.collect.Table; - -public interface SerialEnum { - - byte code(); - - Table, Byte, SerialEnum> TABLE = HashBasedTable.create(); - - static void register(Class clazz) { - Object enums; - try { - enums = clazz.getMethod("values").invoke(null); - } catch (Exception e) { - throw new BackendException(e); - } - for (SerialEnum e : CollectionUtil.toList(enums)) { - TABLE.put(clazz, e.code(), e); - } - } - - static T fromCode(Class clazz, byte code) { - @SuppressWarnings("unchecked") - T value = (T) TABLE.get(clazz, code); - if (value == null) { - E.checkArgument(false, "Can't construct %s from code %s", - clazz.getSimpleName(), code); - } - return value; - } - - static void registerInternalEnums() { - SerialEnum.register(Action.class); - SerialEnum.register(AggregateType.class); - SerialEnum.register(Cardinality.class); - SerialEnum.register(DataType.class); - SerialEnum.register(Directions.class); - SerialEnum.register(Frequency.class); - SerialEnum.register(HugeType.class); - SerialEnum.register(IdStrategy.class); - SerialEnum.register(IndexType.class); - SerialEnum.register(SchemaStatus.class); - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/WriteType.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/WriteType.java deleted file mode 100644 index ea1018eabd..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/WriteType.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.type.define; - -public enum WriteType implements SerialEnum { - - // OLTP property key - OLTP(1, "oltp"), - - // OLAP property key without index - OLAP_COMMON(2, "olap_common"), - - // OLAP property key with secondary index - OLAP_SECONDARY(3, "olap_secondary"), - - // OLAP property key with range index - OLAP_RANGE(4, "olap_range"); - - private byte code = 0; - private String name = null; - - static { - SerialEnum.register(WriteType.class); - } - - WriteType(int code, String name) { - assert code < 256; - this.code = (byte) code; - this.name = name; - } - - @Override - public byte code() { - return this.code; - } - - public String string() { - return this.name; - } - - public boolean oltp() { - return this == OLTP; - } - - public boolean olap() { - return this == OLAP_COMMON || - this == OLAP_RANGE || - this == OLAP_SECONDARY; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/Blob.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/Blob.java deleted file mode 100644 index 5b5d8ec6ad..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/Blob.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.util; - -import java.util.Arrays; - -public class Blob implements Comparable { - - public static final Blob EMPTY = new Blob(new byte[0]); - - private final byte[] bytes; - - private Blob(byte[] bytes) { - E.checkNotNull(bytes, "bytes"); - this.bytes = bytes; - } - - public byte[] bytes() { - return this.bytes; - } - - public static Blob wrap(byte[] bytes) { - return new Blob(bytes); - } - - @Override - public int hashCode() { - return Arrays.hashCode(this.bytes); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof Blob)) { - return false; - } - Blob other = (Blob) obj; - return Arrays.equals(this.bytes, other.bytes); - } - - @Override - public String toString() { - String hex = Bytes.toHex(this.bytes); - StringBuilder sb = new StringBuilder(6 + hex.length()); - sb.append("Blob{").append(hex).append("}"); - return sb.toString(); - } - - @Override - public int compareTo(Blob other) { - E.checkNotNull(other, "other blob"); - return Bytes.compare(this.bytes, other.bytes); - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/ConfigUtil.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/ConfigUtil.java index 54b5392376..a67f2c5680 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/ConfigUtil.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/ConfigUtil.java @@ -40,7 +40,7 @@ import org.apache.commons.configuration2.tree.NodeModel; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeFactory; import org.apache.hugegraph.config.HugeConfig; import org.slf4j.Logger; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/Consumers.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/Consumers.java index f4a7671f35..ea6e77a1ec 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/Consumers.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/Consumers.java @@ -33,7 +33,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.config.CoreOptions; import org.apache.hugegraph.task.TaskManager.ContextCallable; import org.slf4j.Logger; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/CopyUtil.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/CopyUtil.java index 7a043b7cd5..cced524bbd 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/CopyUtil.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/CopyUtil.java @@ -21,7 +21,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; public final class CopyUtil { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/GZipUtil.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/GZipUtil.java index 962d4a33a1..ef09cc2431 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/GZipUtil.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/GZipUtil.java @@ -22,8 +22,8 @@ import java.util.zip.Inflater; import org.apache.commons.codec.digest.DigestUtils; -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.exception.BackendException; +import org.apache.hugegraph.serializer.BytesBuffer; public final class GZipUtil { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/JsonUtil.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/JsonUtil.java index b2fce8da57..5ed4968fe6 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/JsonUtil.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/JsonUtil.java @@ -20,7 +20,7 @@ import java.io.IOException; import java.util.Date; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.io.HugeGraphSONModule; import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator; import org.apache.tinkerpop.shaded.jackson.core.JsonProcessingException; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/KryoUtil.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/KryoUtil.java deleted file mode 100644 index ce789c6d8d..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/KryoUtil.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.util; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.UUID; - -import org.apache.hugegraph.backend.BackendException; -import org.apache.tinkerpop.shaded.kryo.Kryo; -import org.apache.tinkerpop.shaded.kryo.Serializer; -import org.apache.tinkerpop.shaded.kryo.io.Input; -import org.apache.tinkerpop.shaded.kryo.io.Output; - -public final class KryoUtil { - - private static final ThreadLocal KRYOS = new ThreadLocal<>(); - - public static Kryo kryo() { - Kryo kryo = KRYOS.get(); - if (kryo != null) { - return kryo; - } - - kryo = new Kryo(); - registerSerializers(kryo); - KRYOS.set(kryo); - return kryo; - } - - public static byte[] toKryo(Object value) { - try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); - Output output = new Output(bos, 256)) { - kryo().writeObject(output, value); - output.flush(); - return bos.toByteArray(); - } catch (IOException e) { - throw new BackendException("Failed to serialize: %s", e, value); - } - } - - public static T fromKryo(byte[] value, Class clazz) { - E.checkState(value != null, - "Kryo value can't be null for '%s'", - clazz.getSimpleName()); - return kryo().readObject(new Input(value), clazz); - } - - public static byte[] toKryoWithType(Object value) { - try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); - Output output = new Output(bos, 256)) { - kryo().writeClassAndObject(output, value); - output.flush(); - return bos.toByteArray(); - } catch (IOException e) { - throw new BackendException("Failed to serialize: %s", e, value); - } - } - - @SuppressWarnings("unchecked") - public static T fromKryoWithType(byte[] value) { - E.checkState(value != null, "Kryo value can't be null for object"); - return (T) kryo().readClassAndObject(new Input(value)); - } - - private static void registerSerializers(Kryo kryo) { - kryo.addDefaultSerializer(UUID.class, new Serializer() { - - @Override - public UUID read(Kryo kryo, Input input, Class c) { - return new UUID(input.readLong(), input.readLong()); - } - - @Override - public void write(Kryo kryo, Output output, UUID uuid) { - output.writeLong(uuid.getMostSignificantBits()); - output.writeLong(uuid.getLeastSignificantBits()); - } - }); - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/LZ4Util.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/LZ4Util.java deleted file mode 100644 index 44de9c60f6..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/LZ4Util.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.util; - -import java.io.ByteArrayInputStream; -import java.io.IOException; - -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.serializer.BytesBuffer; - -import net.jpountz.lz4.LZ4BlockInputStream; -import net.jpountz.lz4.LZ4BlockOutputStream; -import net.jpountz.lz4.LZ4Compressor; -import net.jpountz.lz4.LZ4Factory; -import net.jpountz.lz4.LZ4FastDecompressor; - -public class LZ4Util { - - protected static final float DEFAULT_BUFFER_RATIO = 1.5f; - - public static BytesBuffer compress(byte[] bytes, int blockSize) { - return compress(bytes, blockSize, DEFAULT_BUFFER_RATIO); - } - - public static BytesBuffer compress(byte[] bytes, int blockSize, float bufferRatio) { - float ratio = bufferRatio <= 0.0F ? DEFAULT_BUFFER_RATIO : bufferRatio; - LZ4Factory factory = LZ4Factory.fastestInstance(); - LZ4Compressor compressor = factory.fastCompressor(); - int initBufferSize = Math.round(bytes.length / ratio); - BytesBuffer buf = new BytesBuffer(initBufferSize); - LZ4BlockOutputStream lz4Output = new LZ4BlockOutputStream(buf, blockSize, compressor); - try { - lz4Output.write(bytes); - lz4Output.close(); - } catch (IOException e) { - throw new BackendException("Failed to compress", e); - } - // If we need to perform reading outside the method, remember to call forReadWritten() - return buf; - } - - public static BytesBuffer decompress(byte[] bytes, int blockSize) { - return decompress(bytes, blockSize, DEFAULT_BUFFER_RATIO); - } - - public static BytesBuffer decompress(byte[] bytes, int blockSize, float bufferRatio) { - float ratio = bufferRatio <= 0.0F ? DEFAULT_BUFFER_RATIO : bufferRatio; - LZ4Factory factory = LZ4Factory.fastestInstance(); - LZ4FastDecompressor decompressor = factory.fastDecompressor(); - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - int initBufferSize = Math.min(Math.round(bytes.length * ratio), - BytesBuffer.maxBufferCapacity()); - BytesBuffer buf = new BytesBuffer(initBufferSize); - LZ4BlockInputStream lzInput = new LZ4BlockInputStream(bais, decompressor); - int count; - byte[] buffer = new byte[blockSize]; - try { - while ((count = lzInput.read(buffer)) != -1) { - buf.write(buffer, 0, count); - } - lzInput.close(); - } catch (IOException e) { - throw new BackendException("Failed to decompress", e); - } - // If we need to perform reading outside the method, remember to call forReadWritten() - return buf; - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/LockUtil.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/LockUtil.java index 0fb10989fc..c9d317634e 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/LockUtil.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/LockUtil.java @@ -29,8 +29,8 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.exception.HugeException; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.concurrent.KeyLock; import org.apache.hugegraph.concurrent.LockManager; import org.apache.hugegraph.concurrent.RowLock; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/Reflection.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/Reflection.java index 14e7b77120..f66d051d5d 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/Reflection.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/Reflection.java @@ -23,7 +23,7 @@ import java.util.LinkedHashSet; import java.util.Set; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.exception.NotSupportException; import org.slf4j.Logger; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/StringEncoding.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/StringEncoding.java deleted file mode 100644 index 7b10738580..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/StringEncoding.java +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright 2017 JanusGraph Authors -// -// 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.apache.hugegraph.util; - -import java.nio.charset.StandardCharsets; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Base64; -import java.util.UUID; - -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.backend.serializer.BytesBuffer; -import org.mindrot.jbcrypt.BCrypt; - -import com.google.common.base.CharMatcher; - -/** - * @author Matthias Broecheler (me@matthiasb.com) - * @author HugeGraph Authors - */ -public final class StringEncoding { - - private static final MessageDigest DIGEST; - private static final byte[] BYTES_EMPTY = new byte[0]; - private static final String STRING_EMPTY = ""; - private static final int BLOCK_SIZE = 4096; - private static final int BCRYPT_WORK_FACTOR = 10; - - static { - final String ALG = "SHA-256"; - try { - DIGEST = MessageDigest.getInstance(ALG); - } catch (NoSuchAlgorithmException e) { - throw new HugeException("Failed to load algorithm %s", e, ALG); - } - } - - private static final Base64.Encoder BASE64_ENCODER = Base64.getEncoder(); - private static final Base64.Decoder BASE64_DECODER = Base64.getDecoder(); - - /** Similar to {@link StringSerializer} */ - public static int writeAsciiString(byte[] array, int offset, String value) { - E.checkArgument(CharMatcher.ascii().matchesAllOf(value), - "'%s' must be ASCII string", value); - int len = value.length(); - if (len == 0) { - array[offset++] = (byte) 0x80; - return offset; - } - - int i = 0; - do { - int c = value.charAt(i); - assert c <= 127; - byte b = (byte) c; - if (++i == len) { - // End marker - b |= 0x80; - } - array[offset++] = b; - } while (i < len); - - return offset; - } - - public static String readAsciiString(byte[] array, int offset) { - StringBuilder sb = new StringBuilder(); - int c; - do { - c = 0xFF & array[offset++]; - if (c != 0x80) { - sb.append((char) (c & 0x7F)); - } - } while ((c & 0x80) <= 0); - return sb.toString(); - } - - public static int getAsciiByteLength(String value) { - E.checkArgument(CharMatcher.ascii().matchesAllOf(value), - "'%s' must be ASCII string", value); - return value.isEmpty() ? 1 : value.length(); - } - - public static byte[] encode(String value) { - return value.getBytes(StandardCharsets.UTF_8); - } - - public static String decode(byte[] bytes) { - if (bytes.length == 0) { - return STRING_EMPTY; - } - return new String(bytes, StandardCharsets.UTF_8); - } - - public static String decode(byte[] bytes, int offset, int length) { - if (length == 0) { - return STRING_EMPTY; - } - return new String(bytes, offset, length, StandardCharsets.UTF_8); - } - - public static String encodeBase64(byte[] bytes) { - return BASE64_ENCODER.encodeToString(bytes); - } - - public static byte[] decodeBase64(String value) { - if (value.isEmpty()) { - return BYTES_EMPTY; - } - return BASE64_DECODER.decode(value); - } - - public static byte[] compress(String value) { - return compress(value, LZ4Util.DEFAULT_BUFFER_RATIO); - } - - public static byte[] compress(String value, float bufferRatio) { - BytesBuffer buf = LZ4Util.compress(encode(value), BLOCK_SIZE, bufferRatio); - return buf.bytes(); - } - - public static String decompress(byte[] value) { - return decompress(value, LZ4Util.DEFAULT_BUFFER_RATIO); - } - - public static String decompress(byte[] value, float bufferRatio) { - BytesBuffer buf = LZ4Util.decompress(value, BLOCK_SIZE, bufferRatio); - return decode(buf.array(), 0, buf.position()); - } - - public static String hashPassword(String password) { - // OWASP suggests 10 as a minimum and 12–14 for production; - // workFactor 12 is not used by default due to its 200+ ms cost. - return BCrypt.hashpw(password, BCrypt.gensalt(BCRYPT_WORK_FACTOR)); - } - - public static boolean checkPassword(String candidatePassword, String dbPassword) { - return BCrypt.checkpw(candidatePassword, dbPassword); - } - - public static String sha256(String string) { - byte[] stringBytes = encode(string); - DIGEST.reset(); - return StringEncoding.encodeBase64(DIGEST.digest(stringBytes)); - } - - public static String format(byte[] bytes) { - return String.format("%s[0x%s]", decode(bytes), Bytes.toHex(bytes)); - } - - public static UUID uuid(String value) { - E.checkArgument(value != null, "The UUID can't be null"); - try { - if (value.contains("-") && value.length() == 36) { - return UUID.fromString(value); - } - // UUID represented by hex string - E.checkArgument(value.length() == 32, "Invalid UUID string: %s", value); - String high = value.substring(0, 16); - String low = value.substring(16); - return new UUID(Long.parseUnsignedLong(high, 16), - Long.parseUnsignedLong(low, 16)); - } catch (NumberFormatException ignored) { - throw new IllegalArgumentException("Invalid UUID string: " + value); - } - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/TinkerPopUtil.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/TinkerPopUtil.java new file mode 100644 index 0000000000..574201a243 --- /dev/null +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/TinkerPopUtil.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.util; + +import org.apache.hugegraph.type.define.Cardinality; +import org.apache.hugegraph.type.define.Directions; +import org.apache.tinkerpop.gremlin.structure.Direction; +import org.apache.tinkerpop.gremlin.structure.VertexProperty; + +public final class TinkerPopUtil { + + private TinkerPopUtil() { + } + + public static Directions direction(Direction direction) { + switch (direction) { + case OUT: + return Directions.OUT; + case IN: + return Directions.IN; + case BOTH: + return Directions.BOTH; + default: + throw new AssertionError("Unknown direction: " + direction); + } + } + + public static Direction direction(Directions direction) { + switch (direction) { + case OUT: + return Direction.OUT; + case IN: + return Direction.IN; + case BOTH: + return Direction.BOTH; + default: + throw new AssertionError("Unknown direction: " + direction); + } + } + + public static Cardinality cardinality(VertexProperty.Cardinality cardinality) { + switch (cardinality) { + case single: + return Cardinality.SINGLE; + case list: + return Cardinality.LIST; + case set: + return Cardinality.SET; + default: + throw new AssertionError("Unknown cardinality: " + cardinality); + } + } +} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/collection/CollectionFactory.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/collection/CollectionFactory.java deleted file mode 100644 index eba9d4fa6e..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/collection/CollectionFactory.java +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.util.collection; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.type.define.CollectionType; -import org.apache.hugegraph.util.E; -import org.eclipse.collections.api.map.primitive.IntObjectMap; -import org.eclipse.collections.api.map.primitive.MutableIntObjectMap; -import org.eclipse.collections.impl.list.mutable.FastList; -import org.eclipse.collections.impl.map.mutable.UnifiedMap; -import org.eclipse.collections.impl.map.mutable.primitive.IntObjectHashMap; -import org.eclipse.collections.impl.set.mutable.UnifiedSet; - -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.objects.ObjectArrayList; -import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; - -public class CollectionFactory { - - private final CollectionType type; - - public CollectionFactory() { - this.type = CollectionType.EC; - } - - public CollectionFactory(CollectionType type) { - this.type = type; - } - - public List newList() { - return newList(this.type); - } - - public List newList(int initialCapacity) { - return newList(this.type, initialCapacity); - } - - public List newList(Collection collection) { - return newList(this.type, collection); - } - - public static List newList(CollectionType type) { - switch (type) { - case EC: - return new FastList<>(); - case JCF: - return new ArrayList<>(); - case FU: - return new ObjectArrayList<>(); - default: - throw new AssertionError( - "Unsupported collection type: " + type); - } - } - - public static List newList(CollectionType type, - int initialCapacity) { - switch (type) { - case EC: - return new FastList<>(initialCapacity); - case JCF: - return new ArrayList<>(initialCapacity); - case FU: - return new ObjectArrayList<>(initialCapacity); - default: - throw new AssertionError( - "Unsupported collection type: " + type); - } - } - - public static List newList(CollectionType type, - Collection collection) { - switch (type) { - case EC: - return new FastList<>(collection); - case JCF: - return new ArrayList<>(collection); - case FU: - return new ObjectArrayList<>(collection); - default: - throw new AssertionError( - "Unsupported collection type: " + type); - } - } - - public Set newSet() { - return newSet(this.type); - } - - public Set newSet(int initialCapacity) { - return newSet(this.type, initialCapacity); - } - - public Set newSet(Collection collection) { - return newSet(this.type, collection); - } - - public static Set newSet(CollectionType type) { - switch (type) { - case EC: - return new UnifiedSet<>(); - case JCF: - return new HashSet<>(); - case FU: - return new ObjectOpenHashSet<>(); - default: - throw new AssertionError( - "Unsupported collection type: " + type); - } - } - - public static Set newSet(CollectionType type, - int initialCapacity) { - switch (type) { - case EC: - return new UnifiedSet<>(initialCapacity); - case JCF: - return new HashSet<>(initialCapacity); - case FU: - return new ObjectOpenHashSet<>(initialCapacity); - default: - throw new AssertionError( - "Unsupported collection type: " + type); - } - } - - public static Set newSet(CollectionType type, - Collection collection) { - switch (type) { - case EC: - return new UnifiedSet<>(collection); - case JCF: - return new HashSet<>(collection); - case FU: - return new ObjectOpenHashSet<>(collection); - default: - throw new AssertionError( - "Unsupported collection type: " + type); - } - } - - public Map newMap() { - return newMap(this.type); - } - - public Map newMap(int initialCapacity) { - return newMap(this.type, initialCapacity); - } - - public Map newMap(Map map) { - return newMap(this.type, map); - } - - public static Map newMap(CollectionType type) { - /* - * EC is faster 10%-20% than JCF, and it's more stable & less - * memory cost(size is bigger, EC is better). - */ - switch (type) { - case EC: - return new UnifiedMap<>(); - case JCF: - return new HashMap<>(); - case FU: - return new Object2ObjectOpenHashMap<>(); - default: - throw new AssertionError( - "Unsupported collection type: " + type); - } - } - - public static Map newMap(CollectionType type, - int initialCapacity) { - switch (type) { - case EC: - return new UnifiedMap<>(initialCapacity); - case JCF: - return new HashMap<>(initialCapacity); - case FU: - return new Object2ObjectOpenHashMap<>(initialCapacity); - default: - throw new AssertionError( - "Unsupported collection type: " + type); - } - } - - public static Map newMap(CollectionType type, - Map map) { - switch (type) { - case EC: - return new UnifiedMap<>(map); - case JCF: - return new HashMap<>(map); - case FU: - return new Object2ObjectOpenHashMap<>(map); - default: - throw new AssertionError( - "Unsupported collection type: " + type); - } - } - - public static MutableIntObjectMap newIntObjectMap() { - return new IntObjectHashMap<>(); - } - - public static MutableIntObjectMap newIntObjectMap( - int initialCapacity) { - return new IntObjectHashMap<>(initialCapacity); - } - - public static MutableIntObjectMap newIntObjectMap( - IntObjectMap map) { - return new IntObjectHashMap<>(map); - } - - @SuppressWarnings("unchecked") - public static MutableIntObjectMap newIntObjectMap( - Object... objects) { - IntObjectHashMap map = IntObjectHashMap.newMap(); - E.checkArgument(objects.length % 2 == 0, - "Must provide even arguments for " + - "CollectionFactory.newIntObjectMap"); - for (int i = 0; i < objects.length; i += 2) { - int key = objects[i] instanceof Id ? - (int) ((Id) objects[i]).asLong() : (int) objects[i]; - map.put(key, (V) objects[i + 1]); - } - return map; - } - - public IdSet newIdSet() { - return newIdSet(this.type); - } - - public static IdSet newIdSet(CollectionType type) { - return new IdSet(type); - } - - public static IntSet newIntSet() { - /* - * Resume to the old version like this: - * return concurrent ? new IntHashSet().asSynchronized() : - * new IntHashSet(); - */ - return new IntSet.IntSetBySegments(Integer.MAX_VALUE); - } - - public static IntMap newIntMap() { - /* - * Resume to the old version like this: - * return concurrent ? new IntIntHashMap().asSynchronized() : - * new IntIntHashMap(); - */ - return new IntMap.IntMapBySegments(Integer.MAX_VALUE); - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/collection/IdSet.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/collection/IdSet.java deleted file mode 100644 index 57f3b12021..0000000000 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/collection/IdSet.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.util.collection; - -import java.util.AbstractSet; -import java.util.Iterator; -import java.util.Set; - -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.iterator.ExtendableIterator; -import org.apache.hugegraph.type.define.CollectionType; -import org.eclipse.collections.api.iterator.MutableLongIterator; -import org.eclipse.collections.impl.set.mutable.primitive.LongHashSet; - -public class IdSet extends AbstractSet { - - private final LongHashSet numberIds; - private final Set nonNumberIds; - - public IdSet(CollectionType type) { - this.numberIds = new LongHashSet(); - this.nonNumberIds = CollectionFactory.newSet(type); - } - - @Override - public int size() { - return this.numberIds.size() + this.nonNumberIds.size(); - } - - @Override - public boolean isEmpty() { - return this.numberIds.isEmpty() && this.nonNumberIds.isEmpty(); - } - - @Override - public boolean contains(Object object) { - if (!(object instanceof Id)) { - return false; - } - Id id = (Id) object; - if (id.type() == Id.IdType.LONG) { - return this.numberIds.contains(id.asLong()); - } else { - return this.nonNumberIds.contains(id); - } - } - - @Override - public Iterator iterator() { - return new ExtendableIterator<>( - this.nonNumberIds.iterator(), - new EcLongIdIterator(this.numberIds.longIterator())); - } - - @Override - public boolean add(Id id) { - if (id.type() == Id.IdType.LONG) { - return this.numberIds.add(id.asLong()); - } else { - return this.nonNumberIds.add(id); - } - } - - public boolean remove(Id id) { - if (id.type() == Id.IdType.LONG) { - return this.numberIds.remove(id.asLong()); - } else { - return this.nonNumberIds.remove(id); - } - } - - @Override - public void clear() { - this.numberIds.clear(); - this.nonNumberIds.clear(); - } - - private static class EcLongIdIterator implements Iterator { - - private final MutableLongIterator iterator; - - public EcLongIdIterator(MutableLongIterator iter) { - this.iterator = iter; - } - - @Override - public boolean hasNext() { - return this.iterator.hasNext(); - } - - @Override - public Id next() { - return IdGenerator.of(this.iterator.next()); - } - - @Override - public void remove() { - this.iterator.remove(); - } - } -} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/collection/ObjectIntMappingFactory.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/collection/ObjectIntMappingFactory.java index 832ed680bc..2872b9f998 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/collection/ObjectIntMappingFactory.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/collection/ObjectIntMappingFactory.java @@ -17,7 +17,7 @@ package org.apache.hugegraph.util.collection; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.perf.PerfUtil.Watched; import org.eclipse.collections.impl.map.mutable.primitive.IntObjectHashMap; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/variables/HugeVariables.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/variables/HugeVariables.java index b7f2a6c58f..de1f15fa3d 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/variables/HugeVariables.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/variables/HugeVariables.java @@ -33,17 +33,17 @@ import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.SplicingIdGenerator; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.SplicingIdGenerator; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.backend.tx.GraphTransaction; import org.apache.hugegraph.iterator.FilterIterator; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Cardinality; diff --git a/hugegraph-server/hugegraph-dist/src/assembly/static/conf/gremlin-server.yaml b/hugegraph-server/hugegraph-dist/src/assembly/static/conf/gremlin-server.yaml index 0b070c98ff..6cfdf61aef 100644 --- a/hugegraph-server/hugegraph-dist/src/assembly/static/conf/gremlin-server.yaml +++ b/hugegraph-server/hugegraph-dist/src/assembly/static/conf/gremlin-server.yaml @@ -37,7 +37,7 @@ scriptEngines: { org.apache.tinkerpop.gremlin.jsr223.ImportGremlinPlugin: { classImports: [ java.lang.Math, - org.apache.hugegraph.backend.id.IdGenerator, + org.apache.hugegraph.id.IdGenerator, org.apache.hugegraph.type.define.Directions, org.apache.hugegraph.type.define.NodeRole, org.apache.hugegraph.masterelection.GlobalMasterInfo, diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft1/gremlin-server.yaml b/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft1/gremlin-server.yaml index 54e9f30260..37f5735897 100644 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft1/gremlin-server.yaml +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft1/gremlin-server.yaml @@ -33,7 +33,7 @@ scriptEngines: { org.apache.tinkerpop.gremlin.jsr223.ImportGremlinPlugin: { classImports: [ java.lang.Math, - org.apache.hugegraph.backend.id.IdGenerator, + org.apache.hugegraph.id.IdGenerator, org.apache.hugegraph.type.define.Directions, org.apache.hugegraph.type.define.NodeRole, org.apache.hugegraph.masterelection.GlobalMasterInfo, diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft2/gremlin-server.yaml b/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft2/gremlin-server.yaml index c2eccf2b38..45a95ad7f8 100644 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft2/gremlin-server.yaml +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft2/gremlin-server.yaml @@ -33,7 +33,7 @@ scriptEngines: { org.apache.tinkerpop.gremlin.jsr223.ImportGremlinPlugin: { classImports: [ java.lang.Math, - org.apache.hugegraph.backend.id.IdGenerator, + org.apache.hugegraph.id.IdGenerator, org.apache.hugegraph.type.define.Directions, org.apache.hugegraph.type.define.NodeRole, org.apache.hugegraph.masterelection.GlobalMasterInfo, diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft3/gremlin-server.yaml b/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft3/gremlin-server.yaml index 09cba186d8..4e61f9674a 100644 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft3/gremlin-server.yaml +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft3/gremlin-server.yaml @@ -33,7 +33,7 @@ scriptEngines: { org.apache.tinkerpop.gremlin.jsr223.ImportGremlinPlugin: { classImports: [ java.lang.Math, - org.apache.hugegraph.backend.id.IdGenerator, + org.apache.hugegraph.id.IdGenerator, org.apache.hugegraph.type.define.Directions, org.apache.hugegraph.type.define.NodeRole, org.apache.hugegraph.masterelection.GlobalMasterInfo, diff --git a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/cmd/StoreDumper.java b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/cmd/StoreDumper.java index 352ea0b02e..70be13b9a4 100644 --- a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/cmd/StoreDumper.java +++ b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/cmd/StoreDumper.java @@ -21,7 +21,7 @@ import org.apache.hugegraph.HugeFactory; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.backend.store.BackendStore; import org.apache.hugegraph.dist.RegisterUtil; diff --git a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/HugeGraphServer.java b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/HugeGraphServer.java index 1165fb1a93..6e87c54194 100644 --- a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/HugeGraphServer.java +++ b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/HugeGraphServer.java @@ -17,7 +17,7 @@ package org.apache.hugegraph.dist; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeFactory; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.config.ServerOptions; diff --git a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/HugeGremlinServer.java b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/HugeGremlinServer.java index d03f8172d4..90319aef75 100644 --- a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/HugeGremlinServer.java +++ b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/HugeGremlinServer.java @@ -17,7 +17,7 @@ package org.apache.hugegraph.dist; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.auth.ContextGremlinServer; import org.apache.hugegraph.event.EventHub; import org.apache.hugegraph.util.ConfigUtil; diff --git a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/RegisterUtil.java b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/RegisterUtil.java index 380dd996ad..4b862e822c 100644 --- a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/RegisterUtil.java +++ b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/RegisterUtil.java @@ -24,7 +24,7 @@ import org.apache.commons.configuration2.PropertiesConfiguration; import org.apache.commons.configuration2.builder.fluent.Configurations; import org.apache.commons.configuration2.ex.ConfigurationException; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.backend.serializer.SerializerFactory; import org.apache.hugegraph.backend.store.BackendProviderFactory; import org.apache.hugegraph.config.CoreOptions; diff --git a/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/Example1.java b/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/Example1.java index a6cda3932f..03c4a0a643 100644 --- a/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/Example1.java +++ b/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/Example1.java @@ -23,14 +23,14 @@ import org.apache.hugegraph.HugeFactory; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.exception.BackendException; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.query.ConditionQuery; import org.apache.hugegraph.backend.tx.GraphTransaction; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.testutil.Whitebox; import org.apache.hugegraph.traversal.optimize.Text; import org.apache.hugegraph.type.HugeType; diff --git a/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/Example4.java b/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/Example4.java index 0416dd757f..3d552e19dc 100644 --- a/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/Example4.java +++ b/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/Example4.java @@ -22,10 +22,10 @@ import org.apache.hugegraph.HugeFactory; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.backend.tx.GraphTransaction; import org.apache.hugegraph.meta.MetaManager; -import org.apache.hugegraph.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; import org.apache.hugegraph.schema.SchemaManager; import org.apache.hugegraph.testutil.Whitebox; import org.apache.hugegraph.util.Log; diff --git a/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/ExampleUtil.java b/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/ExampleUtil.java index c5f0a4206f..3bde4e4d65 100644 --- a/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/ExampleUtil.java +++ b/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/ExampleUtil.java @@ -21,7 +21,7 @@ import java.util.Iterator; import java.util.concurrent.TimeoutException; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeFactory; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.dist.RegisterUtil; diff --git a/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/PerfExampleBase.java b/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/PerfExampleBase.java index 278b6336bd..88dd3c6a8c 100644 --- a/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/PerfExampleBase.java +++ b/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/PerfExampleBase.java @@ -29,8 +29,8 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.backend.cache.Cache; import org.apache.hugegraph.backend.cache.CacheManager; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.ConditionQuery; import org.apache.hugegraph.perf.PerfUtil; import org.apache.hugegraph.schema.SchemaManager; import org.apache.hugegraph.structure.HugeVertex; diff --git a/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/TaskExample.java b/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/TaskExample.java index 2afa719b99..fef7c3676d 100644 --- a/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/TaskExample.java +++ b/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/TaskExample.java @@ -22,8 +22,8 @@ import org.apache.commons.collections.IteratorUtils; import org.apache.hugegraph.HugeFactory; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.task.HugeTask; import org.apache.hugegraph.task.TaskCallable; import org.apache.hugegraph.task.TaskScheduler; diff --git a/hugegraph-server/hugegraph-hbase/src/main/java/org/apache/hugegraph/backend/store/hbase/HbaseSerializer.java b/hugegraph-server/hugegraph-hbase/src/main/java/org/apache/hugegraph/backend/store/hbase/HbaseSerializer.java index 0cfc928ab8..37b98dc037 100644 --- a/hugegraph-server/hugegraph-hbase/src/main/java/org/apache/hugegraph/backend/store/hbase/HbaseSerializer.java +++ b/hugegraph-server/hugegraph-hbase/src/main/java/org/apache/hugegraph/backend/store/hbase/HbaseSerializer.java @@ -19,7 +19,7 @@ import java.util.Arrays; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.serializer.BinarySerializer; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.type.HugeType; diff --git a/hugegraph-server/hugegraph-hbase/src/main/java/org/apache/hugegraph/backend/store/hbase/HbaseSessions.java b/hugegraph-server/hugegraph-hbase/src/main/java/org/apache/hugegraph/backend/store/hbase/HbaseSessions.java index 3255d092d6..d27ce99591 100644 --- a/hugegraph-server/hugegraph-hbase/src/main/java/org/apache/hugegraph/backend/store/hbase/HbaseSessions.java +++ b/hugegraph-server/hugegraph-hbase/src/main/java/org/apache/hugegraph/backend/store/hbase/HbaseSessions.java @@ -67,8 +67,8 @@ import org.apache.hadoop.hbase.filter.PrefixFilter; import org.apache.hadoop.hbase.util.VersionInfo; import org.apache.hadoop.security.UserGroupInformation; -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.exception.BackendException; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.backend.store.BackendEntry.BackendIterator; import org.apache.hugegraph.backend.store.BackendSession.AbstractBackendSession; import org.apache.hugegraph.backend.store.BackendSessionPool; diff --git a/hugegraph-server/hugegraph-hbase/src/main/java/org/apache/hugegraph/backend/store/hbase/HbaseStore.java b/hugegraph-server/hugegraph-hbase/src/main/java/org/apache/hugegraph/backend/store/hbase/HbaseStore.java index 56f7210cc8..b539fc5427 100644 --- a/hugegraph-server/hugegraph-hbase/src/main/java/org/apache/hugegraph/backend/store/hbase/HbaseStore.java +++ b/hugegraph-server/hugegraph-hbase/src/main/java/org/apache/hugegraph/backend/store/hbase/HbaseStore.java @@ -30,9 +30,9 @@ import org.apache.hadoop.hbase.NamespaceExistException; import org.apache.hadoop.hbase.TableExistsException; import org.apache.hadoop.hbase.TableNotFoundException; -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.exception.BackendException; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.store.AbstractBackendStore; import org.apache.hugegraph.backend.store.BackendAction; import org.apache.hugegraph.backend.store.BackendEntry; diff --git a/hugegraph-server/hugegraph-hbase/src/main/java/org/apache/hugegraph/backend/store/hbase/HbaseTable.java b/hugegraph-server/hugegraph-hbase/src/main/java/org/apache/hugegraph/backend/store/hbase/HbaseTable.java index 53a8d14f65..3faeb5d3e3 100644 --- a/hugegraph-server/hugegraph-hbase/src/main/java/org/apache/hugegraph/backend/store/hbase/HbaseTable.java +++ b/hugegraph-server/hugegraph-hbase/src/main/java/org/apache/hugegraph/backend/store/hbase/HbaseTable.java @@ -37,23 +37,23 @@ import org.apache.hadoop.hbase.client.Admin; import org.apache.hadoop.hbase.client.RegionInfo; import org.apache.hadoop.hbase.client.Result; -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.exception.BackendException; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.page.PageState; -import org.apache.hugegraph.backend.query.Aggregate; -import org.apache.hugegraph.backend.query.Aggregate.AggregateFunc; -import org.apache.hugegraph.backend.query.Condition.Relation; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.IdPrefixQuery; -import org.apache.hugegraph.backend.query.IdRangeQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Aggregate; +import org.apache.hugegraph.query.Aggregate.AggregateFunc; +import org.apache.hugegraph.query.Condition.Relation; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.IdPrefixQuery; +import org.apache.hugegraph.query.IdRangeQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.serializer.BinaryBackendEntry; import org.apache.hugegraph.backend.serializer.BinaryEntryIterator; import org.apache.hugegraph.backend.store.BackendEntry; -import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.backend.store.BackendEntryIterator; import org.apache.hugegraph.backend.store.BackendTable; -import org.apache.hugegraph.backend.store.Shard; +import org.apache.hugegraph.backend.Shard; import org.apache.hugegraph.exception.NotSupportException; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.util.Bytes; diff --git a/hugegraph-server/hugegraph-hbase/src/main/java/org/apache/hugegraph/backend/store/hbase/HbaseTables.java b/hugegraph-server/hugegraph-hbase/src/main/java/org/apache/hugegraph/backend/store/hbase/HbaseTables.java index c3cda4031e..7535e29d01 100644 --- a/hugegraph-server/hugegraph-hbase/src/main/java/org/apache/hugegraph/backend/store/hbase/HbaseTables.java +++ b/hugegraph-server/hugegraph-hbase/src/main/java/org/apache/hugegraph/backend/store/hbase/HbaseTables.java @@ -25,12 +25,12 @@ import org.apache.hadoop.hbase.CellUtil; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.util.Bytes; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.serializer.BinaryBackendEntry; import org.apache.hugegraph.backend.serializer.BinaryEntryIterator; -import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.backend.store.BackendEntry; -import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.backend.store.BackendEntryIterator; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.HugeKeys; diff --git a/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreSessions.java b/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreSessions.java index 85d664c587..2048e7d98e 100755 --- a/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreSessions.java +++ b/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreSessions.java @@ -22,7 +22,8 @@ import java.util.Set; import org.apache.commons.lang3.tuple.Pair; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Query; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.backend.store.BackendEntry.BackendColumnIterator; import org.apache.hugegraph.backend.store.BackendSession.AbstractBackendSession; @@ -183,6 +184,12 @@ public abstract BackendColumnIterator scan(String table, public abstract BackendColumnIterator getWithBatch(String table, List keys); + public BackendColumnIterator getWithBatchExact(String table, List keys) { + return BackendColumnIterator.wrap(keys.stream().map(key -> + BackendColumn.of(key.getKey(), this.get(table, key.getOwner(), key.getKey()))) + .filter(column -> column.value != null && column.value.length != 0).iterator()); + } + public abstract void merge(String table, byte[] ownerKey, byte[] key, byte[] value); diff --git a/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreSessionsImpl.java b/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreSessionsImpl.java index d172651393..7c3ab3dc66 100755 --- a/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreSessionsImpl.java +++ b/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreSessionsImpl.java @@ -32,9 +32,9 @@ import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.lang3.tuple.Pair; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.store.BackendEntry; -import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.backend.store.BackendEntry.BackendColumnIterator; import org.apache.hugegraph.backend.store.BackendEntryIterator; import org.apache.hugegraph.config.CoreOptions; @@ -409,6 +409,11 @@ public void close() { } } + static BackendColumnIterator getWithBatchExact(HgStoreSession graph, String table, List keys) { + return BackendColumnIterator.wrap(graph.batchGetOwner(table, keys).stream() + .map(entry -> BackendColumn.of(entry.key(), entry.value())).iterator()); + } + /** * HstoreSession implement for hstore */ @@ -787,6 +792,12 @@ public BackendColumnIterator getWithBatch(String table, return new ColumnIterator<>(table, kvIterator); } + @Override + public BackendColumnIterator getWithBatchExact(String table, List keys) { + assert !this.hasChanges(); + return HstoreSessionsImpl.getWithBatchExact(this.graph, table, keys); + } + @Override public void merge(String table, byte[] ownerKey, byte[] key, byte[] value) { diff --git a/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreStore.java b/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreStore.java index 6439096674..22cc02676b 100644 --- a/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreStore.java +++ b/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreStore.java @@ -17,12 +17,13 @@ package org.apache.hugegraph.backend.store.hstore; +import org.apache.hugegraph.backend.BinaryId; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; -import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -38,16 +39,14 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.query.ConditionQuery; import org.apache.hugegraph.backend.query.ConditionQueryFlatten; -import org.apache.hugegraph.backend.query.IdPrefixQuery; -import org.apache.hugegraph.backend.query.IdQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.IdPrefixQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.serializer.BinaryBackendEntry; -import org.apache.hugegraph.backend.serializer.BytesBuffer; -import org.apache.hugegraph.backend.serializer.MergeIterator; +import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.backend.store.AbstractBackendStore; import org.apache.hugegraph.backend.store.BackendAction; import org.apache.hugegraph.backend.store.BackendEntry; @@ -59,7 +58,7 @@ import org.apache.hugegraph.config.CoreOptions; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.iterator.CIter; -import org.apache.hugegraph.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; import org.apache.hugegraph.type.HugeTableType; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Action; @@ -451,7 +450,7 @@ public IdPrefixQuery next() { BytesBuffer buffer = BytesBuffer.allocate(BytesBuffer.BUF_EDGE_ID); buffer.writeId(ownerId); - return new IdPrefixQuery(cq, new BinaryBackendEntry.BinaryId( + return new IdPrefixQuery(cq, new BinaryId( buffer.bytes(), ownerId)); } @@ -566,65 +565,14 @@ public Iterator> query(List typeList, private Iterator getBackendEntryIterator( Iterator entries, Query query) { - HstoreTable table; Set olapPks = query.olapPks(); if (this.isGraphStore && !olapPks.isEmpty()) { - List> iterators = new ArrayList<>(); - for (Id pk : olapPks) { - // Construct OLAP table query query condition - Query q = this.constructOlapQueryCondition(pk, query); - table = this.table(HugeType.OLAP); - iterators.add(table.queryOlap(this.session(HugeType.OLAP), q)); - } - entries = new MergeIterator<>(entries, iterators, - BackendEntry::mergeable); + HstoreTables.OlapTable table = (HstoreTables.OlapTable) this.table(HugeType.OLAP); + entries = table.mergeEntries(this.session(HugeType.OLAP), entries, olapPks, query.paging()); } return entries; } - /** - * Reconstruct the query OLAP table query - * Due to the olap merged into one table, when writing olap data, the key has a pk added at the end. - * So when making inquiries here, it is necessary to reconstruct the pk prefix. - * Write reference BinarySerializer.writeOlapVertex - * - * @param pk - * @param query - * @return - */ - private Query constructOlapQueryCondition(Id pk, Query query) { - if (query instanceof IdQuery && !CollectionUtils.isEmpty((query).ids())) { - IdQuery q = (IdQuery) query.copy(); - Iterator iterator = q.ids().iterator(); - LinkedHashSet linkedHashSet = new LinkedHashSet<>(); - while (iterator.hasNext()) { - Id id = iterator.next(); - if (id instanceof BinaryBackendEntry.BinaryId) { - id = ((BinaryBackendEntry.BinaryId) id).origin(); - } - - // create binary id - BytesBuffer buffer = - BytesBuffer.allocate(1 + pk.length() + 1 + id.length()); - buffer.writeId(pk); - id = new BinaryBackendEntry.BinaryId( - buffer.writeId(id).bytes(), id); - linkedHashSet.add(id); - } - q.resetIds(); - q.query(linkedHashSet); - return q; - } else { - // create binary id - BytesBuffer buffer = BytesBuffer.allocate(1 + pk.length()); - pk = new BinaryBackendEntry.BinaryId( - buffer.writeId(pk).bytes(), pk); - - IdPrefixQuery idPrefixQuery = new IdPrefixQuery(HugeType.OLAP, pk); - return idPrefixQuery; - } - } - @Override public Number queryNumber(Query query) { this.checkOpened(); diff --git a/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreTable.java b/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreTable.java index a1baa14089..5774eeb7c6 100755 --- a/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreTable.java +++ b/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreTable.java @@ -17,6 +17,8 @@ package org.apache.hugegraph.backend.store.hstore; +import org.apache.hugegraph.backend.BinaryId; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -29,25 +31,25 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.page.PageState; -import org.apache.hugegraph.backend.query.Aggregate; -import org.apache.hugegraph.backend.query.Aggregate.AggregateFunc; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.Condition.Relation; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.IdPrefixQuery; -import org.apache.hugegraph.backend.query.IdRangeQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Aggregate; +import org.apache.hugegraph.query.Aggregate.AggregateFunc; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.Condition.Relation; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.IdPrefixQuery; +import org.apache.hugegraph.query.IdRangeQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.serializer.BinaryBackendEntry; import org.apache.hugegraph.backend.serializer.BinaryEntryIterator; import org.apache.hugegraph.backend.store.BackendEntry; -import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.backend.store.BackendEntry.BackendColumnIterator; import org.apache.hugegraph.backend.store.BackendEntryIterator; import org.apache.hugegraph.backend.store.BackendTable; -import org.apache.hugegraph.backend.store.Shard; +import org.apache.hugegraph.backend.Shard; import org.apache.hugegraph.backend.store.hstore.HstoreSessions.Countable; import org.apache.hugegraph.backend.store.hstore.HstoreSessions.Session; import org.apache.hugegraph.exception.NotSupportException; @@ -210,8 +212,8 @@ public byte[] getInsertOwner(BackendEntry entry) { * @return */ protected byte[] getOwnerId(Id id) { - if (id instanceof BinaryBackendEntry.BinaryId) { - id = ((BinaryBackendEntry.BinaryId) id).origin(); + if (id instanceof BinaryId) { + id = ((BinaryId) id).origin(); } if (id != null && id.edge()) { id = ((EdgeId) id).ownerVertexId(); diff --git a/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreTables.java b/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreTables.java index fe8c324f19..54b721d325 100644 --- a/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreTables.java +++ b/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreTables.java @@ -18,12 +18,28 @@ package org.apache.hugegraph.backend.store.hstore; import java.util.List; - -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.Condition.Relation; -import org.apache.hugegraph.backend.query.ConditionQuery; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Collections; +import java.util.Map; +import java.util.HashMap; +import java.util.Set; +import java.nio.ByteBuffer; + +import org.apache.hugegraph.backend.BackendColumn; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.backend.BinaryId; +import org.apache.hugegraph.serializer.BytesBuffer; +import org.apache.hugegraph.serializer.OlapKey; +import org.apache.hugegraph.iterator.FlatMapperIterator; +import org.apache.hugegraph.iterator.WrappedIterator; +import org.apache.hugegraph.store.HgOwnerKey; +import org.apache.hugegraph.query.Query; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.Condition.Relation; +import org.apache.hugegraph.query.ConditionQuery; import org.apache.hugegraph.backend.serializer.BinarySerializer; +import org.apache.hugegraph.backend.serializer.BinaryBackendEntry; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.backend.store.BackendEntry.BackendColumnIterator; import org.apache.hugegraph.backend.store.hstore.HstoreSessions.Session; @@ -124,7 +140,7 @@ public void delete(Session session, BackendEntry entry) { * Regular index delete will call eliminate() */ byte[] ownerKey = super.ownerDelegate.apply(entry); - for (BackendEntry.BackendColumn column : entry.columns()) { + for (BackendColumn column : entry.columns()) { // Don't assert entry.belongToMe(column), length-prefix is 1* session.deletePrefix(this.table(), ownerKey, column.name); } @@ -197,17 +213,207 @@ protected BackendColumnIterator queryByCond(Session session, public static class OlapTable extends HstoreTable { public static final String TABLE = HugeTableType.OLAP_TABLE.string(); + private static final int MAX_REQUEST_KEYS = 1024; + private static final int MAX_SELECTED_VERTICES = 128; public OlapTable(String database) { // Originally multiple ap_{pk_id} merged into one ap table super(database, TABLE); } + @Override + public void insert(Session session, BackendEntry entry) { + E.checkArgumentNotNull(entry.subId(), "Merged OLAP write requires a property ID"); + byte[] owner = this.getInsertOwner(entry); + for (BackendColumn column : entry.columns()) { + E.checkArgument(OlapKey.matchesProperty(column.value, entry.subId()), + "OLAP value must match property ID '%s'", entry.subId()); + session.put(this.table(), owner, OlapKey.format(entry.subId(), entry.originId()), column.value); + } + } + + @Override + public void insert(Session session, BackendEntry entry, boolean isEdge) { + this.insert(session, entry); + } + + @Override + public void delete(Session session, BackendEntry entry) { + E.checkArgumentNotNull(entry.subId(), "Merged OLAP delete requires a property ID"); + byte[] owner = this.getInsertOwner(entry); + session.delete(this.table(), owner, OlapKey.format(entry.subId(), entry.originId())); + // Delete an old vertex-only record only if it belongs to the requested property. + byte[] legacyKey = BytesBuffer.allocate(entry.originId().length() + 9) + .writeId(entry.originId()).bytes(); + if (OlapKey.matchesProperty(session.get(this.table(), owner, legacyKey), entry.subId())) { + session.delete(this.table(), owner, legacyKey); + } + } + + @Override + public boolean queryExist(Session session, BackendEntry entry) { + E.checkArgumentNotNull(entry.subId(), "Merged OLAP existence query requires a property ID"); + Id key = new BinaryId(OlapKey.format(entry.subId(), entry.originId()), entry.originId()); + try (BackendColumnIterator result = this.getById(session, key)) { + return result.hasNext(); + } + } + + @Override + protected BackendColumnIterator queryBy(Session session, Query query) { + if (!query.ids().isEmpty() && query.conditions().isEmpty()) { + return BackendColumnIterator.wrap(new FlatMapperIterator<>( + query.ids().iterator(), id -> this.getById(session, id))); + } + return super.queryBy(session, query); + } + + @Override + protected BackendColumnIterator getById(Session session, Id id) { + // This query key is explicitly constructed by HstoreStore for the merged OLAP table. + BytesBuffer key = BytesBuffer.wrap(id.asBytes()); + Id propertyId = key.readId(); + Id vertexId = key.readId(); + byte[] owner = this.getOwnerId(id instanceof BinaryId ? ((BinaryId) id).origin() : vertexId); + byte[] value = session.get(this.table(), owner, id.asBytes()); + if (value == null || value.length == 0) { + byte[] legacyKey = BytesBuffer.allocate(vertexId.length() + 9).writeId(vertexId).bytes(); + value = session.get(this.table(), owner, legacyKey); + } + if (!OlapKey.matchesProperty(value, propertyId)) { + return BackendColumnIterator.empty(); + } + // Normalize only the returned key, so the existing OLAP entry parser retains vertex origin. + return BackendColumnIterator.iterator(BackendColumn.of(id.asBytes(), value)); + } + @Override protected BackendColumnIterator queryById(Session session, Id id) { return this.getById(session, id); } + Iterator mergeEntries(Session session, Iterator entries, + Set properties, boolean paging) { + if (properties == null || properties.isEmpty()) { + return entries; + } + return new WrappedIterator() { + private Iterator batch = Collections.emptyIterator(); + private final int batchSize = paging ? 1 : (int) Math.max(1L, Math.min( + MAX_SELECTED_VERTICES, MAX_REQUEST_KEYS / (properties.size() + 1L))); + private boolean closed; + + @Override + public void close() throws Exception { + if (!this.closed) { + this.closed = true; + this.current = none(); + this.batch = Collections.emptyIterator(); + super.close(); + } + } + + @Override + protected Iterator originIterator() { + return entries; + } + + @Override + protected boolean fetch() { + if (this.closed) { + return false; + } + try { + return this.fetchBatch(); + } catch (RuntimeException | Error failure) { + try { + this.close(); + } catch (Exception closeFailure) { + failure.addSuppressed(closeFailure); + } + throw failure; + } + } + + private boolean fetchBatch() { + if (!this.batch.hasNext()) { + List selected = new ArrayList<>(this.batchSize); + while (selected.size() < this.batchSize && entries.hasNext()) { + selected.add(entries.next()); + } + if (selected.isEmpty()) { + WrappedIterator.close(this); + return false; + } + this.mergeSelected(selected); + this.batch = selected.iterator(); + } + this.current = this.batch.next(); + return true; + } + + private void mergeSelected(List selected) { + Map legacy = new HashMap<>(); + Iterator remaining = properties.iterator(); + boolean firstChunk = true; + do { + int capacity = Math.min(MAX_REQUEST_KEYS, + selected.size() * (Math.min(properties.size(), MAX_REQUEST_KEYS) + 1)); + List keys = new ArrayList<>(capacity); + if (firstChunk) { + for (BackendEntry entry : selected) { + Id vertexId = entry.originId(); + byte[] key = BytesBuffer.allocate(vertexId.length() + 9).writeId(vertexId).bytes(); + keys.add(HgOwnerKey.of(OlapTable.this.getOwnerId(vertexId), key)); + } + } + int propertyLimit = (MAX_REQUEST_KEYS - keys.size()) / selected.size(); + List requestedProperties = new ArrayList<>(Math.min(propertyLimit, properties.size())); + while (requestedProperties.size() < propertyLimit && remaining.hasNext()) { + Id property = remaining.next(); + requestedProperties.add(property); + for (BackendEntry entry : selected) { + Id vertexId = entry.originId(); + keys.add(HgOwnerKey.of(OlapTable.this.getOwnerId(vertexId), + OlapKey.format(property, vertexId))); + } + } + Map values = new HashMap<>(); + try (BackendColumnIterator columns = session.getWithBatchExact(OlapTable.this.table(), keys)) { + while (columns.hasNext()) { + BackendColumn column = columns.next(); + values.put(ByteBuffer.wrap(column.name), column); + } + } + if (firstChunk) { + for (BackendEntry entry : selected) { + Id vertexId = entry.originId(); + byte[] key = BytesBuffer.allocate(vertexId.length() + 9).writeId(vertexId).bytes(); + legacy.put(vertexId, values.get(ByteBuffer.wrap(key))); + } + firstChunk = false; + } + for (BackendEntry entry : selected) { + Id vertexId = entry.originId(); + for (Id property : requestedProperties) { + byte[] key = OlapKey.format(property, vertexId); + BackendColumn column = values.get(ByteBuffer.wrap(key)); + if (column == null || column.value == null || column.value.length == 0) { + column = legacy.get(vertexId); + } + if (column == null || !OlapKey.matchesProperty(column.value, property)) { + continue; + } + BinaryBackendEntry olap = new BinaryBackendEntry(entry.type(), key, false, true); + olap.columns(BackendColumn.of(key, column.value)); + E.checkState(entry.mergeable(olap), "OLAP row must belong to its selected vertex"); + } + } + } while (remaining.hasNext()); + } + }; + } + @Override public boolean isOlap() { return true; diff --git a/hugegraph-server/hugegraph-hstore/src/test/java/org/apache/hugegraph/backend/store/hstore/HstoreSessionsImplTest.java b/hugegraph-server/hugegraph-hstore/src/test/java/org/apache/hugegraph/backend/store/hstore/HstoreSessionsImplTest.java index b962ae0b0d..dd15724c23 100644 --- a/hugegraph-server/hugegraph-hstore/src/test/java/org/apache/hugegraph/backend/store/hstore/HstoreSessionsImplTest.java +++ b/hugegraph-server/hugegraph-hstore/src/test/java/org/apache/hugegraph/backend/store/hstore/HstoreSessionsImplTest.java @@ -20,14 +20,19 @@ import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Constructor; +import java.lang.reflect.Proxy; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; import java.util.NoSuchElementException; -import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.backend.store.BackendEntry.BackendColumnIterator; import org.apache.hugegraph.store.HgKvEntry; +import org.apache.hugegraph.store.HgStoreSession; +import org.apache.hugegraph.store.HgOwnerKey; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.serializer.OlapKey; import org.apache.hugegraph.store.HgKvIterator; import org.junit.Assert; import org.junit.Test; @@ -71,6 +76,30 @@ public void testColumnIteratorClearsPositionWhenFullyExhausted() Assert.assertNull(iterator.position()); } + @Test + public void testExactOlapBatchUsesNativePointKeysAndOwnerRouting() { + byte[] vertexOwner = IdGenerator.of(9).asBytes(); + byte[] namespaced = OlapKey.format(IdGenerator.of(9), IdGenerator.of(9)); + List keys = List.of(HgOwnerKey.of(vertexOwner, namespaced)); + int[] calls = {0}; + HgStoreSession graph = (HgStoreSession) Proxy.newProxyInstance(HgStoreSession.class.getClassLoader(), + new Class[]{HgStoreSession.class}, (proxy, method, args) -> { + Assert.assertEquals("batchGetOwner", method.getName()); + Assert.assertEquals("g+olap", args[0]); + Assert.assertSame(keys, args[1]); + Assert.assertArrayEquals(vertexOwner, keys.get(0).getOwner()); + Assert.assertArrayEquals(namespaced, keys.get(0).getKey()); + calls[0]++; + return List.of(new TestEntry(namespaced)); + }); + try (BackendColumnIterator result = HstoreSessionsImpl.getWithBatchExact(graph, "g+olap", keys)) { + Assert.assertTrue(result.hasNext()); + Assert.assertArrayEquals(namespaced, result.next().name); + Assert.assertFalse(result.hasNext()); + } + Assert.assertEquals(1, calls[0]); + } + private static BackendColumnIterator newColumnIterator( HgKvIterator iterator) throws Exception { Class clazz = Class.forName(HstoreSessionsImpl.class.getName() + diff --git a/hugegraph-server/hugegraph-hstore/src/test/java/org/apache/hugegraph/backend/store/hstore/HstoreTableTest.java b/hugegraph-server/hugegraph-hstore/src/test/java/org/apache/hugegraph/backend/store/hstore/HstoreTableTest.java index 79791daae1..0ae351548e 100644 --- a/hugegraph-server/hugegraph-hstore/src/test/java/org/apache/hugegraph/backend/store/hstore/HstoreTableTest.java +++ b/hugegraph-server/hugegraph-hstore/src/test/java/org/apache/hugegraph/backend/store/hstore/HstoreTableTest.java @@ -18,23 +18,45 @@ package org.apache.hugegraph.backend.store.hstore; import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.Set; +import java.util.LinkedHashSet; +import java.nio.ByteBuffer; +import java.lang.reflect.Proxy; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import org.apache.commons.lang3.tuple.Pair; -import org.apache.hugegraph.backend.id.Id.IdType; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id.IdType; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.HugeGraph; +import org.apache.hugegraph.backend.BinaryId; +import org.apache.hugegraph.backend.serializer.BinaryBackendEntry; +import org.apache.hugegraph.backend.serializer.BinarySerializer; +import org.apache.hugegraph.serializer.BytesBuffer; +import org.apache.hugegraph.serializer.OlapKey; +import org.apache.hugegraph.config.HugeConfig; +import org.apache.hugegraph.config.ConfigOption; +import org.apache.hugegraph.iterator.CIter; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; +import org.apache.hugegraph.structure.HugeVertex; +import org.apache.hugegraph.type.define.DataType; +import org.apache.hugegraph.type.define.WriteType; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.page.PageInfo; import org.apache.hugegraph.backend.page.PageState; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.IdPrefixQuery; -import org.apache.hugegraph.backend.query.IdRangeQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.IdPrefixQuery; +import org.apache.hugegraph.query.IdRangeQuery; +import org.apache.hugegraph.query.Query; +import org.apache.hugegraph.query.IdQuery; import org.apache.hugegraph.backend.store.BackendEntry; -import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.backend.store.BackendEntry.BackendColumnIterator; import org.apache.hugegraph.backend.store.BackendEntryIterator; import org.apache.hugegraph.store.HgOwnerKey; @@ -216,6 +238,343 @@ public void testPrefixListQueryPushesCopyAndKeepsOrigin() { Assert.assertNull(pushed.originQuery()); } + @Test + public void testMergedOlapInsertPreservesStandaloneEntryAndIsolatesProperties() { + HstoreTables.OlapTable table = new HstoreTables.OlapTable("g"); + OlapSession session = new OlapSession(); + BinaryBackendEntry score = olapEntry(9, 1, 99); + BinaryBackendEntry rank = olapEntry(10, 1, 123); + byte[] standaloneKey = score.columns().iterator().next().name; + table.insert(session, score, false); // Actual HstoreStore.mutate entry point. + table.insert(session, rank); + Assert.assertEquals(2, session.values.size()); + Assert.assertArrayEquals(standaloneKey, score.columns().iterator().next().name); + Assert.assertNull(session.values.get(ByteBuffer.wrap(standaloneKey))); + Assert.assertTrue(OlapKey.matchesProperty(session.values.get(ByteBuffer.wrap( + OlapKey.format(IdGenerator.of(9), IdGenerator.of(1)))), IdGenerator.of(9))); + for (byte[] owner : session.owners) { + Assert.assertArrayEquals(IdGenerator.of(1).asBytes(), owner); + } + } + + @Test + public void testOlapPointFallbackAndDeleteValidateLegacyPropertyIdentity() { + HstoreTables.OlapTable table = new HstoreTables.OlapTable("g"); + OlapSession session = new OlapSession(); + BinaryBackendEntry legacy = olapEntry(9, 1, 42); + BackendColumn old = legacy.columns().iterator().next(); + session.values.put(ByteBuffer.wrap(old.name), old.value); + Id scoreKey = new BinaryId(OlapKey.format(IdGenerator.of(9), IdGenerator.of(1)), IdGenerator.of(1)); + Id rankKey = new BinaryId(OlapKey.format(IdGenerator.of(10), IdGenerator.of(1)), IdGenerator.of(1)); + try (BackendColumnIterator result = table.getById(session, scoreKey)) { + Assert.assertTrue(result.hasNext()); + Assert.assertArrayEquals(scoreKey.asBytes(), result.next().name); + } + try (BackendColumnIterator result = table.getById(session, rankKey)) { + Assert.assertFalse(result.hasNext()); + } + IdQuery query = new IdQuery(HugeType.VERTEX); + query.query(scoreKey); + query.query(rankKey); + Iterator queried = table.queryOlap(session, query); + Assert.assertTrue(queried.hasNext()); + Assert.assertEquals(IdGenerator.of(1), queried.next().originId()); + Assert.assertFalse(queried.hasNext()); + table.delete(session, olapEntry(10, 1, 123)); + Assert.assertNotNull(session.values.get(ByteBuffer.wrap(old.name))); + table.delete(session, legacy); + Assert.assertNull(session.values.get(ByteBuffer.wrap(old.name))); + } + + @Test + public void testOlapConditionalUpdatesUsePropertyScopedExistenceForOldAndNewRows() { + HstoreTables.OlapTable table = new HstoreTables.OlapTable("g"); + OlapSession session = new OlapSession(); + BinaryBackendEntry oldScore = olapEntry(9, 1, 42); + BackendColumn old = oldScore.columns().iterator().next(); + session.values.put(ByteBuffer.wrap(old.name), old.value); + BinaryBackendEntry score = olapEntry(9, 1, 99); + BinaryBackendEntry rank = olapEntry(10, 1, 123); + byte[] scoreKey = OlapKey.format(IdGenerator.of(9), IdGenerator.of(1)); + byte[] rankKey = OlapKey.format(IdGenerator.of(10), IdGenerator.of(1)); + Assert.assertTrue(table.queryExist(session, score)); + Assert.assertFalse(table.queryExist(session, rank)); + table.updateIfPresent(session, rank); + Assert.assertNull(session.values.get(ByteBuffer.wrap(rankKey))); + table.updateIfAbsent(session, rank); + Assert.assertNotNull(session.values.get(ByteBuffer.wrap(rankKey))); + table.updateIfPresent(session, score); + Assert.assertArrayEquals(score.columns().iterator().next().value, + session.values.get(ByteBuffer.wrap(scoreKey))); + table.updateIfAbsent(session, olapEntry(9, 1, 101)); + Assert.assertArrayEquals(score.columns().iterator().next().value, + session.values.get(ByteBuffer.wrap(scoreKey))); + Assert.assertArrayEquals(old.value, session.values.get(ByteBuffer.wrap(old.name))); + table.delete(session, score); + Assert.assertFalse(table.queryExist(session, score)); + Assert.assertTrue(table.queryExist(session, rank)); + table.updateIfPresent(session, score); + Assert.assertNull(session.values.get(ByteBuffer.wrap(scoreKey))); + Assert.assertEquals(1, session.values.size()); + } + + @Test + public void testOlapMergeBatchesOnlySelectedVerticesAndPrefersNamespacedRows() throws Exception { + HstoreTables.OlapTable table = new HstoreTables.OlapTable("g"); + OlapSession session = new OlapSession(); + BinaryBackendEntry legacy = olapEntry(9, 1, 42); + BackendColumn old = legacy.columns().iterator().next(); + session.values.put(ByteBuffer.wrap(old.name), old.value); + table.insert(session, olapEntry(9, 1, 99)); + table.insert(session, olapEntry(10, 1, 123)); + BackendColumn legacySecond = olapEntry(9, 2, 43).columns().iterator().next(); + session.values.put(ByteBuffer.wrap(legacySecond.name), legacySecond.value); + List base = new ArrayList<>(); + for (int i = 1; i <= 130; i++) { + base.add(vertexEntry(i)); + } + EntrySource source = new EntrySource(base); + Iterator merged = table.mergeEntries(session, source, + Set.of(IdGenerator.of(9), IdGenerator.of(10)), false); + Assert.assertEquals(3, merged.next().columnsSize()); + Assert.assertEquals(1, session.batchCalls); + Assert.assertEquals(128 * 3, session.requested.get(0).size()); + for (HgOwnerKey key : session.requested.get(0)) { + Assert.assertFalse(Arrays.equals(key.getOwner(), IdGenerator.of(129).asBytes())); + } + int count = 1; + while (merged.hasNext()) { + Assert.assertEquals(IdGenerator.of(++count), merged.next().originId()); + } + Assert.assertEquals(130, count); + Assert.assertEquals(2, base.get(1).columnsSize()); // Legacy score must not also be merged as rank. + Assert.assertEquals(1, base.get(2).columnsSize()); + Assert.assertEquals(2, session.batchCalls); + Assert.assertEquals(2, session.batchCloses); + Assert.assertEquals(1, source.closes); + BackendColumn score = base.get(0).columns().stream() + .filter(column -> Arrays.equals(column.name, OlapKey.format(IdGenerator.of(9), IdGenerator.of(1)))) + .findFirst().get(); + Assert.assertArrayEquals(olapEntry(9, 1, 99).columns().iterator().next().value, score.value); + // The old row remains unchanged and has not been rewritten during reads. + Assert.assertArrayEquals(old.value, session.values.get(ByteBuffer.wrap(old.name))); + } + + @Test + public void testOlapMergeCapsTotalKeysForManyPropertiesAndRetainsLastChunkRows() throws Exception { + HstoreTables.OlapTable table = new HstoreTables.OlapTable("g"); + OlapSession session = new OlapSession(); + Set properties = manyOlapProperties(); + BackendColumn old = olapEntry(9999, 1, 42).columns().iterator().next(); + session.values.put(ByteBuffer.wrap(old.name), old.value); + table.insert(session, olapEntry(10000, 1, 99)); + EntrySource source = new EntrySource(List.of(vertexEntry(1), vertexEntry(2))); + Iterator merged = table.mergeEntries(session, source, properties, false); + BackendEntry first = merged.next(); + Assert.assertEquals(1, source.consumed); // Many properties reduce the selected vertex batch. + Assert.assertEquals(3, first.columnsSize()); + Assert.assertEquals(10, session.batchCalls); + Assert.assertEquals(10, session.batchCloses); + int oldRequests = 0; + for (List requested : session.requested) { + Assert.assertTrue(requested.size() <= 1024); + for (HgOwnerKey key : requested) { + Assert.assertArrayEquals(IdGenerator.of(1).asBytes(), key.getOwner()); + if (Arrays.equals(old.name, key.getKey())) { + oldRequests++; + } + } + } + Assert.assertEquals(1, oldRequests); + BinaryBackendEntry decoded = (BinaryBackendEntry) first; + Assert.assertArrayEquals(old.value, decoded.column( + OlapKey.format(IdGenerator.of(9999), IdGenerator.of(1))).value); + Assert.assertArrayEquals(olapEntry(10000, 1, 99).columns().iterator().next().value, + decoded.column(OlapKey.format(IdGenerator.of(10000), IdGenerator.of(1))).value); + ((AutoCloseable) merged).close(); + Assert.assertEquals(1, source.closes); + Assert.assertEquals(1, source.consumed); + } + + @Test + public void testOlapPropertyChunksCloseOnLaterBatchFailureWithoutReadingAhead() { + HstoreTables.OlapTable table = new HstoreTables.OlapTable("g"); + OlapSession session = new OlapSession(); + session.failBatchAt = 3; + EntrySource source = new EntrySource(List.of(vertexEntry(1), vertexEntry(2))); + Iterator merged = table.mergeEntries(session, source, manyOlapProperties(), true); + try { + merged.hasNext(); + Assert.fail("A later property chunk failure must propagate"); + } catch (IllegalStateException expected) { + Assert.assertEquals("batch failed", expected.getMessage()); + } + Assert.assertEquals(1, source.consumed); + Assert.assertEquals(1, source.closes); + Assert.assertEquals(3, session.batchCalls); + Assert.assertEquals(3, session.batchCloses); + for (List requested : session.requested) { + Assert.assertTrue(requested.size() <= 1024); + } + } + + private static Set manyOlapProperties() { + Set properties = new LinkedHashSet<>(); + for (int i = 1; i <= 10000; i++) { + properties.add(IdGenerator.of(i)); + } + return properties; + } + + @Test + public void testOlapMergePreservesPagingMetadataAndClosesOnEarlyCloseOrFailure() throws Exception { + HstoreTables.OlapTable table = new HstoreTables.OlapTable("g"); + OlapSession session = new OlapSession(); + EntrySource source = new EntrySource(List.of(vertexEntry(1), vertexEntry(2))); + Iterator merged = table.mergeEntries(session, source, Set.of(IdGenerator.of(9)), true); + Assert.assertEquals(IdGenerator.of(1), merged.next().originId()); + Assert.assertEquals(1, source.consumed); + Assert.assertEquals(1, ((CIter) merged).metadata("position")); + ((AutoCloseable) merged).close(); + Assert.assertEquals(1, source.closes); + Assert.assertEquals(1, session.batchCloses); + Assert.assertFalse(merged.hasNext()); + EntrySource failed = new EntrySource(List.of(vertexEntry(1))); + session.failBatch = true; + Iterator failure = table.mergeEntries(session, failed, Set.of(IdGenerator.of(9)), false); + try { + failure.hasNext(); + Assert.fail("Native batch failure must propagate"); + } catch (IllegalStateException expected) { + Assert.assertEquals("batch failed", expected.getMessage()); + } + Assert.assertEquals(1, failed.closes); + Assert.assertEquals(2, session.batchCloses); + EntrySource empty = new EntrySource(List.of(vertexEntry(1))); + Assert.assertSame(empty, table.mergeEntries(session, empty, Set.of(), false)); + Assert.assertSame(empty, table.mergeEntries(session, empty, null, false)); + Assert.assertEquals(2, session.batchCalls); + } + + private static BinaryBackendEntry vertexEntry(int vertex) { + BinaryBackendEntry entry = new BinaryBackendEntry(HugeType.VERTEX, + BytesBuffer.allocate(16).writeId(IdGenerator.of(vertex)).bytes()); + entry.column(entry.id().asBytes(), new byte[]{0}); + return entry; + } + + private static BinaryBackendEntry olapEntry(int property, int vertex, int value) { + HugeConfig config = new HugeConfig(Map.of()); + HugeGraph graph = (HugeGraph) Proxy.newProxyInstance(HugeGraph.class.getClassLoader(), + new Class[]{HugeGraph.class}, (proxy, method, args) -> { + if (method.getName().equals("option")) { + return ((ConfigOption) args[0]).defaultValue(); + } + if (method.getName().equals("configuration")) { + return config; + } + return null; + }); + PropertyKey key = new PropertyKey(graph, IdGenerator.of(property), "property" + property); + key.dataType(DataType.INT); + key.writeType(WriteType.OLAP_COMMON); + HugeVertex olap = new HugeVertex(graph, IdGenerator.of(vertex), VertexLabel.OLAP_VL); + olap.addProperty(key, value); + return (BinaryBackendEntry) new BinarySerializer(config).writeOlapVertex(olap); + } + + private static final class EntrySource implements CIter { + private final Iterator source; + private int consumed; + private int closes; + + private EntrySource(List entries) { + this.source = entries.iterator(); + } + + @Override + public boolean hasNext() { + return this.source.hasNext(); + } + + @Override + public BackendEntry next() { + this.consumed++; + return this.source.next(); + } + + @Override + public void close() { + this.closes++; + } + + @Override + public Object metadata(String meta, Object... args) { + return this.consumed; + } + } + + private static final class OlapSession extends ScanRecordingSession { + private final Map values = new HashMap<>(); + private final List owners = new ArrayList<>(); + private final List> requested = new ArrayList<>(); + private int batchCalls; + private int batchCloses; + private boolean failBatch; + private int failBatchAt; + + @Override + public void put(String table, byte[] owner, byte[] key, byte[] value) { + this.owners.add(owner); + this.values.put(ByteBuffer.wrap(key), value); + } + + @Override + public byte[] get(String table, byte[] owner, byte[] key) { + this.owners.add(owner); + return this.values.get(ByteBuffer.wrap(key)); + } + + @Override + public void delete(String table, byte[] owner, byte[] key) { + this.values.remove(ByteBuffer.wrap(key)); + } + + @Override + public BackendColumnIterator getWithBatchExact(String table, List keys) { + this.batchCalls++; + this.requested.add(keys); + Iterator result = keys.stream().filter(key -> + this.values.containsKey(ByteBuffer.wrap(key.getKey()))) + .map(key -> BackendColumn.of(key.getKey(), this.values.get(ByteBuffer.wrap(key.getKey())))) + .iterator(); + return new BackendColumnIterator() { + @Override + public boolean hasNext() { + if (failBatch || (failBatchAt > 0 && batchCalls == failBatchAt)) { + throw new IllegalStateException("batch failed"); + } + return result.hasNext(); + } + + @Override + public BackendColumn next() { + return result.next(); + } + + @Override + public byte[] position() { + return null; + } + + @Override + public void close() { + batchCloses++; + } + }; + } + } + private HstoreTable newTestTable() { HstoreTable table = new HstoreTable("hugegraph", "g+oe"); table.ownerByQueryDelegate = (type, id) -> new byte[]{0}; @@ -245,7 +604,7 @@ private static byte[] keyBytes(int key) { return bytes; } - private static final class ScanRecordingSession extends HstoreSessions.Session { + private static class ScanRecordingSession extends HstoreSessions.Session { private boolean scanCalled = false; private byte[] lastQueryBytes = null; diff --git a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/OpenedRocksDB.java b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/OpenedRocksDB.java index 2aa6d2292c..43d7cf393c 100644 --- a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/OpenedRocksDB.java +++ b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/OpenedRocksDB.java @@ -27,7 +27,7 @@ import java.util.concurrent.atomic.AtomicInteger; import org.apache.commons.io.FileUtils; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.backend.store.rocksdb.RocksDBIteratorPool.ReusedRocksIterator; import org.apache.hugegraph.util.E; import org.apache.hugegraph.util.Log; diff --git a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBIngester.java b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBIngester.java index 2d379b89ea..22913895c6 100644 --- a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBIngester.java +++ b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBIngester.java @@ -27,7 +27,7 @@ import java.util.ArrayList; import java.util.List; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.util.Log; import org.rocksdb.ColumnFamilyHandle; import org.rocksdb.IngestExternalFileOptions; diff --git a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBIteratorPool.java b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBIteratorPool.java index 66acdd5ec9..2923446357 100644 --- a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBIteratorPool.java +++ b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBIteratorPool.java @@ -20,7 +20,7 @@ import java.util.Queue; import java.util.concurrent.ArrayBlockingQueue; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.config.CoreOptions; import org.apache.hugegraph.util.Log; import org.apache.hugegraph.util.StringEncoding; diff --git a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBStdSessions.java b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBStdSessions.java index c1cc1c5075..467de5a273 100644 --- a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBStdSessions.java +++ b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBStdSessions.java @@ -32,9 +32,9 @@ import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.tuple.Pair; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.backend.serializer.BinarySerializer; -import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.backend.store.BackendEntry.BackendColumnIterator; import org.apache.hugegraph.backend.store.BackendEntryIterator; import org.apache.hugegraph.backend.store.rocksdb.RocksDBIteratorPool.ReusedRocksIterator; diff --git a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBStore.java b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBStore.java index 3b6b54eadb..eb7abcf6bc 100644 --- a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBStore.java +++ b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBStore.java @@ -44,10 +44,10 @@ import java.util.stream.Collectors; import org.apache.commons.io.FileUtils; -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.exception.HugeException; +import org.apache.hugegraph.exception.BackendException; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.serializer.MergeIterator; import org.apache.hugegraph.backend.store.AbstractBackendStore; import org.apache.hugegraph.backend.store.BackendAction; diff --git a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBTable.java b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBTable.java index 23e88def9b..b2082abe56 100644 --- a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBTable.java +++ b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBTable.java @@ -26,23 +26,23 @@ import java.util.Set; import org.apache.commons.lang3.tuple.Pair; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.page.PageState; -import org.apache.hugegraph.backend.query.Aggregate; -import org.apache.hugegraph.backend.query.Aggregate.AggregateFunc; -import org.apache.hugegraph.backend.query.Condition.Relation; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.IdPrefixQuery; -import org.apache.hugegraph.backend.query.IdRangeQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.Aggregate; +import org.apache.hugegraph.query.Aggregate.AggregateFunc; +import org.apache.hugegraph.query.Condition.Relation; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.IdPrefixQuery; +import org.apache.hugegraph.query.IdRangeQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.serializer.BinaryBackendEntry; import org.apache.hugegraph.backend.serializer.BinaryEntryIterator; import org.apache.hugegraph.backend.store.BackendEntry; -import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.backend.store.BackendEntry.BackendColumnIterator; import org.apache.hugegraph.backend.store.BackendEntryIterator; import org.apache.hugegraph.backend.store.BackendTable; -import org.apache.hugegraph.backend.store.Shard; +import org.apache.hugegraph.backend.Shard; import org.apache.hugegraph.backend.store.rocksdb.RocksDBSessions.Session; import org.apache.hugegraph.exception.NotSupportException; import org.apache.hugegraph.iterator.FlatMapperIterator; diff --git a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBTables.java b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBTables.java index becb685c58..74a52fef39 100644 --- a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBTables.java +++ b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBTables.java @@ -22,10 +22,11 @@ import java.util.Collection; import java.util.List; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.Condition.Relation; -import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.backend.BackendColumn; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.Condition.Relation; +import org.apache.hugegraph.query.ConditionQuery; import org.apache.hugegraph.backend.serializer.BinarySerializer; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.backend.store.BackendEntry.BackendColumnIterator; @@ -234,7 +235,7 @@ public void delete(RocksDBSessions.Session session, BackendEntry entry) { * Only delete index by label will come here * Regular index delete will call eliminate() */ - for (BackendEntry.BackendColumn column : entry.columns()) { + for (BackendColumn column : entry.columns()) { // Don't assert entry.belongToMe(column), length-prefix is 1* session.deletePrefix(this.table(), column.name); } diff --git a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdbsst/RocksDBSstSessions.java b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdbsst/RocksDBSstSessions.java index b85ae5312b..052ab55387 100644 --- a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdbsst/RocksDBSstSessions.java +++ b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdbsst/RocksDBSstSessions.java @@ -31,7 +31,7 @@ import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.tuple.Pair; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.backend.store.BackendEntry.BackendColumnIterator; import org.apache.hugegraph.backend.store.rocksdb.RocksDBIngester; import org.apache.hugegraph.backend.store.rocksdb.RocksDBSessions; diff --git a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdbsst/RocksDBSstStore.java b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdbsst/RocksDBSstStore.java index d7b75610f1..0e33cb3e50 100644 --- a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdbsst/RocksDBSstStore.java +++ b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdbsst/RocksDBSstStore.java @@ -19,7 +19,7 @@ import java.util.List; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.backend.store.BackendStoreProvider; import org.apache.hugegraph.backend.store.rocksdb.RocksDBSessions; import org.apache.hugegraph.backend.store.rocksdb.RocksDBStore; diff --git a/hugegraph-server/hugegraph-test/pom.xml b/hugegraph-server/hugegraph-test/pom.xml index a411a06b9c..8627174dd9 100644 --- a/hugegraph-server/hugegraph-test/pom.xml +++ b/hugegraph-server/hugegraph-test/pom.xml @@ -277,6 +277,8 @@ microbenchmarks + + false diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/BaseApiTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/BaseApiTest.java index abe4b6839c..92f9fba3e9 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/BaseApiTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/BaseApiTest.java @@ -29,7 +29,7 @@ import java.util.stream.Collectors; import org.apache.http.util.TextUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.util.CollectionUtil; import org.apache.hugegraph.util.JsonUtil; import org.apache.tinkerpop.shaded.jackson.core.type.TypeReference; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/auth/GraphSpaceAuthPayloadTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/auth/GraphSpaceAuthPayloadTest.java index 6333dbb44a..ca7ec157aa 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/auth/GraphSpaceAuthPayloadTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/auth/GraphSpaceAuthPayloadTest.java @@ -27,7 +27,7 @@ import org.apache.hugegraph.auth.HugeGroup; import org.apache.hugegraph.auth.HugePermission; import org.apache.hugegraph.auth.HugeTarget; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.testutil.Assert; import org.junit.Test; import org.mockito.Mockito; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/cypher/CypherClientTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/cypher/CypherClientTest.java index d9d36638d5..04b94cd99b 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/cypher/CypherClientTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/cypher/CypherClientTest.java @@ -22,7 +22,7 @@ import java.util.Map; import java.util.Set; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.unit.BaseUnitTest; import org.apache.tinkerpop.gremlin.process.traversal.Path; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/auth/StandardAuthManagerV2Test.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/auth/StandardAuthManagerV2Test.java index 1b05e4ee24..5d77bd25a0 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/auth/StandardAuthManagerV2Test.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/auth/StandardAuthManagerV2Test.java @@ -20,8 +20,8 @@ import java.util.Arrays; import java.util.Collections; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.testutil.Assert; import org.junit.Test; import org.mockito.Mockito; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/backend/page/QueryListTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/backend/page/QueryListTest.java index 7fc020889b..7d49c15dc9 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/backend/page/QueryListTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/backend/page/QueryListTest.java @@ -24,13 +24,13 @@ import java.util.List; import java.util.Set; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.page.IdHolder.BatchIdHolder; import org.apache.hugegraph.backend.page.IdHolder.FixedIdHolder; import org.apache.hugegraph.backend.page.IdHolder.PagingIdHolder; -import org.apache.hugegraph.backend.query.ConditionQuery.OptimizedType; -import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.query.ConditionQuery.OptimizedType; +import org.apache.hugegraph.query.ConditionQuery; import org.apache.hugegraph.backend.query.QueryBatch; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.backend.serializer.TextBackendEntry; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/backend/tx/GraphIndexTransactionTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/backend/tx/GraphIndexTransactionTest.java index 65940d3e3a..ed945554ac 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/backend/tx/GraphIndexTransactionTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/backend/tx/GraphIndexTransactionTest.java @@ -17,12 +17,43 @@ package org.apache.hugegraph.backend.tx; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.Query; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Consumer; + +import org.apache.hugegraph.HugeGraph; +import org.apache.hugegraph.HugeGraphParams; +import org.apache.hugegraph.analyzer.Analyzer; +import org.apache.hugegraph.backend.serializer.AbstractSerializer; +import org.apache.hugegraph.backend.store.BackendEntry; +import org.apache.hugegraph.backend.store.BackendStore; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.Query; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; +import org.apache.hugegraph.structure.HugeVertex; +import org.apache.hugegraph.structure.HugeEdge; +import org.apache.hugegraph.structure.Index; +import org.apache.hugegraph.structure.builder.IndexBuilder; import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.FakeObjects; import org.apache.hugegraph.type.HugeType; +import org.apache.hugegraph.type.define.Cardinality; +import org.apache.hugegraph.type.define.DataType; +import org.apache.hugegraph.type.define.IdStrategy; import org.apache.hugegraph.type.define.IndexType; +import org.apache.hugegraph.type.define.Directions; +import org.apache.hugegraph.type.define.EdgeLabelType; +import org.apache.hugegraph.type.define.Frequency; +import org.apache.hugegraph.type.define.WriteType; import org.junit.Test; +import org.mockito.Mockito; public class GraphIndexTransactionTest { @@ -46,4 +77,177 @@ public void testKeepBackendIndexOrderOnlyForOrderedHstoreRangeQuery() { Assert.assertTrue(GraphIndexTransaction.keepBackendIndexOrder( true, IndexType.RANGE_INT, query)); } + + @Test + public void testEngineTransactionAndStoreBuilderShareExpansionForEveryIndexKind() { + FakeObjects objects = new FakeObjects(); + HugeGraph graph = objects.graph(); + PropertyKey text = objects.newPropertyKey(IdGenerator.of(1), "text", DataType.TEXT); + PropertyKey number = objects.newPropertyKey(IdGenerator.of(2), "number", DataType.INT); + VertexLabel vertexLabel = objects.newVertexLabel(IdGenerator.of(4), "vertex", + IdStrategy.CUSTOMIZE_NUMBER, text.id(), number.id()); + HugeVertex vertex = new HugeVertex(graph, IdGenerator.of(1), vertexLabel); + vertex.addProperty(text, "alpha beta"); + vertex.addProperty(number, 7); + vertex.expiredTime(123L); + Analyzer analyzer = value -> Set.of("alpha", "beta"); + int value = 10; + for (IndexType type : List.of(IndexType.SECONDARY, IndexType.SEARCH, IndexType.SHARD, + IndexType.UNIQUE, IndexType.RANGE_INT, IndexType.RANGE_FLOAT, + IndexType.RANGE_LONG, IndexType.RANGE_DOUBLE)) { + PropertyKey field = type.isRange() ? number : text; + IndexLabel label = objects.newIndexLabel(IdGenerator.of(value++), type.name(), + HugeType.VERTEX_LABEL, vertexLabel.id(), type, field.id()); + List expected = new IndexBuilder(graph, analyzer).buildIndex(vertex.element(), label); + List actual = captureEngineExpansion(objects, vertex, label, analyzer); + Assert.assertEquals(type.name(), expected.size(), actual.size()); + for (int i = 0; i < expected.size(); i++) { + Assert.assertEquals(type.name(), expected.get(i).fieldValues(), actual.get(i).fieldValues()); + Assert.assertEquals(vertex.id(), actual.get(i).elementId()); + Assert.assertEquals(123L, actual.get(i).expiredTime()); + } + if (type == IndexType.SEARCH) { + Set values = new HashSet<>(); + actual.forEach(index -> values.add(index.fieldValues())); + Assert.assertEquals(Set.of("alpha", "beta", "alpha beta"), values); + } + } + } + + @Test + public void testEngineNullableCompositePrefixAndCollectionExpansionRemainUnloaded() { + FakeObjects objects = new FakeObjects(); + PropertyKey first = objects.newPropertyKey(IdGenerator.of(1), "first", DataType.TEXT); + PropertyKey missing = objects.newPropertyKey(IdGenerator.of(2), "missing", DataType.TEXT); + PropertyKey last = objects.newPropertyKey(IdGenerator.of(3), "last", DataType.TEXT); + VertexLabel label = objects.newVertexLabel(IdGenerator.of(4), "vertex", IdStrategy.CUSTOMIZE_NUMBER, + first.id(), missing.id(), last.id()); + label.nullableKeys(missing.id()); + HugeVertex vertex = new HugeVertex(objects.graph(), IdGenerator.of(1), label); + vertex.addProperty(first, "first"); + vertex.addProperty(last, "last"); + vertex.propNotLoaded(); + IndexLabel index = objects.newIndexLabel(IdGenerator.of(5), "composite", HugeType.VERTEX_LABEL, + label.id(), IndexType.SECONDARY, + first.id(), missing.id(), last.id()); + List actual = captureEngineExpansion(objects, vertex, index, text -> Set.of(text)); + Assert.assertEquals(1, actual.size()); + Assert.assertEquals("first", actual.get(0).fieldValues()); + Assert.assertFalse(vertex.isPropLoaded()); + + PropertyKey list = objects.newPropertyKey(IdGenerator.of(6), "list", DataType.INT, Cardinality.LIST); + label.properties(list.id()); + vertex.addProperty(list, List.of(7, -1, 7)); + IndexLabel collection = objects.newIndexLabel(IdGenerator.of(7), "collection", HugeType.VERTEX_LABEL, + label.id(), IndexType.SECONDARY, list.id()); + actual = captureEngineExpansion(objects, vertex, collection, text -> Set.of(text)); + Assert.assertEquals(3, actual.size()); + Assert.assertEquals(actual.get(0).fieldValues(), actual.get(2).fieldValues()); + } + + @Test + public void testEngineAndStoreSelectInheritedEdgeIndexesThroughSharedHelper() { + FakeObjects objects = new FakeObjects(); + PropertyKey inherited = objects.newPropertyKey(IdGenerator.of(1), "inherited", DataType.TEXT); + PropertyKey own = objects.newPropertyKey(IdGenerator.of(2), "own", DataType.TEXT); + EdgeLabel parent = objects.newEdgeLabel(IdGenerator.of(3), "parent", Frequency.MULTIPLE, + IdGenerator.of(5), IdGenerator.of(5), inherited.id()); + EdgeLabel child = objects.newEdgeLabel(IdGenerator.of(4), "child", Frequency.MULTIPLE, + IdGenerator.of(5), IdGenerator.of(5), inherited.id(), own.id()); + child.edgeLabelType(EdgeLabelType.SUB); + child.fatherId(parent.id()); + parent.enableLabelIndex(false); + child.enableLabelIndex(false); + IndexLabel parentIndex = objects.newIndexLabel(IdGenerator.of(11), "parentIndex", HugeType.EDGE_LABEL, + parent.id(), IndexType.SECONDARY, inherited.id()); + IndexLabel childIndex = objects.newIndexLabel(IdGenerator.of(12), "childIndex", HugeType.EDGE_LABEL, + child.id(), IndexType.SECONDARY, own.id()); + parent.indexLabels(parentIndex.id()); + child.indexLabels(childIndex.id()); + HugeEdge edge = new HugeEdge(objects.graph(), new EdgeId(IdGenerator.of(1), Directions.OUT, + parent.id(), child.id(), "", IdGenerator.of(2)), child); + edge.addProperty(inherited, "parent value"); + edge.addProperty(own, "child value"); + Analyzer analyzer = text -> Set.of(text); + List store = new IndexBuilder(objects.graph(), analyzer).buildEdgeIndex(edge.element()); + List engine = captureEngineIndexes(objects, List.of(parentIndex, childIndex), analyzer, + tx -> tx.updateEdgeIndex(edge, true)); + Assert.assertEquals(2, engine.size()); + Assert.assertEquals(childIndex.id(), engine.get(0).indexLabelId()); + Assert.assertEquals(parentIndex.id(), engine.get(1).indexLabelId()); + for (int i = 0; i < engine.size(); i++) { + Assert.assertEquals(store.get(i).indexLabelId(), engine.get(i).indexLabelId()); + Assert.assertEquals(store.get(i).fieldValues(), engine.get(i).fieldValues()); + } + } + + @Test + public void testEngineOlapAdapterSelectsTransactionCandidatesAndPreservesSingletonGuard() { + FakeObjects objects = new FakeObjects(); + PropertyKey property = objects.newPropertyKey(IdGenerator.of(1), "olap", DataType.INT); + property.writeType(WriteType.OLAP_COMMON); + PropertyKey unrelated = objects.newPropertyKey(IdGenerator.of(2), "other", DataType.INT); + HugeVertex vertex = new HugeVertex(objects.graph(), IdGenerator.of(1), VertexLabel.OLAP_VL); + vertex.addProperty(property, 42); + IndexLabel selected = objects.newIndexLabel(IdGenerator.of(11), "selected", HugeType.VERTEX_LABEL, + VertexLabel.OLAP_VL.id(), IndexType.RANGE_INT, property.id()); + IndexLabel other = objects.newIndexLabel(IdGenerator.of(12), "other", HugeType.VERTEX_LABEL, + VertexLabel.OLAP_VL.id(), IndexType.RANGE_INT, unrelated.id()); + List actual = captureEngineIndexes(objects, List.of(other, selected), text -> Set.of(text), + tx -> tx.updateVertexIndex(vertex, true)); + Assert.assertEquals(1, actual.size()); + Assert.assertEquals(selected.id(), actual.get(0).indexLabelId()); + Assert.assertEquals(42, actual.get(0).fieldValues()); + for (HugeVertex malformed : List.of(new HugeVertex(objects.graph(), IdGenerator.of(2), VertexLabel.OLAP_VL), + new HugeVertex(objects.graph(), IdGenerator.of(3), VertexLabel.OLAP_VL))) { + if (malformed.id().equals(IdGenerator.of(3))) { + malformed.addProperty(property, 42); + malformed.addProperty(unrelated, 43); + } + try { + captureEngineIndexes(objects, List.of(selected), text -> Set.of(text), + tx -> tx.updateVertexIndex(malformed, true)); + Assert.fail("Malformed olap vertex must fail the shared singleton guard"); + } catch (IllegalArgumentException expected) { + Assert.assertTrue(expected.getMessage().contains("Expect only 1 property")); + } + } + } + + private static List captureEngineExpansion(FakeObjects objects, HugeVertex vertex, + IndexLabel label, Analyzer analyzer) { + return captureEngineIndexes(objects, List.of(label), analyzer, + tx -> tx.updateIndex(label.id(), vertex, true)); + } + + private static List captureEngineIndexes(FakeObjects objects, List labels, + Analyzer analyzer, Consumer action) { + HugeGraphParams params = Mockito.mock(HugeGraphParams.class); + ISchemaTransaction schema = Mockito.mock(ISchemaTransaction.class); + AbstractSerializer serializer = Mockito.mock(AbstractSerializer.class); + BackendStore store = Mockito.mock(BackendStore.class); + Mockito.when(params.graph()).thenReturn(objects.graph()); + Mockito.doReturn(objects.graph().configuration()).when(params).configuration(); + Mockito.when(params.serializer()).thenReturn(serializer); + Mockito.when(params.schemaTransaction()).thenReturn(schema); + Mockito.when(schema.getIndexLabels()).thenReturn(labels); + Mockito.when(params.analyzer()).thenReturn(analyzer); + for (IndexLabel label : labels) { + Mockito.when(schema.getIndexLabel(label.id())).thenReturn(label); + } + List indexes = new ArrayList<>(); + Mockito.when(serializer.writeIndex(Mockito.any(Index.class))).thenAnswer(call -> { + indexes.add(call.getArgument(0)); + return Mockito.mock(BackendEntry.class); + }); + GraphIndexTransaction tx = new GraphIndexTransaction(params, store) { + @Override + public void doEliminate(BackendEntry entry) { + // Capture pure expansion without touching a real backend. + } + }; + action.accept(tx); + return indexes; + } + } diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/backend/tx/GraphTransactionTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/backend/tx/GraphTransactionTest.java index 3cb79e3687..a41ee5ffc0 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/backend/tx/GraphTransactionTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/backend/tx/GraphTransactionTest.java @@ -26,16 +26,16 @@ import org.apache.hugegraph.HugeGraphParams; import org.apache.hugegraph.backend.cache.Cache; import org.apache.hugegraph.backend.cache.CachedGraphTransaction; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.ConditionQuery.OptimizedType; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.IdQuery; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery.OptimizedType; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.IdQuery; import org.apache.hugegraph.backend.query.QueryResultContext; import org.apache.hugegraph.backend.tx.GraphIndexTransaction.RemoveLeftIndexJob; import org.apache.hugegraph.job.EphemeralJob; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.testutil.Whitebox; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/AuthTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/AuthTest.java index aa4ac8cce7..12afccd1f8 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/AuthTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/AuthTest.java @@ -27,9 +27,10 @@ import javax.security.sasl.AuthenticationException; import org.apache.commons.collections.CollectionUtils; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.HugeGraphParams; +import org.apache.hugegraph.auth.AuthConstant; import org.apache.hugegraph.auth.AuthManager; import org.apache.hugegraph.auth.HugeAccess; import org.apache.hugegraph.auth.HugeBelong; @@ -41,11 +42,12 @@ import org.apache.hugegraph.auth.HugeUser; import org.apache.hugegraph.auth.RolePermission; import org.apache.hugegraph.auth.StandardAuthManager; +import org.apache.hugegraph.auth.TokenGenerator; import org.apache.hugegraph.auth.UserWithRole; import org.apache.hugegraph.backend.cache.Cache; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.testutil.Whitebox; import org.apache.hugegraph.util.JsonUtil; @@ -1667,6 +1669,25 @@ public void testValidateUserByToken() throws AuthenticationException { Assert.assertNull(userWithRole.role()); } + @Test + public void testRejectInvalidAndExpiredTokens() { + AuthManager authManager = graph().authManager(); + TokenGenerator generator = Whitebox.getInternalState(authManager, + "tokenGenerator"); + Map claims = ImmutableMap.of(AuthConstant.TOKEN_USER_NAME, + "test"); + String expired = generator.create(claims, -60000L); + String wrongKey = new TokenGenerator("abcdefghijklmnopqrstuvwxyz012345") + .create(claims, 60000L); + + for (String token : ImmutableList.of(expired, wrongKey, "123.ansfaf")) { + UserWithRole rejected = authManager.validateUser(token); + Assert.assertEquals("", rejected.username()); + Assert.assertNull(rejected.userId()); + Assert.assertNull(rejected.role()); + } + } + @Test public void testLogout() throws AuthenticationException { AuthManager authManager = graph().authManager(); diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/BaseCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/BaseCoreTest.java index 701065fe44..ab84a393d6 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/BaseCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/BaseCoreTest.java @@ -24,7 +24,7 @@ import org.apache.hugegraph.HugeGraphParams; import org.apache.hugegraph.backend.cache.CacheManager; import org.apache.hugegraph.backend.store.BackendFeatures; -import org.apache.hugegraph.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; import org.apache.hugegraph.schema.SchemaManager; import org.apache.hugegraph.testutil.Whitebox; import org.apache.hugegraph.util.Log; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/CountStrategyCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/CountStrategyCoreTest.java index 4ebb39dd06..273688a5c4 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/CountStrategyCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/CountStrategyCoreTest.java @@ -30,12 +30,12 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.backend.query.Aggregate; -import org.apache.hugegraph.backend.query.Aggregate.AggregateFunc; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.exception.HugeException; +import org.apache.hugegraph.query.Aggregate; +import org.apache.hugegraph.query.Aggregate.AggregateFunc; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.tx.GraphTransaction; import org.apache.hugegraph.exception.NoIndexException; import org.apache.hugegraph.schema.SchemaManager; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java index 9ea6b0e919..d626df4a1a 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java @@ -30,24 +30,24 @@ import java.util.concurrent.ExecutionException; import java.util.function.Function; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.BackendException; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.exception.BackendException; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.page.PageInfo; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.Query; -import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.Query; +import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.backend.store.BackendTable; -import org.apache.hugegraph.backend.store.Shard; +import org.apache.hugegraph.backend.Shard; import org.apache.hugegraph.backend.tx.GraphTransaction; import org.apache.hugegraph.config.CoreOptions; import org.apache.hugegraph.exception.LimitExceedException; import org.apache.hugegraph.exception.NoIndexException; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.Userdata; +import org.apache.hugegraph.struct.schema.Userdata; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.testutil.Assert; @@ -3176,9 +3176,7 @@ public void testQueryAdjacentVerticesOfEdges() { // Fill edge properties Assert.assertEquals(2, edge.getProperties().size()); - Whitebox.setInternalState(edge, "propLoaded", false); - Whitebox.setInternalState(edge, "properties", - CollectionFactory.newIntObjectMap()); + edge.resetProperties(); Assert.assertEquals(0, edge.getProperties().size()); Assert.assertEquals(2, edge.getFilledProperties().size()); Assert.assertEquals(2, edge.getProperties().size()); diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeLabelCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeLabelCoreTest.java index 8629f78b3e..f490641f7c 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeLabelCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeLabelCoreTest.java @@ -20,15 +20,15 @@ import java.util.Date; import java.util.List; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.exception.ExistedException; import org.apache.hugegraph.exception.NoIndexException; import org.apache.hugegraph.exception.NotFoundException; -import org.apache.hugegraph.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.Userdata; +import org.apache.hugegraph.struct.schema.Userdata; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.type.define.Frequency; import org.apache.hugegraph.util.DateUtil; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/IndexLabelCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/IndexLabelCoreTest.java index 24a905427c..c9988db513 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/IndexLabelCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/IndexLabelCoreTest.java @@ -20,16 +20,16 @@ import java.util.Date; import java.util.List; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.exception.ExistedException; import org.apache.hugegraph.exception.NoIndexException; import org.apache.hugegraph.exception.NotFoundException; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.Userdata; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.Userdata; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.IndexType; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/MultiGraphsTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/MultiGraphsTest.java index bb45b47e3b..1064d3a0fd 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/MultiGraphsTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/MultiGraphsTest.java @@ -26,19 +26,19 @@ import org.apache.commons.configuration2.BaseConfiguration; import org.apache.commons.configuration2.Configuration; import org.apache.commons.configuration2.PropertiesConfiguration; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.store.BackendStoreInfo; import org.apache.hugegraph.backend.store.rocksdb.RocksDBOptions; import org.apache.hugegraph.config.CoreOptions; import org.apache.hugegraph.exception.ExistedException; import org.apache.hugegraph.masterelection.GlobalMasterInfo; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.testutil.Utils; import org.apache.tinkerpop.gremlin.structure.T; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/ParentAndSubEdgeCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/ParentAndSubEdgeCoreTest.java index 4d7cc3eea3..b657b62c57 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/ParentAndSubEdgeCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/ParentAndSubEdgeCoreTest.java @@ -21,7 +21,7 @@ import java.util.List; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; import org.apache.hugegraph.schema.SchemaManager; import org.apache.hugegraph.testutil.Assert; import org.apache.tinkerpop.gremlin.structure.Edge; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/PropertyCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/PropertyCoreTest.java index 873efd5e84..755380fc8b 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/PropertyCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/PropertyCoreTest.java @@ -26,7 +26,7 @@ import java.util.UUID; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.schema.SchemaManager; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.testutil.Utils; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/PropertyKeyCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/PropertyKeyCoreTest.java index 0609f607ba..240b4d86f7 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/PropertyKeyCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/PropertyKeyCoreTest.java @@ -19,13 +19,13 @@ import java.util.Date; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.exception.ExistedException; import org.apache.hugegraph.exception.NotAllowException; import org.apache.hugegraph.exception.NotFoundException; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.Userdata; +import org.apache.hugegraph.struct.schema.Userdata; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.type.define.AggregateType; import org.apache.hugegraph.type.define.Cardinality; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/RamTableTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/RamTableTest.java index 8a1f6c4910..359505d945 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/RamTableTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/RamTableTest.java @@ -24,9 +24,9 @@ import org.apache.commons.io.FileUtils; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.store.ram.RamTable; import org.apache.hugegraph.backend.tx.GraphTransaction; import org.apache.hugegraph.schema.SchemaManager; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/SchemaCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/SchemaCoreTest.java index 0d70bb203b..b459224706 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/SchemaCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/SchemaCoreTest.java @@ -22,12 +22,12 @@ import java.util.List; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.testutil.Assert; import org.apache.tinkerpop.gremlin.structure.T; import org.apache.tinkerpop.gremlin.structure.Vertex; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/TaskCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/TaskCoreTest.java index 9e82692689..0622630ecc 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/TaskCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/TaskCoreTest.java @@ -28,11 +28,11 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.api.job.GremlinAPI.GremlinRequest; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.exception.NotFoundException; import org.apache.hugegraph.job.EphemeralJob; import org.apache.hugegraph.job.EphemeralJobBuilder; @@ -1023,24 +1023,34 @@ public void testGremlinJobAndRestore() throws Exception { HugeGraph graph = graph(); TaskScheduler scheduler = graph.taskScheduler(); - String gremlin = "println('task start');" + + BlockingCallable.reset(); + String gremlin = "import org.apache.hugegraph.core.TaskCoreTest.BlockingCallable;" + + "println('task start');" + "for(int i=gremlinJob.progress(); i<=10; i++) {" + " gremlinJob.updateProgress(i);" + + " if (i == 1) BlockingCallable.pause();" + " Thread.sleep(200); " + " println('sleep=>'+i);" + "}; 100;"; HugeTask task = runGremlinJob(gremlin); - sleepAWhile(200 * 6); - task = scheduler.task(task.id()); - scheduler.cancel(task); - - task = scheduler.task(task.id()); - Assert.assertTrue("Task status should be CANCELLING or CANCELLED, but was " + task.status(), - task.status() == TaskStatus.CANCELLING || - task.status() == TaskStatus.CANCELLED); - - task = scheduler.waitUntilTaskCompleted(task.id(), 10); + try { + // RUNNING is set before script evaluation; wait for real progress. + Assert.assertTrue("Gremlin task did not reach progress 1", + BlockingCallable.awaitStarted()); + task = scheduler.task(task.id()); + scheduler.cancel(task); + + task = scheduler.task(task.id()); + Assert.assertTrue("Task status should be CANCELLING or CANCELLED, but was " + task.status(), + task.status() == TaskStatus.CANCELLING || + task.status() == TaskStatus.CANCELLED); + + task = scheduler.waitUntilTaskCompleted(task.id(), 10); + } finally { + // Restored execution can pass the progress barrier and finish. + BlockingCallable.release(); + } Assert.assertEquals(TaskStatus.CANCELLED, task.status()); Assert.assertTrue("progress=" + task.progress(), 0 < task.progress() && task.progress() < 10); @@ -1145,6 +1155,13 @@ public static void release() { release.countDown(); } + public static void pause() throws InterruptedException, TimeoutException { + started.countDown(); + if (!release.await(30L, TimeUnit.SECONDS)) { + throw new TimeoutException("Timed out waiting for task cancellation"); + } + } + @Override public V call() throws Exception { started.countDown(); diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/VertexCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/VertexCoreTest.java index 16cc7d0c83..b6657ae150 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/VertexCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/VertexCoreTest.java @@ -33,30 +33,30 @@ import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.backend.cache.CachedGraphTransaction; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.Id.IdType; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.Id.IdType; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.id.SnowflakeIdGenerator; -import org.apache.hugegraph.backend.id.SplicingIdGenerator; +import org.apache.hugegraph.id.SplicingIdGenerator; import org.apache.hugegraph.backend.page.PageInfo; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.Query; -import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.Query; +import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.backend.store.BackendTable; -import org.apache.hugegraph.backend.store.Shard; +import org.apache.hugegraph.backend.Shard; import org.apache.hugegraph.backend.tx.GraphTransaction; import org.apache.hugegraph.exception.LimitExceedException; import org.apache.hugegraph.exception.NoIndexException; import org.apache.hugegraph.exception.NotAllowException; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.Userdata; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.Userdata; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeElement; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.testutil.FakeObjects; @@ -7872,7 +7872,7 @@ public void testScanVertexInPaging() { Iterator iterator = graph.vertices(query); while (iterator.hasNext()) { Vertex vertex = iterator.next(); - Assert.assertTrue(query.test((HugeElement) vertex)); + Assert.assertTrue(query.test(((HugeElement) vertex).element())); vertices.add(vertex); } page = PageInfo.pageInfo(iterator); diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/VertexLabelCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/VertexLabelCoreTest.java index a43731f235..e25c0aa0d4 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/VertexLabelCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/VertexLabelCoreTest.java @@ -20,16 +20,16 @@ import java.util.Date; import java.util.List; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.exception.ExistedException; import org.apache.hugegraph.exception.NoIndexException; import org.apache.hugegraph.exception.NotFoundException; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.Userdata; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.Userdata; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.task.HugeTask; import org.apache.hugegraph.task.TaskScheduler; import org.apache.hugegraph.task.TaskStatus; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/memory/MemoryConsumerTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/memory/MemoryConsumerTest.java index b3a83d0e50..a059ce5848 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/memory/MemoryConsumerTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/memory/MemoryConsumerTest.java @@ -26,11 +26,11 @@ import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.StandardHugeGraph; import org.apache.hugegraph.backend.cache.CachedBackendStore; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.query.Query; -import org.apache.hugegraph.backend.serializer.BinaryBackendEntry; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.query.Query; +import org.apache.hugegraph.backend.BinaryId; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.dist.RegisterUtil; import org.apache.hugegraph.masterelection.GlobalMasterInfo; @@ -38,8 +38,8 @@ import org.apache.hugegraph.memory.consumer.factory.IdFactory; import org.apache.hugegraph.memory.consumer.factory.PropertyFactory; import org.apache.hugegraph.memory.consumer.impl.id.StringIdOffHeap; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.schema.SchemaManager; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeEdgeProperty; @@ -143,7 +143,7 @@ public void testBinaryId() { Id stringIdOffHeap = IdFactory.getInstance().newStringId("java"); Id idOffHeap = IdFactory.getInstance().newBinaryId(stringIdOffHeap.asBytes(), stringIdOffHeap); - Id id = new BinaryBackendEntry.BinaryId(stringIdOffHeap.asBytes(), stringIdOffHeap); + Id id = new BinaryId(stringIdOffHeap.asBytes(), stringIdOffHeap); Assert.assertNotNull(idOffHeap); Assert.assertArrayEquals(stringIdOffHeap.asBytes(), idOffHeap.asBytes()); Assert.assertEquals(id, ((OffHeapObject) idOffHeap).zeroCopyReadFromByteBuf()); @@ -180,20 +180,49 @@ public void testEdgeId() { Id edgeLabelIdOffHeap = IdFactory.getInstance().newLongId(1); Id subLabelIdOffHeap = IdFactory.getInstance().newLongId(2); Id edgeIdOffHeap = - IdFactory.getInstance().newEdgeId(java, Directions.OUT, edgeLabelIdOffHeap, + IdFactory.getInstance().newEdgeId(java.id(), Directions.OUT, edgeLabelIdOffHeap, subLabelIdOffHeap, - "test", java); - Id edgeId = new EdgeId(java, + "test", java.id()); + Id edgeId = new EdgeId(java.id(), Directions.OUT, (Id) ((OffHeapObject) edgeLabelIdOffHeap).zeroCopyReadFromByteBuf(), (Id) ((OffHeapObject) subLabelIdOffHeap).zeroCopyReadFromByteBuf(), "test", - java); + java.id()); Assert.assertNotNull(edgeIdOffHeap); // TODO: adopt equals method Assert.assertEquals(edgeId.asString(), edgeIdOffHeap.asString()); } + @Test + public void testEdgeIdFormattingUsesSharedComponentsAndCache() { + Id owner = IdFactory.getInstance().newStringId("owner>vertex"); + Id other = IdFactory.getInstance().newStringId("other`vertex"); + Id label = IdFactory.getInstance().newLongId(1); + Id subLabel = IdFactory.getInstance().newLongId(2); + String[] sortValues = {"value", "a>b`c!d:北京"}; + for (Directions direction : new Directions[]{Directions.OUT, Directions.IN}) { + for (boolean directed : new boolean[]{false, true}) { + for (String sortValue : sortValues) { + EdgeId offHeap = IdFactory.getInstance().newEdgeId( + owner, direction, label, subLabel, sortValue, other, directed); + EdgeId onHeap = new EdgeId(IdGenerator.of("owner>vertex"), direction, + IdGenerator.of(1), IdGenerator.of(2), sortValue, + IdGenerator.of("other`vertex"), directed); + OffHeapObject consumer = (OffHeapObject) offHeap; + int memoryBlocks = consumer.getAllMemoryBlock().size(); + String formatted = offHeap.asString(); + Assert.assertEquals(onHeap.asString(), formatted); + Assert.assertEquals(memoryBlocks + 1, consumer.getAllMemoryBlock().size()); + Assert.assertEquals(formatted, offHeap.asString()); + Assert.assertEquals(memoryBlocks + 1, consumer.getAllMemoryBlock().size()); + Assert.assertArrayEquals(onHeap.asBytes(), offHeap.asBytes()); + Assert.assertEquals(sortValue, offHeap.sortValues()); + } + } + } + } + @Test public void testProperty() { Id stringIdOffHeap = IdFactory.getInstance().newStringId("java"); @@ -201,12 +230,12 @@ public void testProperty() { Id edgeLabelIdOffHeap = IdFactory.getInstance().newLongId(1); Id subLabelIdOffHeap = IdFactory.getInstance().newLongId(2); - Id edgeId = new EdgeId(java, + Id edgeId = new EdgeId(java.id(), Directions.OUT, (Id) ((OffHeapObject) edgeLabelIdOffHeap).zeroCopyReadFromByteBuf(), (Id) ((OffHeapObject) subLabelIdOffHeap).zeroCopyReadFromByteBuf(), "test", - java); + java.id()); HugeEdge testEdge = new HugeEdge(graph, edgeId, EdgeLabel.NONE); PropertyKey propertyKey = new PropertyKey(null, IdFactory.getInstance().newLongId(3), "fake"); diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/meta/managers/AuthMetaManagerTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/meta/managers/AuthMetaManagerTest.java index 074753308e..32115c050d 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/meta/managers/AuthMetaManagerTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/meta/managers/AuthMetaManagerTest.java @@ -20,7 +20,7 @@ import java.util.Map; import org.apache.hugegraph.auth.HugeTarget; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.meta.MetaDriver; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.util.JsonUtil; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/task/TaskAndResultSchedulerTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/task/TaskAndResultSchedulerTest.java index a31c70e8d1..d45b6f5137 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/task/TaskAndResultSchedulerTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/task/TaskAndResultSchedulerTest.java @@ -24,10 +24,10 @@ import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.atomic.AtomicInteger; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.core.BaseCoreTest; import org.apache.hugegraph.structure.HugeVertex; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/testutil/Utils.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/testutil/Utils.java index e081423b8e..5fd9928561 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/testutil/Utils.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/testutil/Utils.java @@ -24,10 +24,10 @@ import org.apache.commons.configuration2.PropertiesConfiguration; import org.apache.commons.configuration2.builder.fluent.Configurations; import org.apache.commons.configuration2.ex.ConfigurationException; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeFactory; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.util.DateUtil; import org.apache.hugegraph.util.E; import org.apache.tinkerpop.gremlin.structure.Edge; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/HugeGraphTestInfrastructureTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/HugeGraphTestInfrastructureTest.java index efe2d5fba2..070bcae9a1 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/HugeGraphTestInfrastructureTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/HugeGraphTestInfrastructureTest.java @@ -23,9 +23,9 @@ import java.util.List; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.testutil.Assert; import org.junit.Test; import org.mockito.Mockito; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/TestGraph.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/TestGraph.java index 4d76cb72bf..97447f08ac 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/TestGraph.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/TestGraph.java @@ -30,7 +30,7 @@ import org.apache.hugegraph.io.HugeGraphSONModule; import org.apache.hugegraph.masterelection.GlobalMasterInfo; import org.apache.hugegraph.perf.PerfUtil.Watched; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.schema.SchemaManager; import org.apache.hugegraph.task.TaskScheduler; import org.apache.hugegraph.testutil.Whitebox; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/traversal/optimize/TraversalUtilOptimizeTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/traversal/optimize/TraversalUtilOptimizeTest.java index 630c08dbfb..54a49c67aa 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/traversal/optimize/TraversalUtilOptimizeTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/traversal/optimize/TraversalUtilOptimizeTest.java @@ -25,10 +25,10 @@ import java.util.Set; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.exception.NotFoundException; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.type.define.DataType; import org.apache.tinkerpop.gremlin.process.traversal.GType; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/BaseUnitTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/BaseUnitTest.java index b6dc0bf96a..5be6c3a5e0 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/BaseUnitTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/BaseUnitTest.java @@ -26,7 +26,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.util.Log; import org.apache.hugegraph.util.TimeUtil; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/FakeObjects.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/FakeObjects.java index 9dabd72a3a..e4bd85f578 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/FakeObjects.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/FakeObjects.java @@ -22,17 +22,17 @@ import org.apache.commons.configuration2.Configuration; import org.apache.commons.configuration2.PropertiesConfiguration; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.config.HugeConfig; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.config.TypedOption; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeVertex; -import org.apache.hugegraph.testutil.Whitebox; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Cardinality; import org.apache.hugegraph.type.define.DataType; @@ -53,6 +53,10 @@ public FakeObjects(String name) { public FakeObjects() { this.graph = Mockito.mock(HugeGraph.class); Mockito.doReturn(newConfig()).when(this.graph).configuration(); + Mockito.doAnswer(invocation -> { + TypedOption option = invocation.getArgument(0); + return this.graph.configuration().get(option); + }).when(this.graph).option(Mockito.any()); Mockito.doReturn(true).when(this.graph).sameAs(this.graph); } @@ -159,8 +163,7 @@ public HugeEdge newEdge(long sourceVertexId, long targetVertexId) { Id id = EdgeId.parse("L123456>1>1>>L987654"); HugeEdge edge = new HugeEdge(this.graph(), id, el); - Whitebox.setInternalState(edge, "sourceVertex", source); - Whitebox.setInternalState(edge, "targetVertex", target); + edge.vertices(true, source, target); edge.assignId(); edge.addProperty(date, new Date()); edge.addProperty(weight, 0.75); @@ -202,8 +205,7 @@ public HugeEdge newEdge(String sourceVertexId, String targetVertexId) { Id id = EdgeId.parse("L123456>1>1>>L987654"); HugeEdge edge = new HugeEdge(this.graph(), id, el); - Whitebox.setInternalState(edge, "sourceVertex", source); - Whitebox.setInternalState(edge, "targetVertex", target); + edge.vertices(true, source, target); edge.assignId(); edge.addProperty(date, new Date()); edge.addProperty(weight, 0.75); diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/UnitTestSuite.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/UnitTestSuite.java index f772ffd927..617440b668 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/UnitTestSuite.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/UnitTestSuite.java @@ -65,6 +65,8 @@ import org.apache.hugegraph.unit.core.GroovyScriptEngineCompatibilityTest; import org.apache.hugegraph.unit.core.HugeFeaturesTest; import org.apache.hugegraph.unit.core.HstoreSessionsTest; +import org.apache.hugegraph.unit.core.HugeElementViewTest; +import org.apache.hugegraph.unit.core.HugePrimaryKeyTest; import org.apache.hugegraph.unit.core.IdHolderTest; import org.apache.hugegraph.unit.core.LocksTableTest; import org.apache.hugegraph.unit.core.PageStateTest; @@ -198,6 +200,8 @@ HugeGraphAuthProxyTest.class, SchemaElementTest.class, HugeGraphTestInfrastructureTest.class, + HugeElementViewTest.class, + HugePrimaryKeyTest.class, ShortestPathTraverserTest.class, /* cmd */ diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/auth/HugeGraphAuthProxyTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/auth/HugeGraphAuthProxyTest.java index 60d2e097eb..e5b8494945 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/auth/HugeGraphAuthProxyTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/auth/HugeGraphAuthProxyTest.java @@ -22,7 +22,7 @@ import java.util.List; import java.util.concurrent.atomic.AtomicReference; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.auth.AuthManager; import org.apache.hugegraph.auth.HugeAuthenticator; @@ -34,8 +34,8 @@ import org.apache.hugegraph.auth.RolePermission; import org.apache.hugegraph.auth.UserWithRole; import org.apache.hugegraph.backend.cache.Cache; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.config.AuthOptions; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.task.TaskManager; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/CacheManagerTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/CacheManagerTest.java index 8d7ef2166a..034bbf46a8 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/CacheManagerTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/CacheManagerTest.java @@ -26,8 +26,8 @@ import org.apache.hugegraph.backend.cache.CacheManager; import org.apache.hugegraph.backend.cache.OffheapCache; import org.apache.hugegraph.backend.cache.RamCache; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.testutil.Whitebox; import org.apache.hugegraph.unit.BaseUnitTest; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/CacheTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/CacheTest.java index d9bd4cf953..8883bcf3b4 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/CacheTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/CacheTest.java @@ -29,8 +29,8 @@ import org.apache.hugegraph.backend.cache.LevelCache; import org.apache.hugegraph.backend.cache.OffheapCache; import org.apache.hugegraph.backend.cache.RamCache; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.testutil.Whitebox; import org.apache.hugegraph.unit.BaseUnitTest; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/CachedGraphTransactionTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/CachedGraphTransactionTest.java index ae0321ee01..8708d78479 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/CachedGraphTransactionTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/CachedGraphTransactionTest.java @@ -36,14 +36,14 @@ import org.apache.hugegraph.backend.cache.CachedBackendStore.QueryId; import org.apache.hugegraph.backend.cache.CachedGraphTransaction; import org.apache.hugegraph.backend.cache.OffheapCache; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.ConditionQuery.OptimizedType; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.IdQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery.OptimizedType; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.IdQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.query.QueryResultContext; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.backend.store.BackendStore; @@ -51,7 +51,7 @@ import org.apache.hugegraph.backend.store.ram.RamTable; import org.apache.hugegraph.event.EventHub; import org.apache.hugegraph.event.EventListener; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeElement; import org.apache.hugegraph.structure.HugeVertex; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/CachedSchemaTransactionTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/CachedSchemaTransactionTest.java index 9e7aec3842..a4ea489817 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/CachedSchemaTransactionTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/CachedSchemaTransactionTest.java @@ -39,14 +39,14 @@ import org.apache.hugegraph.backend.cache.CacheManager; import org.apache.hugegraph.backend.cache.CachedSchemaTransaction; import org.apache.hugegraph.backend.cache.CachedSchemaTransactionV2; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.event.EventHub; import org.apache.hugegraph.event.EventListener; import org.apache.hugegraph.meta.MetaDriver; import org.apache.hugegraph.meta.MetaManager; import org.apache.hugegraph.meta.managers.GraphMetaManager; -import org.apache.hugegraph.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.SchemaElement; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.testutil.Whitebox; import org.apache.hugegraph.type.HugeType; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/RamTableTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/RamTableTest.java index 245f311bcb..c7bbfd874f 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/RamTableTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/RamTableTest.java @@ -19,14 +19,14 @@ import java.util.Iterator; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeFactory; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.store.ram.RamTable; -import org.apache.hugegraph.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.testutil.Assert; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/config/GraphBinarySchemaCompatibilityTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/config/GraphBinarySchemaCompatibilityTest.java index 60fd0cfe96..f8b1d704c7 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/config/GraphBinarySchemaCompatibilityTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/config/GraphBinarySchemaCompatibilityTest.java @@ -22,15 +22,15 @@ import java.util.Map; import java.util.UUID; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.store.Shard; +import org.apache.hugegraph.backend.Shard; import org.apache.hugegraph.backend.tx.ISchemaTransaction; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.io.HugeGraphTypeSerializerRegistryBuilder; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; import org.apache.hugegraph.schema.SchemaManager; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Cardinality; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/config/GremlinConfigCompatibilityTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/config/GremlinConfigCompatibilityTest.java index 1ab85c8905..d66a5aca8c 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/config/GremlinConfigCompatibilityTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/config/GremlinConfigCompatibilityTest.java @@ -40,11 +40,11 @@ import java.util.regex.Pattern; import java.util.stream.Stream; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.io.HugeGraphIoRegistry; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeFeatures; import org.apache.hugegraph.structure.HugeVertex; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/BackendMutationTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/BackendMutationTest.java index e07727fd23..728fc7fb1e 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/BackendMutationTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/BackendMutationTest.java @@ -19,9 +19,9 @@ import java.util.List; -import org.apache.hugegraph.HugeException; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.id.SplicingIdGenerator; +import org.apache.hugegraph.exception.HugeException; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.id.SplicingIdGenerator; import org.apache.hugegraph.backend.serializer.TextBackendEntry; import org.apache.hugegraph.backend.store.BackendAction; import org.apache.hugegraph.backend.store.BackendEntry; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/BackendProviderFactoryTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/BackendProviderFactoryTest.java index 767febd620..58bd977b6e 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/BackendProviderFactoryTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/BackendProviderFactoryTest.java @@ -25,7 +25,7 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.backend.store.BackendProviderFactory; import org.apache.hugegraph.backend.store.memory.InMemoryDBStoreProvider; import org.apache.hugegraph.backend.store.raft.RaftBackendStoreProvider; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/ConditionQueryFlattenTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/ConditionQueryFlattenTest.java index 64833a3f70..0d9c2187a2 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/ConditionQueryFlattenTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/ConditionQueryFlattenTest.java @@ -21,10 +21,10 @@ import java.util.Collection; import java.util.List; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; import org.apache.hugegraph.backend.query.ConditionQueryFlatten; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.type.HugeType; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/ConditionTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/ConditionTest.java index bd376d495d..0305fa1bf5 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/ConditionTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/ConditionTest.java @@ -19,11 +19,11 @@ import java.util.Date; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.Condition.Relation; -import org.apache.hugegraph.backend.query.Condition.RelationType; -import org.apache.hugegraph.backend.query.Condition.SyspropRelation; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.Condition.Relation; +import org.apache.hugegraph.query.Condition.RelationType; +import org.apache.hugegraph.query.Condition.SyspropRelation; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.traversal.optimize.ConditionP; import org.apache.hugegraph.type.define.HugeKeys; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/DirectionsTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/DirectionsTest.java index 0f6b69e8fc..75678b82cc 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/DirectionsTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/DirectionsTest.java @@ -17,6 +17,8 @@ package org.apache.hugegraph.unit.core; +import org.apache.hugegraph.util.TinkerPopUtil; + import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Directions; @@ -59,16 +61,16 @@ public void testOpposite() { @Test public void testToDirection() { - Assert.assertEquals(Direction.OUT, Directions.OUT.direction()); - Assert.assertEquals(Direction.IN, Directions.IN.direction()); - Assert.assertEquals(Direction.BOTH, Directions.BOTH.direction()); + Assert.assertEquals(Direction.OUT, TinkerPopUtil.direction(Directions.OUT)); + Assert.assertEquals(Direction.IN, TinkerPopUtil.direction(Directions.IN)); + Assert.assertEquals(Direction.BOTH, TinkerPopUtil.direction(Directions.BOTH)); } @Test public void testFromDirection() { - Assert.assertEquals(Directions.OUT, Directions.convert(Direction.OUT)); - Assert.assertEquals(Directions.IN, Directions.convert(Direction.IN)); + Assert.assertEquals(Directions.OUT, TinkerPopUtil.direction(Direction.OUT)); + Assert.assertEquals(Directions.IN, TinkerPopUtil.direction(Direction.IN)); Assert.assertEquals(Directions.BOTH, - Directions.convert(Direction.BOTH)); + TinkerPopUtil.direction(Direction.BOTH)); } } diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/GraphManagerAdminInitTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/GraphManagerAdminInitTest.java index 60e59666f4..490ffb9920 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/GraphManagerAdminInitTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/GraphManagerAdminInitTest.java @@ -22,7 +22,7 @@ import java.util.Map; import org.apache.commons.configuration2.PropertiesConfiguration; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.auth.HugeAuthenticator; import org.apache.hugegraph.auth.HugeUser; import org.apache.hugegraph.auth.StandardAuthenticator; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/GraphManagerStoresWaitTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/GraphManagerStoresWaitTest.java index c9d991cee0..e5e060e2d3 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/GraphManagerStoresWaitTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/GraphManagerStoresWaitTest.java @@ -30,7 +30,7 @@ import io.grpc.ServerBuilder; import io.grpc.stub.StreamObserver; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.core.GraphManager.Readiness; import org.apache.hugegraph.pd.client.PDConfig; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/HugeElementViewTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/HugeElementViewTest.java new file mode 100644 index 0000000000..1255ac5754 --- /dev/null +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/HugeElementViewTest.java @@ -0,0 +1,220 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.unit.core; + +import java.util.Collection; +import java.util.Iterator; + +import org.apache.hugegraph.HugeGraph; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; +import org.apache.hugegraph.structure.BaseEdge; +import org.apache.hugegraph.structure.BaseProperty; +import org.apache.hugegraph.structure.BaseVertex; +import org.apache.hugegraph.structure.HugeEdge; +import org.apache.hugegraph.structure.HugeProperty; +import org.apache.hugegraph.structure.HugeVertex; +import org.apache.hugegraph.structure.HugeVertexProperty; +import org.apache.hugegraph.type.define.Frequency; +import org.apache.hugegraph.type.define.IdStrategy; +import org.apache.hugegraph.unit.FakeObjects; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; + +public class HugeElementViewTest { + + @Test + public void testPropertyViewWrapsOnlyConsumedEntries() { + FakeObjects objects = new FakeObjects(); + PropertyKey name = objects.newPropertyKey(IdGenerator.of(1), "name"); + PropertyKey city = objects.newPropertyKey(IdGenerator.of(2), "city"); + VertexLabel label = objects.newVertexLabel(IdGenerator.of(1), "person", + IdStrategy.CUSTOMIZE_NUMBER, + name.id(), city.id()); + CountingVertex vertex = new CountingVertex(objects.graph(), label); + vertex.addProperty(name, "tom"); + vertex.wrapped = 0; + + Collection> properties = vertex.getProperties(); + Assert.assertEquals(1, properties.size()); + Assert.assertEquals(0, vertex.wrapped); + Iterator> iterator = properties.iterator(); + Assert.assertTrue(iterator.hasNext()); + Assert.assertEquals(0, vertex.wrapped); + Assert.assertEquals("tom", iterator.next().value()); + Assert.assertEquals(1, vertex.wrapped); + + vertex.addProperty(city, "Beijing"); + vertex.wrapped = 0; + Assert.assertEquals(2, properties.size()); + Assert.assertEquals(0, vertex.wrapped); + properties.clear(); + Assert.assertEquals(0, vertex.sizeOfProperties()); + Assert.assertEquals(0, vertex.wrapped); + } + + @Test + public void testPropertyViewIteratorRemovesSharedEntry() { + FakeObjects objects = new FakeObjects(); + PropertyKey name = objects.newPropertyKey(IdGenerator.of(1), "name"); + VertexLabel label = objects.newVertexLabel(IdGenerator.of(1), "person", + IdStrategy.CUSTOMIZE_NUMBER, name.id()); + CountingVertex vertex = new CountingVertex(objects.graph(), label); + vertex.addProperty(name, "tom"); + Iterator> iterator = vertex.getProperties().iterator(); + iterator.next(); + iterator.remove(); + Assert.assertFalse(vertex.hasProperty(name.id())); + Assert.assertFalse(vertex.element().hasProperty(name.id())); + } + + @Test + public void testFreshEngineStateViewsDoNotShareMutableEmptyProperties() { + FakeObjects objects = new FakeObjects(); + PropertyKey key = objects.newPropertyKey(IdGenerator.of(1), "name"); + VertexLabel label = objects.newVertexLabel(IdGenerator.of(1), "person", + IdStrategy.CUSTOMIZE_NUMBER, key.id()); + CountingVertex first = new CountingVertex(objects.graph(), label); + CountingVertex second = new CountingVertex(objects.graph(), label); + Collection> secondView = second.getProperties(); + Assert.assertEquals(0, secondView.size()); + Assert.assertFalse(secondView.iterator().hasNext()); + Assert.assertEquals(0, second.wrapped); + first.element().properties().put(1, new BaseProperty<>(key, "first")); + Assert.assertEquals("first", first.getPropertyValue(key.id())); + Assert.assertTrue(secondView.isEmpty()); + secondView.clear(); + Assert.assertEquals("first", first.getPropertyValue(key.id())); + Assert.assertEquals(0, second.wrapped); + } + + @Test + public void testAdoptedAdjacencyPreservesOwnerStateAndStableWrappers() { + FakeObjects objects = new FakeObjects(); + PropertyKey name = objects.newPropertyKey(IdGenerator.of(1), "name"); + VertexLabel label = objects.newVertexLabel(IdGenerator.of(1), "person", + IdStrategy.CUSTOMIZE_NUMBER, name.id()); + EdgeLabel link = objects.newEdgeLabel(IdGenerator.of(2), "link", Frequency.SINGLE, + label.id(), label.id()); + for (boolean out : new boolean[]{true, false}) { + BaseVertex owner = new BaseVertex(IdGenerator.of(1), label); + owner.addProperty(name, "tom"); + BaseEdge base = BaseEdge.constructEdge(objects.graph(), owner, out, link, "", IdGenerator.of(2)); + base.expiredTime(123); + HugeVertex vertex = new HugeVertex(objects.graph(), owner); + Assert.assertEquals(1, vertex.getEdges().size()); + HugeEdge edge = vertex.getEdges().iterator().next(); + Assert.assertSame(vertex, edge.ownerVertex()); + Assert.assertSame(base, edge.element()); + Assert.assertSame(owner.getProperty(name.id()), vertex.getProperty(name.id()).baseProperty()); + Assert.assertSame(edge, vertex.getEdges().iterator().next()); + Assert.assertEquals(out, edge.element().isOutEdge()); + Assert.assertEquals(123, edge.expiredTime()); + Assert.assertFalse(vertex.isPropLoaded()); + vertex.removeEdge(edge); + Assert.assertTrue(owner.edges().isEmpty()); + } + } + + @Test + public void testCanonicalSelfLoopAndCopyResetKeepMembershipConsistent() { + FakeObjects objects = new FakeObjects(); + VertexLabel label = objects.newVertexLabel(IdGenerator.of(1), "person", IdStrategy.CUSTOMIZE_NUMBER); + EdgeLabel link = objects.newEdgeLabel(IdGenerator.of(2), "link", Frequency.SINGLE, + label.id(), label.id()); + BaseVertex base = new BaseVertex(IdGenerator.of(1), label); + BaseEdge loop = new BaseEdge(link, true); + loop.vertices(true, base, base); + loop.name(""); + loop.assignId(); + base.addEdge(loop); + HugeVertex vertex = new HugeVertex(objects.graph(), base); + HugeEdge edge = vertex.getEdges().iterator().next(); + Assert.assertTrue(edge.selfLoop()); + Assert.assertSame(vertex, edge.sourceVertex()); + Assert.assertSame(vertex, edge.targetVertex()); + Assert.assertSame(vertex, edge.switchOwner().ownerVertex()); + HugeVertex copy = vertex.copy(); + copy.resetEdges(); + Assert.assertTrue(copy.getEdges().isEmpty()); + Assert.assertEquals(1, vertex.getEdges().size()); + Assert.assertEquals(1, base.edges().size()); + } + + @Test + public void testConstructedEdgeUsesOneAdjacencyMembershipAndOriginalOwner() { + FakeObjects objects = new FakeObjects(); + VertexLabel label = objects.newVertexLabel(IdGenerator.of(1), "person", IdStrategy.CUSTOMIZE_NUMBER); + EdgeLabel link = objects.newEdgeLabel(IdGenerator.of(2), "link", Frequency.SINGLE, + label.id(), label.id()); + HugeVertex vertex = new HugeVertex(objects.graph(), IdGenerator.of(1), label); + HugeEdge edge = HugeEdge.constructEdge(vertex, false, link, "", IdGenerator.of(2)); + Assert.assertSame(vertex, edge.ownerVertex()); + Assert.assertSame(edge, vertex.getEdges().iterator().next()); + Assert.assertEquals(1, vertex.element().edges().size()); + Assert.assertEquals(1, edge.otherVertex().element().edges().size()); + Assert.assertSame(edge.element(), vertex.element().edges().iterator().next()); + Assert.assertSame(edge.otherVertex(), edge.otherVertex().getEdges().iterator().next().ownerVertex()); + } + + @Test + public void testEdgeConstructionWithoutSchemaLookupRetainsEngineGraph() { + FakeObjects objects = new FakeObjects(); + VertexLabel label = objects.newVertexLabel(IdGenerator.of(1), "person", IdStrategy.CUSTOMIZE_NUMBER); + EdgeLabel link = objects.newEdgeLabel(IdGenerator.of(2), "link", Frequency.SINGLE, + label.id(), label.id()); + HugeVertex owner = new HugeVertex(objects.graph(), IdGenerator.of(1), label); + HugeEdge withoutLabel = HugeEdge.constructEdgeWithoutLabel(owner, true, "", IdGenerator.of(2)); + Assert.assertSame(owner, withoutLabel.ownerVertex()); + Assert.assertSame(label, owner.schemaLabel()); + Assert.assertTrue(withoutLabel.otherVertex().schemaLabel().undefined()); + Assert.assertEquals(VertexLabel.NONE.id(), withoutLabel.otherVertex().schemaLabel().id()); + Assert.assertSame(objects.graph(), withoutLabel.schemaLabel().graph()); + Assert.assertSame(objects.graph(), withoutLabel.otherVertex().schemaLabel().graph()); + Assert.assertEquals(1, owner.element().edges().size()); + + owner.resetEdges(); + HugeEdge withoutLookup = HugeEdge.constructEdgeWithoutGraph(owner, true, link, "", IdGenerator.of(2)); + Assert.assertSame(objects.graph(), withoutLookup.graph()); + Assert.assertSame(owner, withoutLookup.ownerVertex()); + Assert.assertTrue(withoutLookup.otherVertex().schemaLabel().undefined()); + Assert.assertSame(objects.graph(), withoutLookup.schemaLabel().graph()); + Assert.assertSame(objects.graph(), withoutLookup.ownerVertex().schemaLabel().graph()); + Assert.assertSame(objects.graph(), withoutLookup.otherVertex().schemaLabel().graph()); + Assert.assertEquals(1, owner.element().edges().size()); + Mockito.verify(objects.graph(), Mockito.never()).vertexLabelOrNone(Mockito.any()); + } + + private static final class CountingVertex extends HugeVertex { + + private int wrapped; + + private CountingVertex(HugeGraph graph, VertexLabel label) { + super(graph, IdGenerator.of(1), label); + } + + @Override + protected HugeVertexProperty wrapProperty(BaseProperty property) { + this.wrapped++; + return super.wrapProperty(property); + } + } +} diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/HugePrimaryKeyTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/HugePrimaryKeyTest.java new file mode 100644 index 0000000000..d567fc922b --- /dev/null +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/HugePrimaryKeyTest.java @@ -0,0 +1,136 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.unit.core; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.hugegraph.backend.tx.GraphTransaction; +import org.apache.hugegraph.config.CoreOptions; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.Query; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; +import org.apache.hugegraph.structure.HugeVertex; +import org.apache.hugegraph.testutil.Whitebox; +import org.apache.hugegraph.type.HugeType; +import org.apache.hugegraph.type.define.DataType; +import org.apache.hugegraph.type.define.HugeKeys; +import org.apache.hugegraph.type.define.IdStrategy; +import org.apache.hugegraph.unit.FakeObjects; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; + +public class HugePrimaryKeyTest { + + @Test + public void testEmptyPrimaryKeyStillRejected() { + Fixture fixture = new Fixture(true, ""); + IllegalArgumentException error = Assert.assertThrows(IllegalArgumentException.class, + () -> fixture.vertex.assignId(null)); + Assert.assertTrue(error.getMessage().contains("primary key can't be empty")); + } + + @Test + public void testReservedLeadingSymbolsStillRejected() { + for (char value = 0; value <= 3; value++) { + Fixture fixture = new Fixture(true, value + "value"); + IllegalArgumentException error = Assert.assertThrows(IllegalArgumentException.class, + () -> fixture.vertex.assignId(null)); + Assert.assertTrue(error.getMessage().contains("Illegal leading char")); + } + } + + @Test + public void testEnginePrimaryIdMatchesActualQueryOptimizer() { + Fixture escaped = new Fixture(true, "a!b", "left>right:tail`x"); + escaped.vertex.assignId(null); + Assert.assertEquals(escaped.vertex.id(), escaped.optimizedQueryId(false)); + Fixture numeric = new Fixture(true, 42); + numeric.vertex.assignId(null); + Assert.assertEquals(numeric.vertex.id(), numeric.optimizedQueryId(false)); + } + + @Test + public void testCompositeEmptyFieldRetainsLegacyEncodedName() { + Fixture fixture = new Fixture(true, "first", "", "a!b"); + fixture.vertex.assignId(null); + Assert.assertEquals("1:first!!a`!b", fixture.vertex.id().asString()); + Assert.assertEquals(fixture.vertex.id(), fixture.optimizedQueryId(true)); + } + + @Test + public void testNumberEncodingOptionRetainsPlainNumberMode() { + Fixture plain = new Fixture(false, 42); + plain.vertex.assignId(null); + Assert.assertEquals("1:42", plain.vertex.id().asString()); + Assert.assertEquals(plain.vertex.id(), plain.optimizedQueryId(true)); + Fixture encoded = new Fixture(true, 42); + encoded.vertex.assignId(null); + Assert.assertNotEquals(plain.vertex.id(), encoded.vertex.id()); + } + + private static final class Fixture { + + private final FakeObjects objects = new FakeObjects(); + private final List keys = new ArrayList<>(); + private final Object[] values; + private final boolean encodeNumber; + private final VertexLabel label; + private final HugeVertex vertex; + + private Fixture(boolean encodeNumber, Object... values) { + this.values = values; + this.encodeNumber = encodeNumber; + Mockito.doReturn(encodeNumber).when(this.objects.graph()).option(CoreOptions.VERTEX_ENCODE_PK_NUMBER); + for (int i = 0; i < values.length; i++) { + this.keys.add(this.objects.newPropertyKey(IdGenerator.of(i + 1), "key" + i, + values[i] instanceof Number ? DataType.INT : DataType.TEXT)); + } + Id[] ids = this.keys.stream().map(PropertyKey::id).toArray(Id[]::new); + this.label = this.objects.newVertexLabel(IdGenerator.of(1), "person", IdStrategy.PRIMARY_KEY, ids); + this.label.primaryKeys(ids); + this.vertex = new HugeVertex(this.objects.graph(), null, this.label); + for (int i = 0; i < values.length; i++) { + this.vertex.addProperty(this.keys.get(i), values[i]); + } + } + + private Id optimizedQueryId(boolean serializedValues) { + ConditionQuery query = new ConditionQuery(HugeType.VERTEX); + query.eq(HugeKeys.LABEL, this.label.id()); + for (int i = 0; i < this.values.length; i++) { + Condition.Relation relation = Condition.eq(this.keys.get(i).id(), this.values[i]); + if (serializedValues) { + Object value = this.keys.get(i).serialValue(this.values[i], this.encodeNumber); + relation.serialValue("".equals(value) ? ConditionQuery.INDEX_VALUE_EMPTY : value); + } + query.query(relation); + } + GraphTransaction tx = Mockito.mock(GraphTransaction.class, Mockito.CALLS_REAL_METHODS); + Mockito.doReturn(this.objects.graph()).when(tx).graph(); + Query optimized = Whitebox.invoke(GraphTransaction.class, new Class[]{ConditionQuery.class}, + "optimizeQuery", tx, query); + return optimized.ids().iterator().next(); + } + } +} diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/IdHolderTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/IdHolderTest.java index c6bdcc32d5..a4822307f5 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/IdHolderTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/IdHolderTest.java @@ -22,17 +22,17 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicReference; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.page.IdHolder.BatchIdHolder; import org.apache.hugegraph.backend.page.IdHolder.PagingIdHolder; import org.apache.hugegraph.backend.page.IdHolderList; import org.apache.hugegraph.backend.page.PageIds; import org.apache.hugegraph.backend.page.PageState; import org.apache.hugegraph.backend.page.QueryList; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.IdQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.IdQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.testutil.Assert; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/LocksTableTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/LocksTableTest.java index 00eb918211..2fded2bf6c 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/LocksTableTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/LocksTableTest.java @@ -22,8 +22,8 @@ import java.util.Set; import java.util.concurrent.locks.Lock; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.concurrent.LockManager; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.testutil.Whitebox; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/PageStateTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/PageStateTest.java index ba1b37f5c4..34f12f3a0f 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/PageStateTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/PageStateTest.java @@ -19,7 +19,7 @@ import java.util.Arrays; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.backend.page.PageState; import org.apache.hugegraph.testutil.Assert; import org.junit.Test; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/QueryResultsTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/QueryResultsTest.java index 64c675f647..dc2c4f2233 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/QueryResultsTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/QueryResultsTest.java @@ -24,13 +24,13 @@ import java.util.List; import java.util.Set; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.page.PageInfo; import org.apache.hugegraph.backend.page.PageState; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.IdQuery; -import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.IdQuery; +import org.apache.hugegraph.query.Query; import org.apache.hugegraph.backend.query.QueryBatch; import org.apache.hugegraph.backend.query.QueryResultContext; import org.apache.hugegraph.backend.query.QueryResults; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/QueryTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/QueryTest.java index 5778ceba7c..622535cbc0 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/QueryTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/QueryTest.java @@ -17,16 +17,16 @@ package org.apache.hugegraph.unit.core; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.query.Aggregate.AggregateFunc; -import org.apache.hugegraph.backend.query.Condition; -import org.apache.hugegraph.backend.query.ConditionQuery; -import org.apache.hugegraph.backend.query.IdPrefixQuery; -import org.apache.hugegraph.backend.query.IdQuery; -import org.apache.hugegraph.backend.query.IdRangeQuery; -import org.apache.hugegraph.backend.query.Query; -import org.apache.hugegraph.backend.query.Query.Order; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.query.Aggregate.AggregateFunc; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.IdPrefixQuery; +import org.apache.hugegraph.query.IdQuery; +import org.apache.hugegraph.query.IdRangeQuery; +import org.apache.hugegraph.query.Query; +import org.apache.hugegraph.query.Query.Order; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.HugeKeys; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/RangeTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/RangeTest.java index 39b28784b9..d016fa07ab 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/RangeTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/RangeTest.java @@ -20,7 +20,7 @@ import java.util.List; import org.apache.hugegraph.backend.store.BackendTable.ShardSplitter.Range; -import org.apache.hugegraph.backend.store.Shard; +import org.apache.hugegraph.backend.Shard; import org.apache.hugegraph.testutil.Assert; import org.apache.logging.log4j.util.Strings; import org.junit.After; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/RolePermissionTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/RolePermissionTest.java index 645b02e232..436b1aabb3 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/RolePermissionTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/RolePermissionTest.java @@ -17,7 +17,7 @@ package org.apache.hugegraph.unit.core; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.auth.HugePermission; import org.apache.hugegraph.auth.HugeProject; import org.apache.hugegraph.auth.HugeResource; @@ -27,8 +27,8 @@ import org.apache.hugegraph.auth.ResourceObject; import org.apache.hugegraph.auth.ResourceType; import org.apache.hugegraph.auth.RolePermission; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.testutil.Whitebox; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/SchemaElementTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/SchemaElementTest.java index 9853af107e..36f6f75f86 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/SchemaElementTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/SchemaElementTest.java @@ -17,23 +17,32 @@ package org.apache.hugegraph.unit.core; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.schema.Userdata; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.Userdata; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.type.define.Cardinality; import org.apache.hugegraph.type.define.DataType; +import org.apache.hugegraph.type.define.EdgeLabelType; +import org.apache.hugegraph.type.define.Frequency; +import org.apache.hugegraph.type.define.IdStrategy; import org.apache.hugegraph.unit.FakeObjects; import org.apache.hugegraph.util.DateUtil; +import org.apache.hugegraph.util.JsonUtil; import org.junit.Test; public class SchemaElementTest { @@ -270,4 +279,73 @@ public void testBulkSetterRejectsNullUserdata() { Assert.assertContains("userdata", e.getMessage()); }); } + + @Test + public void testEdgeLabelMetadataJsonRoundTrip() { + for (EdgeLabelType type : new EdgeLabelType[]{EdgeLabelType.NORMAL, + EdgeLabelType.PARENT, + EdgeLabelType.SUB}) { + for (boolean multipleLinks : new boolean[]{false, true}) { + EdgeLabel label = new EdgeLabel(null, IdGenerator.of(3), "knows"); + label.edgeLabelType(type); + label.frequency(Frequency.SINGLE); + label.links(Pair.of(IdGenerator.of(1), IdGenerator.of(2))); + if (multipleLinks) { + label.links(Pair.of(IdGenerator.of(2), IdGenerator.of(4))); + } + if (type.sub()) { + label.fatherId(IdGenerator.of(5)); + } + String json = JsonUtil.toJson(label.asMap()); + Map decoded = JsonUtil.fromJson(json, Map.class); + Assert.assertEquals(!multipleLinks, decoded.containsKey(EdgeLabel.P.SOURCE_LABEL)); + Assert.assertEquals(!multipleLinks, decoded.containsKey(EdgeLabel.P.TARGET_LABEL)); + Assert.assertTrue(decoded.containsKey(EdgeLabel.P.LINKS)); + + // Metadata JSON key order must not select setter execution order. + List keys = new ArrayList<>(decoded.keySet()); + Collections.reverse(keys); + Map reordered = new LinkedHashMap<>(); + reordered.put(EdgeLabel.P.LINKS, decoded.get(EdgeLabel.P.LINKS)); + for (String key : keys) { + reordered.put(key, decoded.get(key)); + } + for (Map input : Arrays.asList(decoded, reordered)) { + EdgeLabel restored = EdgeLabel.fromMap(input, null); + Assert.assertEquals(label.links(), restored.links()); + Assert.assertEquals(label.edgeLabelType(), restored.edgeLabelType()); + Assert.assertEquals(label.fatherId(), restored.fatherId()); + Assert.assertEquals(label.frequency(), restored.frequency()); + Assert.assertEquals(label.status(), restored.status()); + Assert.assertEquals(label.asMap(), restored.asMap()); + } + } + } + } + + + @Test + public void testOrderedSchemaFieldsSurviveMetadataJson() { + for (int[] values : new int[][]{{17, 2}, {2, 17}, {2, 17, 2}}) { + VertexLabel vertex = new VertexLabel(null, IdGenerator.of(1), "person"); + vertex.idStrategy(IdStrategy.PRIMARY_KEY); + EdgeLabel edge = new EdgeLabel(null, IdGenerator.of(3), "knows"); + edge.frequency(Frequency.SINGLE); + edge.links(Pair.of(IdGenerator.of(1), IdGenerator.of(2))); + for (int value : values) { + vertex.primaryKey(IdGenerator.of(value)); + edge.sortKey(IdGenerator.of(value)); + } + String vertexJson = JsonUtil.toJson(vertex.asMap()); + String edgeJson = JsonUtil.toJson(edge.asMap()); + VertexLabel restoredVertex = VertexLabel.fromMap( + JsonUtil.fromJson(vertexJson, Map.class), null); + EdgeLabel restoredEdge = EdgeLabel.fromMap(JsonUtil.fromJson(edgeJson, Map.class), null); + Assert.assertEquals(vertex.primaryKeys(), restoredVertex.primaryKeys()); + Assert.assertEquals(edge.sortKeys(), restoredEdge.sortKeys()); + Assert.assertEquals(vertex.asMap(), restoredVertex.asMap()); + Assert.assertEquals(edge.asMap(), restoredEdge.asMap()); + } + } + } diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/SecurityManagerTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/SecurityManagerTest.java index a30f35cb31..a39d1b138d 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/SecurityManagerTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/SecurityManagerTest.java @@ -32,7 +32,7 @@ import java.util.Map; import java.util.concurrent.TimeoutException; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.HugeFactory; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.auth.HugeFactoryAuthProxy; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/ServerInfoManagerTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/ServerInfoManagerTest.java index 3784cef086..74cf096185 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/ServerInfoManagerTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/ServerInfoManagerTest.java @@ -18,7 +18,7 @@ package org.apache.hugegraph.unit.core; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.masterelection.GlobalMasterInfo; import org.apache.hugegraph.task.ServerInfoManager; import org.apache.hugegraph.testutil.Assert; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/StandardHugeGraphClearBackendTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/StandardHugeGraphClearBackendTest.java index f056c9291f..9aa9295f25 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/StandardHugeGraphClearBackendTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/StandardHugeGraphClearBackendTest.java @@ -17,7 +17,7 @@ package org.apache.hugegraph.unit.core; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.StandardHugeGraph; import org.apache.hugegraph.backend.cache.CachedSchemaTransactionV2; import org.apache.hugegraph.backend.store.BackendStore; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/SystemSchemaStoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/SystemSchemaStoreTest.java index 96a0ce791c..e345ed3a21 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/SystemSchemaStoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/SystemSchemaStoreTest.java @@ -18,11 +18,11 @@ package org.apache.hugegraph.unit.core; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.store.SystemSchemaStore; -import org.apache.hugegraph.schema.SchemaElement; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.testutil.Whitebox; import org.junit.Test; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/TaskSchedulerServerInfoTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/TaskSchedulerServerInfoTest.java index f7dd3e370a..feef2f623c 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/TaskSchedulerServerInfoTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/TaskSchedulerServerInfoTest.java @@ -23,8 +23,8 @@ import org.apache.commons.configuration2.PropertiesConfiguration; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.HugeGraphParams; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.concurrent.PausableScheduledThreadPool; import org.apache.hugegraph.config.CoreOptions; import org.apache.hugegraph.config.HugeConfig; @@ -32,7 +32,7 @@ import org.apache.hugegraph.core.GraphManager; import org.apache.hugegraph.event.EventHub; import org.apache.hugegraph.exception.NotFoundException; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.task.DistributedTaskScheduler; import org.apache.hugegraph.task.HugeTask; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/TraversalUtilTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/TraversalUtilTest.java index 08322112b7..fe664e1003 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/TraversalUtilTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/TraversalUtilTest.java @@ -17,7 +17,7 @@ package org.apache.hugegraph.unit.core; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.traversal.optimize.TraversalUtil; import org.apache.hugegraph.util.DateUtil; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/EdgeIdTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/EdgeIdTest.java index 0c917832f8..d36fe413a8 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/EdgeIdTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/EdgeIdTest.java @@ -19,9 +19,9 @@ import java.util.Set; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.type.define.Directions; import org.apache.hugegraph.unit.BaseUnitTest; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/IdTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/IdTest.java index 8bd772a3db..c695e80f26 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/IdTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/IdTest.java @@ -20,9 +20,9 @@ import java.nio.ByteBuffer; import java.util.UUID; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.Id.IdType; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.Id.IdType; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.unit.BaseUnitTest; import org.apache.hugegraph.util.NumericUtil; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/IdUtilTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/IdUtilTest.java index 473dc61891..38d1e4d876 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/IdUtilTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/IdUtilTest.java @@ -19,10 +19,10 @@ import java.nio.ByteBuffer; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.id.IdUtil; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.id.IdUtil; import org.junit.Assert; import org.junit.Test; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/SplicingIdGeneratorTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/SplicingIdGeneratorTest.java index bc7f97ccfb..50214b650b 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/SplicingIdGeneratorTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/SplicingIdGeneratorTest.java @@ -19,17 +19,14 @@ import java.util.List; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.id.SplicingIdGenerator; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.VertexLabel; -import org.apache.hugegraph.structure.HugeVertex; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.id.SplicingIdGenerator; +import org.apache.hugegraph.struct.schema.VertexLabel; +import org.apache.hugegraph.structure.BaseVertex; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.type.define.IdStrategy; -import org.apache.hugegraph.unit.FakeObjects; import org.junit.Test; -import org.mockito.Mockito; import com.google.common.collect.ImmutableList; @@ -37,15 +34,9 @@ public class SplicingIdGeneratorTest { @Test public void testGenerate() { - FakeObjects fakeObjects = new FakeObjects(); - PropertyKey name = fakeObjects.newPropertyKey(IdGenerator.of(1), - "name"); - VertexLabel vertexLabel = fakeObjects.newVertexLabel( - IdGenerator.of(1L), "fake", - IdStrategy.PRIMARY_KEY, name.id()); - HugeVertex vertex = Mockito.mock(HugeVertex.class); - Mockito.when(vertex.schemaLabel()).thenReturn(vertexLabel); - Mockito.when(vertex.name()).thenReturn("marko"); + VertexLabel vertexLabel = new VertexLabel(null, IdGenerator.of(1L), "fake"); + vertexLabel.idStrategy(IdStrategy.PRIMARY_KEY); + BaseVertex vertex = new BaseVertex(IdGenerator.of("1:marko"), vertexLabel); Id vid = SplicingIdGenerator.instance().generate(vertex); Assert.assertEquals(IdGenerator.of("1:marko"), vid); } diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/rocksdb/RocksDBCountersTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/rocksdb/RocksDBCountersTest.java index cd42f2bccf..d7e5fc38a3 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/rocksdb/RocksDBCountersTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/rocksdb/RocksDBCountersTest.java @@ -21,8 +21,8 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.store.rocksdb.RocksDBSessions.Session; import org.apache.hugegraph.backend.store.rocksdb.RocksDBTables; import org.apache.hugegraph.testutil.Assert; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/rocksdb/RocksDBPerfTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/rocksdb/RocksDBPerfTest.java index 4256f290e3..dec44b917e 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/rocksdb/RocksDBPerfTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/rocksdb/RocksDBPerfTest.java @@ -24,7 +24,7 @@ import java.util.Map; import java.util.Random; -import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.backend.store.BackendEntry.BackendColumnIterator; import org.apache.hugegraph.backend.store.rocksdb.RocksDBSessions.Session; import org.junit.Test; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/rocksdb/RocksDBSessionTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/rocksdb/RocksDBSessionTest.java index 16b87d9a1c..700e466453 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/rocksdb/RocksDBSessionTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/rocksdb/RocksDBSessionTest.java @@ -25,7 +25,7 @@ import java.util.Map; import java.util.Random; -import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.backend.store.BackendEntry.BackendColumnIterator; import org.apache.hugegraph.backend.store.rocksdb.RocksDBSessions.Session; import org.apache.hugegraph.testutil.Assert; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/rocksdb/RocksDBTableQueryByIdsTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/rocksdb/RocksDBTableQueryByIdsTest.java index 26598ba497..a50beb24b1 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/rocksdb/RocksDBTableQueryByIdsTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/rocksdb/RocksDBTableQueryByIdsTest.java @@ -27,10 +27,10 @@ import java.util.Set; import org.apache.commons.lang3.tuple.Pair; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.query.IdQuery; -import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.query.IdQuery; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.backend.store.BackendEntry.BackendColumnIterator; import org.apache.hugegraph.backend.store.rocksdb.RocksDBSessions; import org.apache.hugegraph.backend.store.rocksdb.RocksDBTables; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/BinaryBackendEntryTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/BinaryBackendEntryTest.java index 7c8a507021..bcaab2878f 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/BinaryBackendEntryTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/BinaryBackendEntryTest.java @@ -18,7 +18,7 @@ package org.apache.hugegraph.unit.serializer; import org.apache.hugegraph.backend.serializer.BinaryBackendEntry; -import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.unit.BaseUnitTest; @@ -38,6 +38,7 @@ public void testColumns() { entry.columns(ImmutableList.of(col)); Assert.assertEquals(1, entry.columnsSize()); Assert.assertEquals(ImmutableList.of(col), entry.columns()); + Assert.assertSame(col, entry.columns().iterator().next()); entry.columns(ImmutableList.of(col, col)); Assert.assertEquals(3, entry.columnsSize()); diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/BinaryScatterSerializerTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/BinaryScatterSerializerTest.java index a0df546327..224867c71a 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/BinaryScatterSerializerTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/BinaryScatterSerializerTest.java @@ -24,7 +24,6 @@ import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.testutil.Assert; -import org.apache.hugegraph.testutil.Whitebox; import org.apache.hugegraph.unit.BaseUnitTest; import org.apache.hugegraph.unit.FakeObjects; import org.junit.Test; @@ -49,7 +48,7 @@ public void testVertex() { assertCollectionEquals(edge.targetVertex().getProperties(), vertex2.getProperties()); - Whitebox.setInternalState(vertex2, "removed", true); + vertex2.element().removed(true); Assert.assertTrue(vertex2.removed()); BackendEntry entry3 = ser.writeVertex(vertex2); Assert.assertEquals(0, entry3.columnsSize()); diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/BinarySerializerTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/BinarySerializerTest.java index 02d64bcc78..92fa5976bc 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/BinarySerializerTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/BinarySerializerTest.java @@ -19,27 +19,140 @@ import java.util.Arrays; import java.util.Date; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; import java.util.Set; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.backend.BackendColumn; +import org.apache.hugegraph.backend.serializer.BinaryBackendEntry; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.structure.Index; +import org.apache.hugegraph.structure.Index.IdWithExpiredTime; +import org.apache.hugegraph.type.HugeType; +import org.apache.hugegraph.type.define.Directions; +import org.apache.hugegraph.type.define.IdStrategy; +import org.apache.hugegraph.type.define.IndexType; +import org.apache.hugegraph.serializer.BytesBuffer; +import org.apache.hugegraph.type.define.HugeKeys; +import org.apache.hugegraph.util.Bytes; import org.apache.hugegraph.backend.serializer.BinarySerializer; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.config.HugeConfig; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.Userdata; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.Userdata; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeVertex; import org.apache.hugegraph.testutil.Assert; -import org.apache.hugegraph.testutil.Whitebox; import org.apache.hugegraph.type.define.Cardinality; import org.apache.hugegraph.type.define.DataType; import org.apache.hugegraph.unit.BaseUnitTest; import org.apache.hugegraph.unit.FakeObjects; import org.apache.hugegraph.util.DateUtil; import org.junit.Test; +import org.mockito.Mockito; public class BinarySerializerTest extends BaseUnitTest { + @Test + public void testLegacyStoredLabelExpiryReadEliminateAndAppendKeys() throws IOException { + Properties core = labelFixtures("core-rows.properties"); + Properties store = labelFixtures("store-index-rows.properties"); + long expiry = Long.parseLong(core.getProperty("expiry")); + FakeObjects objects = new FakeObjects("legacy-fixture"); + Mockito.when(objects.graph().now()).thenReturn(expiry + 1L); + BinarySerializer serializer = new BinarySerializer(); + for (String name : new String[]{"system", "system.edge"}) { + boolean edge = name.endsWith("edge"); + HugeType base = edge ? HugeType.EDGE : HugeType.VERTEX; + IndexLabel label = IndexLabel.label(base); + HugeType indexType = edge ? HugeType.EDGE_LABEL_INDEX : HugeType.VERTEX_LABEL_INDEX; + Id element = edge ? new EdgeId(IdGenerator.of(1L), Directions.OUT, + IdGenerator.of(5L), IdGenerator.of(5L), "2026!x", + IdGenerator.of(2L)) : IdGenerator.of(1L); + byte[] key = Bytes.fromHex(store.getProperty(name + ".name")); + byte[] value = Bytes.fromHex(store.getProperty(name + ".value")); + byte[] rowId = Bytes.fromHex(core.getProperty("index." + name + ".id")); + BinaryBackendEntry stored = new BinaryBackendEntry(indexType, rowId); + stored.column(key, value); + ConditionQuery query = new ConditionQuery(indexType); + query.eq(HugeKeys.FIELD_VALUES, edge ? 5L : 4L); + Index read = serializer.readIndex(objects.graph(), query, stored); + Assert.assertEquals(element, read.elementId()); + Assert.assertEquals(expiry, read.expiredTime()); + Assert.assertFalse(read.hasTtl()); + Set expired = read.expiredElementIds(); + Assert.assertEquals(1, expired.size()); + Assert.assertTrue(read.elementIds().isEmpty()); + Index removal = read.clone(); + removal.resetElementIds(); + for (IdWithExpiredTime record : expired) { + removal.elementIds(record.id(), record.expiredTime()); + } + BackendEntry removed = serializer.writeIndex(removal); + Assert.assertEquals(1, removed.columnsSize()); + BackendColumn removedColumn = removed.columns().iterator().next(); + Assert.assertArrayEquals(key, removedColumn.name); + Assert.assertNotNull(removedColumn.value); + Assert.assertArrayEquals(BytesBuffer.BYTES_EMPTY, removedColumn.value); + Assert.assertTrue(read.elementIds().isEmpty()); + + Index append = new Index(objects.graph(), label); + append.fieldValues(edge ? 5L : 4L); + append.elementIds(element, expiry); + BackendEntry appended = serializer.writeIndex(append); + BackendColumn appendedColumn = appended.columns().iterator().next(); + Assert.assertArrayEquals(key, appendedColumn.name); + Assert.assertArrayEquals(Bytes.fromHex(core.getProperty( + "index." + name + ".column.0.name")), appendedColumn.name); + Assert.assertNotNull(appendedColumn.value); + Assert.assertArrayEquals(Bytes.fromHex(core.getProperty( + "index." + name + ".column.0.value")), appendedColumn.value); + // Core append and TTL elimination address the original Store cell, + // so they cannot introduce a second key carrying an expiry suffix. + Assert.assertArrayEquals(removedColumn.name, appendedColumn.name); + Index appendedRead = serializer.readIndex(objects.graph(), query, appended); + Assert.assertEquals(1, appendedRead.elementIds().size()); + Assert.assertEquals(element, appendedRead.elementId()); + Assert.assertEquals(0L, appendedRead.expiredTime()); + } + } + + @Test + public void testOrdinaryIndexWriterProducesNonNullKvValue() { + FakeObjects objects = new FakeObjects(); + Id fieldId = IdGenerator.of(1L); + Id baseId = IdGenerator.of(2L); + objects.newPropertyKey(fieldId, "age", DataType.INT, Cardinality.SINGLE); + objects.newVertexLabel(baseId, "person", IdStrategy.CUSTOMIZE_NUMBER, fieldId); + IndexLabel label = objects.newIndexLabel(IdGenerator.of(3L), "by-age", HugeType.VERTEX_LABEL, + baseId, IndexType.SECONDARY, fieldId); + Index index = new Index(objects.graph(), label); + index.fieldValues("42"); + index.elementIds(IdGenerator.of(4L)); + + BackendEntry entry = new BinarySerializer().writeIndex(index); + Assert.assertEquals(1, entry.columnsSize()); + BackendColumn column = entry.columns().iterator().next(); + Assert.assertNotNull(column.name); + Assert.assertNotNull(column.value); + Assert.assertArrayEquals(BytesBuffer.BYTES_EMPTY, column.value); + } + + private static Properties labelFixtures(String name) throws IOException { + Properties fixtures = new Properties(); + try (InputStream input = BinarySerializerTest.class.getResourceAsStream( + "/compatibility/2f827d6e8/" + name)) { + Assert.assertNotNull(input); + fixtures.load(input); + } + return fixtures; + } + @Test public void testVertex() { HugeConfig config = FakeObjects.newConfig(); @@ -58,7 +171,7 @@ public void testVertex() { assertCollectionEquals(edge.targetVertex().getProperties(), vertex2.getProperties()); - Whitebox.setInternalState(vertex2, "removed", true); + vertex2.element().removed(true); Assert.assertTrue(vertex2.removed()); BackendEntry entry3 = ser.writeVertex(vertex2); Assert.assertEquals(0, entry3.columnsSize()); @@ -107,7 +220,7 @@ public void testVertexForPartition() { assertCollectionEquals(edge.targetVertex().getProperties(), vertex2.getProperties()); - Whitebox.setInternalState(vertex2, "removed", true); + vertex2.element().removed(true); Assert.assertTrue(vertex2.removed()); BackendEntry entry3 = ser.writeVertex(vertex2); Assert.assertEquals(0, entry3.columnsSize()); diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/BytesBufferTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/BytesBufferTest.java index 8d82a7c6c8..af438b578f 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/BytesBufferTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/BytesBufferTest.java @@ -30,13 +30,13 @@ import org.apache.hugegraph.HugeFactory; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.id.IdGenerator.UuidId; -import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.id.IdGenerator.UuidId; +import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.config.CoreOptions; import org.apache.hugegraph.config.HugeConfig; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.type.define.Cardinality; import org.apache.hugegraph.type.define.DataType; @@ -921,77 +921,77 @@ public void testProperty() { PropertyKey pkey = genPkey(DataType.BOOLEAN); Object value = true; byte[] bytes = genBytes("01"); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); value = false; bytes = genBytes("00"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genPkey(DataType.BYTE); value = (byte) 127; bytes = genBytes("7f"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genPkey(DataType.INT); value = 127; bytes = genBytes("7f"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genPkey(DataType.INT); value = 128; bytes = genBytes("8100"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genPkey(DataType.FLOAT); value = 1.0f; bytes = genBytes("3f800000"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genPkey(DataType.FLOAT); value = 3.14f; bytes = genBytes("4048f5c3"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genPkey(DataType.FLOAT); value = -1.0f; bytes = genBytes("bf800000"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genPkey(DataType.FLOAT); value = Float.MAX_VALUE; bytes = genBytes("7f7fffff"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genPkey(DataType.LONG); value = 127L; bytes = genBytes("7f"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genPkey(DataType.DOUBLE); value = 3.14d; bytes = genBytes("40091eb851eb851f"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genPkey(DataType.DATE); Calendar c = Calendar.getInstance(TimeZone.getTimeZone("Beijing")); @@ -999,53 +999,53 @@ public void testProperty() { value = c.getTime(); bytes = genBytes("adc9a098e22a"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genPkey(DataType.TEXT); value = "abc"; bytes = genBytes("03616263"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genPkey(DataType.BLOB); value = genBytes("001199aabbcc"); bytes = genBytes("06001199aabbcc"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); Assert.assertEquals(Blob.wrap((byte[]) value), - BytesBuffer.wrap(bytes).readProperty(pkey)); + BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genPkey(DataType.UUID); value = UUID.fromString("3cfcafc8-7906-4ab7-a207-4ded056f58de"); bytes = genBytes("3cfcafc879064ab7a2074ded056f58de"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genPkey(DataType.OBJECT); value = new Point(3, 8); bytes = genBytes("1301006a6176612e6177742e506f696ef4010610"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genPkey(DataType.OBJECT); value = UUID.fromString("3cfcafc8-7906-4ab7-a207-4ded056f58de"); bytes = genBytes("2101006a6176612e7574696c2e555549c401" + "3cfcafc879064ab7a2074ded056f58de"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genPkey(DataType.OBJECT); value = new int[]{1, 3, 8}; bytes = genBytes("0901005bc90104020610"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); Assert.assertArrayEquals((int[]) value, (int[]) - BytesBuffer.wrap(bytes).readProperty(pkey)); + BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); } @Test @@ -1054,50 +1054,50 @@ public void testPropertyWithList() { PropertyKey pkey = genListPkey(DataType.BOOLEAN); Object value = ImmutableList.of(true, false); byte[] bytes = genBytes("020100"); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genListPkey(DataType.BYTE); value = ImmutableList.of(); bytes = genBytes("00"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genListPkey(DataType.BYTE); value = ImmutableList.of((byte) 127, (byte) 128); bytes = genBytes("027f8fffffff00"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genListPkey(DataType.INT); value = ImmutableList.of(127, 128); bytes = genBytes("027f8100"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genListPkey(DataType.FLOAT); value = ImmutableList.of(1.0f, 3.14f); bytes = genBytes("023f8000004048f5c3"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genListPkey(DataType.LONG); value = ImmutableList.of(127L, 128L); bytes = genBytes("027f8100"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genListPkey(DataType.DOUBLE); value = ImmutableList.of(1.0d, 3.14d); bytes = genBytes("023ff000000000000040091eb851eb851f"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genListPkey(DataType.DATE); Calendar c = Calendar.getInstance(TimeZone.getTimeZone("Beijing")); @@ -1105,22 +1105,22 @@ public void testPropertyWithList() { value = ImmutableList.of(c.getTime(), c.getTime()); bytes = genBytes("02adc9a098e22aadc9a098e22a"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genListPkey(DataType.TEXT); value = ImmutableList.of("abc", "123"); bytes = genBytes("020361626303313233"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genListPkey(DataType.BLOB); value = ImmutableList.of(genBytes("001199aabbcc"), genBytes("5566")); bytes = genBytes("0206001199aabbcc025566"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - List list = (List) BytesBuffer.wrap(bytes).readProperty(pkey); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + List list = (List) BytesBuffer.wrap(bytes).readSchemaProperty(pkey); Assert.assertEquals(Blob.wrap(genBytes("001199aabbcc")), list.get(0)); Assert.assertEquals(Blob.wrap(genBytes("5566")), list.get(1)); @@ -1130,23 +1130,23 @@ public void testPropertyWithList() { bytes = genBytes("023cfcafc879064ab7a2074ded056f58de" + "3cfcafc879064ab7a2074ded056f58de"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genListPkey(DataType.OBJECT); value = ImmutableList.of(new Point(3, 8), new Point(3, 9)); bytes = genBytes("021301006a6176612e6177742e506f696ef4010610" + "1301006a6176612e6177742e506f696ef4010612"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genListPkey(DataType.OBJECT); value = ImmutableList.of(new int[]{1, 3}, new int[]{2, 5}); bytes = genBytes("020801005bc9010302060801005bc90103040a"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - list = (List) BytesBuffer.wrap(bytes).readProperty(pkey); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + list = (List) BytesBuffer.wrap(bytes).readSchemaProperty(pkey); Assert.assertArrayEquals(new int[]{1, 3}, (int[]) list.get(0)); Assert.assertArrayEquals(new int[]{2, 5}, (int[]) list.get(1)); } @@ -1157,50 +1157,50 @@ public void testPropertyWithSet() { PropertyKey pkey = genSetPkey(DataType.BOOLEAN); Object value = ImmutableSet.of(true, false); byte[] bytes = genBytes("020100"); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genSetPkey(DataType.BYTE); value = ImmutableSet.of(); bytes = genBytes("00"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genSetPkey(DataType.BYTE); value = ImmutableSet.of((byte) 127, (byte) 128); bytes = genBytes("027f8fffffff00"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genSetPkey(DataType.INT); value = ImmutableSet.of(127, 128); bytes = genBytes("027f8100"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genSetPkey(DataType.FLOAT); value = ImmutableSet.of(1.0f, 3.14f); bytes = genBytes("023f8000004048f5c3"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genSetPkey(DataType.LONG); value = ImmutableSet.of(127L, 128L); bytes = genBytes("027f8100"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genSetPkey(DataType.DOUBLE); value = ImmutableSet.of(1.0d, 3.14d); bytes = genBytes("023ff000000000000040091eb851eb851f"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genSetPkey(DataType.DATE); Calendar c = Calendar.getInstance(TimeZone.getTimeZone("Beijing")); @@ -1208,22 +1208,22 @@ public void testPropertyWithSet() { value = ImmutableSet.of(c.getTime(), c.getTime()); bytes = genBytes("01adc9a098e22a"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genSetPkey(DataType.TEXT); value = ImmutableSet.of("abc", "123"); bytes = genBytes("020361626303313233"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genSetPkey(DataType.BLOB); value = ImmutableSet.of(genBytes("001199aabbcc"), genBytes("5566")); bytes = genBytes("0206001199aabbcc025566"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Set set = (Set) BytesBuffer.wrap(bytes).readProperty(pkey); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Set set = (Set) BytesBuffer.wrap(bytes).readSchemaProperty(pkey); Iterator iterator = set.iterator(); Assert.assertEquals(Blob.wrap(genBytes("001199aabbcc")), iterator.next()); @@ -1234,23 +1234,23 @@ public void testPropertyWithSet() { value = ImmutableSet.of(uuid, uuid); bytes = genBytes("013cfcafc879064ab7a2074ded056f58de"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genSetPkey(DataType.OBJECT); value = ImmutableSet.of(new Point(3, 8), new Point(3, 9)); bytes = genBytes("021301006a6176612e6177742e506f696ef4010610" + "1301006a6176612e6177742e506f696ef4010612"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - Assert.assertEquals(value, BytesBuffer.wrap(bytes).readProperty(pkey)); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + Assert.assertEquals(value, BytesBuffer.wrap(bytes).readSchemaProperty(pkey)); pkey = genSetPkey(DataType.OBJECT); value = ImmutableSet.of(new int[]{1, 3}, new int[]{2, 5}); bytes = genBytes("020801005bc9010302060801005bc90103040a"); buf.forReadWritten(); - Assert.assertArrayEquals(bytes, buf.writeProperty(pkey, value).bytes()); - set = (Set) BytesBuffer.wrap(bytes).readProperty(pkey); + Assert.assertArrayEquals(bytes, buf.writeSchemaProperty(pkey, value).bytes()); + set = (Set) BytesBuffer.wrap(bytes).readSchemaProperty(pkey); iterator = set.iterator(); Assert.assertArrayEquals(new int[]{1, 3}, (int[]) iterator.next()); Assert.assertArrayEquals(new int[]{2, 5}, (int[]) iterator.next()); diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/HugeGraphSONModuleTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/HugeGraphSONModuleTest.java index 5b7b5fa4ab..8f0af5417a 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/HugeGraphSONModuleTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/HugeGraphSONModuleTest.java @@ -25,13 +25,13 @@ import java.util.Map; import java.util.UUID; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.backend.id.IdGenerator.LongId; -import org.apache.hugegraph.backend.id.IdGenerator.StringId; -import org.apache.hugegraph.backend.id.IdGenerator.UuidId; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.id.IdGenerator.LongId; +import org.apache.hugegraph.id.IdGenerator.StringId; +import org.apache.hugegraph.id.IdGenerator.UuidId; import org.apache.hugegraph.io.HugeGraphIoRegistry; -import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.unit.BaseUnitTest; import org.apache.hugegraph.unit.FakeObjects; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/SerializerFactoryTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/SerializerFactoryTest.java index 15294439db..2a241e30e2 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/SerializerFactoryTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/SerializerFactoryTest.java @@ -25,7 +25,7 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.backend.serializer.AbstractSerializer; import org.apache.hugegraph.backend.serializer.BinaryScatterSerializer; import org.apache.hugegraph.backend.serializer.BinarySerializer; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/StoreSerializerTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/StoreSerializerTest.java index 321f018de2..9d4497aa83 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/StoreSerializerTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/StoreSerializerTest.java @@ -20,7 +20,7 @@ import java.util.Iterator; import org.apache.hugegraph.backend.serializer.BinaryBackendEntry; -import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.backend.store.BackendAction; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.backend.store.BackendMutation; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/TableBackendEntryTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/TableBackendEntryTest.java index 2771764d48..2c27643d26 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/TableBackendEntryTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/TableBackendEntryTest.java @@ -18,10 +18,10 @@ package org.apache.hugegraph.unit.serializer; import org.apache.commons.lang3.NotImplementedException; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.serializer.TableBackendEntry; -import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Cardinality; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/TextBackendEntryTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/TextBackendEntryTest.java index 4700ca4afa..e016588bc5 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/TextBackendEntryTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/TextBackendEntryTest.java @@ -17,9 +17,9 @@ package org.apache.hugegraph.unit.serializer; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.serializer.TextBackendEntry; -import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.HugeKeys; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/TextSerializerTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/TextSerializerTest.java index 4d55a9b046..8e5af99921 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/TextSerializerTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/TextSerializerTest.java @@ -21,12 +21,12 @@ import java.util.Date; import java.util.Set; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.backend.serializer.TextSerializer; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.config.HugeConfig; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.Userdata; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.Userdata; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.type.define.Cardinality; import org.apache.hugegraph.type.define.DataType; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/traversal/ShortestPathTraverserTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/traversal/ShortestPathTraverserTest.java index e3630a1109..c527212c53 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/traversal/ShortestPathTraverserTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/traversal/ShortestPathTraverserTest.java @@ -27,9 +27,9 @@ import java.util.Map; import org.apache.hugegraph.HugeGraph; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.config.CoreOptions; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.testutil.Assert; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/util/JsonUtilTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/util/JsonUtilTest.java index 722f747ed8..990841d928 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/util/JsonUtilTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/util/JsonUtilTest.java @@ -26,13 +26,13 @@ import java.util.UUID; import org.apache.commons.lang3.tuple.Pair; -import org.apache.hugegraph.backend.id.EdgeId; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; -import org.apache.hugegraph.schema.EdgeLabel; -import org.apache.hugegraph.schema.IndexLabel; -import org.apache.hugegraph.schema.PropertyKey; -import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.structure.HugeEdge; import org.apache.hugegraph.structure.HugeEdgeProperty; import org.apache.hugegraph.structure.HugeProperty; @@ -40,7 +40,6 @@ import org.apache.hugegraph.structure.HugeVertexProperty; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.testutil.Utils; -import org.apache.hugegraph.testutil.Whitebox; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Cardinality; import org.apache.hugegraph.type.define.DataType; @@ -251,7 +250,7 @@ public void testSerializeVertexWithNumberId() { age.id(), new HugeVertexProperty<>(vertex, age, 29), city.id(), new HugeVertexProperty<>(vertex, city, "Beijing") ); - Whitebox.setInternalState(vertex, "properties", properties); + properties.values().forEach(vertex::setProperty); String json = JsonUtil.toJson(vertex); Assert.assertEquals("{\"id\":123456,\"label\":\"person\"," + @@ -291,8 +290,7 @@ public void testSerializeEdge() { Id id = EdgeId.parse("L123456>1>1>>L987654"); HugeEdge edge = new HugeEdge(fakeObject.graph(), id, el); - Whitebox.setInternalState(edge, "sourceVertex", source); - Whitebox.setInternalState(edge, "targetVertex", target); + edge.vertices(true, source, target); Date dateValue = Utils.date("2019-03-12"); MutableIntObjectMap> properties = @@ -300,7 +298,7 @@ public void testSerializeEdge() { date.id(), new HugeEdgeProperty<>(edge, date, dateValue), weight.id(), new HugeEdgeProperty<>(edge, weight, 0.8) ); - Whitebox.setInternalState(edge, "properties", properties); + properties.values().forEach(edge::setProperty); String json = JsonUtil.toJson(edge); Assert.assertEquals("{\"id\":\"L123456>1>1>>L987654\"," + diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/util/collection/CollectionFactoryTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/util/collection/CollectionFactoryTest.java index 9e4697d81a..917a3d6d44 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/util/collection/CollectionFactoryTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/util/collection/CollectionFactoryTest.java @@ -25,7 +25,7 @@ import java.util.Map; import java.util.Set; -import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.testutil.Whitebox; import org.apache.hugegraph.type.define.CollectionType; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/util/collection/IdSetTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/util/collection/IdSetTest.java index 2a9082c831..02ceaaea66 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/util/collection/IdSetTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/util/collection/IdSetTest.java @@ -23,8 +23,8 @@ import java.util.UUID; import org.apache.commons.lang.RandomStringUtils; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.testutil.Whitebox; import org.apache.hugegraph.type.define.CollectionType; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/util/collection/ObjectIntMappingTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/util/collection/ObjectIntMappingTest.java index 4d74c5bd85..f712e9421b 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/util/collection/ObjectIntMappingTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/util/collection/ObjectIntMappingTest.java @@ -23,8 +23,8 @@ import java.util.UUID; import org.apache.commons.lang.RandomStringUtils; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.testutil.Assert; import org.apache.hugegraph.util.collection.ObjectIntMapping; import org.apache.hugegraph.util.collection.ObjectIntMappingFactory; diff --git a/hugegraph-server/hugegraph-test/src/main/resources/compatibility/2f827d6e8/README.md b/hugegraph-server/hugegraph-test/src/main/resources/compatibility/2f827d6e8/README.md new file mode 100644 index 0000000000..5f5868f933 --- /dev/null +++ b/hugegraph-server/hugegraph-test/src/main/resources/compatibility/2f827d6e8/README.md @@ -0,0 +1,22 @@ + + +# Historical fixtures for Server label-index tests + +`BinarySerializerTest.testLegacyStoredLabelExpiryReadEliminateAndAppendKeys` uses `core-rows.properties` and `store-index-rows.properties` to recover Store expiry values and retain original label-index keys through elimination and append. + +These byte-identical copies allow tests to load fixtures from this module's own resource classpath. Keep them synchronized with the shared resources. The [canonical fixture guide](../../../../../../../hugegraph-struct/src/test/resources/compatibility/2f827d6e8/README.md) contains the pinned source revision, historical producers, regeneration instructions, compatibility limits and SHA-256 checksums. Regenerate against those historical writers only, never the current writer. diff --git a/hugegraph-server/hugegraph-test/src/main/resources/compatibility/2f827d6e8/core-rows.properties b/hugegraph-server/hugegraph-test/src/main/resources/compatibility/2f827d6e8/core-rows.properties new file mode 100644 index 0000000000..fd489e58c1 --- /dev/null +++ b/hugegraph-server/hugegraph-test/src/main/resources/compatibility/2f827d6e8/core-rows.properties @@ -0,0 +1,108 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # +now=1609459200000 +expiry=1609459260000 +vertex.type=VERTEX +vertex.id=0801 +vertex.ttl=60000 +vertex.columns=1 +vertex.column.0.name=0801 +vertex.column.0.value=08040301070203078fffffff7f0703028fffffff7f07aeebd9fdb460 +edge.out.type=EDGE_OUT +edge.out.id=08018208050805323032362178000802 +edge.out.ttl=60000 +edge.out.columns=1 +edge.out.column.0.name=08018208050805323032362178000802 +edge.out.column.0.value=0301070203078fffffff7f0703028fffffff7f07aeebd9fdb460 +edge.in.type=EDGE_IN +edge.in.id=08028c08050805323032362178000801 +edge.in.ttl=60000 +edge.in.columns=1 +edge.in.column.0.name=08028c08050805323032362178000801 +edge.in.column.0.value=0301070203078fffffff7f0703028fffffff7f07aeebd9fdb460 +olap.type=OLAP +olap.id=0801 +olap.ttl=0 +olap.columns=1 +olap.column.0.name=0801 +olap.column.0.value=092a +index.secondary.type=SECONDARY_INDEX +index.secondary.id=53493a363a616c69636500 +index.secondary.ttl=60000 +index.secondary.columns=1 +index.secondary.column.0.name=53493a363a616c696365000801aeebd9fdb460 +index.secondary.column.0.value= +index.int.type=RANGE_INT_INDEX +index.int.id=a00000000780000007 +index.int.ttl=60000 +index.int.columns=1 +index.int.column.0.name=a000000007800000070801aeebd9fdb460 +index.int.column.0.value= +index.long.type=RANGE_LONG_INDEX +index.long.id=a2000000088000000000000007 +index.long.ttl=60000 +index.long.columns=1 +index.long.column.0.name=a20000000880000000000000070801aeebd9fdb460 +index.long.column.0.value= +vertex.untimed.type=VERTEX +vertex.untimed.id=0803 +vertex.untimed.ttl=0 +vertex.untimed.columns=1 +vertex.untimed.column.0.name=0803 +vertex.untimed.column.0.value=080a0301070203078fffffff7f0703028fffffff7f07 +edge.untimed.type=EDGE_OUT +edge.untimed.id=080182080b080b000802 +edge.untimed.ttl=0 +edge.untimed.columns=1 +edge.untimed.column.0.name=080182080b080b000802 +edge.untimed.column.0.value=0301070203078fffffff7f0703028fffffff7f07 +index.secondary.untimed.type=SECONDARY_INDEX +index.secondary.untimed.id=53493a433a616c69636500 +index.secondary.untimed.ttl=0 +index.secondary.untimed.columns=1 +index.secondary.untimed.column.0.name=53493a433a616c696365000801 +index.secondary.untimed.column.0.value= +index.int.untimed.type=RANGE_INT_INDEX +index.int.untimed.id=a00000000d80000007 +index.int.untimed.ttl=0 +index.int.untimed.columns=1 +index.int.untimed.column.0.name=a00000000d800000070801 +index.int.untimed.column.0.value= +index.long.untimed.type=RANGE_LONG_INDEX +index.long.untimed.id=a20000000e8000000000000007 +index.long.untimed.ttl=0 +index.long.untimed.columns=1 +index.long.untimed.column.0.name=a20000000e80000000000000070801 +index.long.untimed.column.0.value= +index.hashed.type=SECONDARY_INDEX +index.hashed.id=53493a463a323234303534613200 +index.hashed.ttl=60000 +index.hashed.columns=1 +index.hashed.column.0.name=53493a463a3232343035346132000801aeebd9fdb460 +index.hashed.column.0.value=6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d +index.system.type=VERTEX_LABEL_INDEX +index.system.id=56493a2d313a3400 +index.system.ttl=0 +index.system.columns=1 +index.system.column.0.name=56493a2d313a34000801 +index.system.column.0.value= +index.system.edge.type=EDGE_LABEL_INDEX +index.system.edge.id=45493a2d323a3500 +index.system.edge.ttl=0 +index.system.edge.columns=1 +index.system.edge.column.0.name=45493a2d323a35007e08018208050805323032362178000802 +index.system.edge.column.0.value= diff --git a/hugegraph-server/hugegraph-test/src/main/resources/compatibility/2f827d6e8/store-index-rows.properties b/hugegraph-server/hugegraph-test/src/main/resources/compatibility/2f827d6e8/store-index-rows.properties new file mode 100644 index 0000000000..7f5a599ed4 --- /dev/null +++ b/hugegraph-server/hugegraph-test/src/main/resources/compatibility/2f827d6e8/store-index-rows.properties @@ -0,0 +1,31 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # +secondary.name=53493a363a616c696365000801 +secondary.value=00414141426472732f576d413d +secondary.expiry=1609459260000 +int.name=a000000007800000070801 +int.value=00414141426472732f576d413d +int.expiry=1609459260000 +long.name=a20000000880000000000000070801 +long.value=00414141426472732f576d413d +long.expiry=1609459260000 +system.name=56493a2d313a34000801 +system.value=00414141426472732f576d413d +system.expiry=1609459260000 +system.edge.name=45493a2d323a35007e08018208050805323032362178000802 +system.edge.value=00414141426472732f576d413d +system.edge.expiry=1609459260000 diff --git a/hugegraph-store/docs/development-guide.md b/hugegraph-store/docs/development-guide.md index bdc36e07ef..63d6be8727 100644 --- a/hugegraph-store/docs/development-guide.md +++ b/hugegraph-store/docs/development-guide.md @@ -796,11 +796,17 @@ When adding third-party dependencies: 5. Update `install-dist/scripts/dependency/known-dependencies.txt` **Run Dependency Check**: + +Run from the repository root after building Server, PD and Store distributions for the current revision: + ```bash -cd install-dist/scripts/dependency -./regenerate_known_dependencies.sh +mvn install -DskipTests -Dmaven.javadoc.skip=true +bash install-dist/scripts/dependency/regenerate_known_dependencies.sh current-dependencies.txt +bash install-dist/scripts/dependency/check_dependencies.sh ``` +This build prepares artifacts without running tests. The collector combines the Maven runtime union with actual distribution libraries, including nested Spring Boot jars; missing current-revision distribution libraries fail. Review both added and removed names against `known-dependencies.txt`, including license/NOTICE changes, before updating the approved list. Comparison is strict, and source-only inspection is insufficient; verify the release platform/profile variants too. + ### Documentation **When to Update Docs**: diff --git a/hugegraph-store/hg-store-client/src/main/java/org/apache/hugegraph/store/client/query/QueryExecutor.java b/hugegraph-store/hg-store-client/src/main/java/org/apache/hugegraph/store/client/query/QueryExecutor.java index b4102bb373..9f6fd0dc8b 100644 --- a/hugegraph-store/hg-store-client/src/main/java/org/apache/hugegraph/store/client/query/QueryExecutor.java +++ b/hugegraph-store/hg-store-client/src/main/java/org/apache/hugegraph/store/client/query/QueryExecutor.java @@ -45,6 +45,7 @@ import org.apache.hugegraph.store.grpc.query.Index; import org.apache.hugegraph.store.grpc.query.QueryRequest; import org.apache.hugegraph.store.grpc.query.QueryResponse; +import org.apache.hugegraph.store.grpc.query.QueryResultFormat; import org.apache.hugegraph.store.grpc.query.ScanType; import org.apache.hugegraph.store.grpc.query.ScanTypeParam; import org.apache.hugegraph.store.query.BaseElementComparator; @@ -191,7 +192,8 @@ private StreamKvIterator getIterator(String address, QueryRequest r public boolean hasNext() { if (element == null) { while (itr.hasNext()) { - element = fromKv(request.getTable(), itr.next(), hasAgg); + element = fromKv(request.getTable(), itr.next(), hasAgg, + !QueryResultFormat.returnsTaggedElements(request)); if (element != null) { break; } @@ -447,7 +449,7 @@ private static List getOrCreate(List list) { return new ArrayList<>(); } - private BaseElement fromKv(String table, Kv kv, boolean isAgg) { + private BaseElement fromKv(String table, Kv kv, boolean isAgg, boolean schemaRow) { if (isAgg) { return KvElement.of(KvSerializer.fromBytes(kv.getKey().toByteArray()), KvSerializer.fromObjectBytes(kv.getValue().toByteArray())); @@ -457,9 +459,11 @@ private BaseElement fromKv(String table, Kv kv, boolean isAgg) { BackendColumn.of(kv.getKey().toByteArray(), kv.getValue().toByteArray()); try { if (IN_EDGE_TABLE.equals(table) || OUT_EDGE_TABLE.equals(table)) { - return serializer.parseEdge(this.supplier, backendColumn, null, true); + return schemaRow ? serializer.parseSchemaEdge(this.supplier, backendColumn, null, true) : + serializer.parseEdge(this.supplier, backendColumn, null, true); } - return serializer.parseVertex(this.supplier, backendColumn, null); + return schemaRow ? serializer.parseSchemaVertex(this.supplier, backendColumn, null) : + serializer.parseVertex(this.supplier, backendColumn, null); } catch (Exception e) { log.error("parse element error,", e); return null; @@ -539,7 +543,7 @@ public boolean hasNext() { @Override public BaseElement next() { - return fromKv(query.getTable(), data.next(), false); + return fromKv(query.getTable(), data.next(), false, true); } }; }) @@ -574,7 +578,7 @@ public boolean hasNext() { @Override public BaseElement next() { - return fromKv(query.getTable(), data.next(), true); + return fromKv(query.getTable(), data.next(), true, false); } }; }) diff --git a/hugegraph-store/hg-store-core/pom.xml b/hugegraph-store/hg-store-core/pom.xml index cffafaf446..6d456af251 100644 --- a/hugegraph-store/hg-store-core/pom.xml +++ b/hugegraph-store/hg-store-core/pom.xml @@ -113,11 +113,6 @@ ${revision} compile - - org.apache.hugegraph - hugegraph-core - ${revision} - org.apache.hugegraph hg-store-common diff --git a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/HgStoreEngine.java b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/HgStoreEngine.java index 03eb5fe77b..948b1e8f43 100644 --- a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/HgStoreEngine.java +++ b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/HgStoreEngine.java @@ -232,7 +232,11 @@ public void shutdown() { // exists even shut down. rpcServer = null; // close all db session - RocksDBFactory.getInstance().releaseAllGraphDB(); + try { + RocksDBFactory.getInstance().releaseAllGraphDB(); + } finally { + BusinessHandlerImpl.closeSchemaResources(); + } } public void snapshotForTest() { diff --git a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/AbstractSelectIterator.java b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/AbstractSelectIterator.java index 40f909b0d2..47ea660ca7 100644 --- a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/AbstractSelectIterator.java +++ b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/AbstractSelectIterator.java @@ -17,6 +17,9 @@ package org.apache.hugegraph.store.business; +import java.util.Objects; + +import org.apache.hugegraph.HugeGraphSupplier; import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.rocksdb.access.ScanIterator; import org.apache.hugegraph.serializer.BinaryElementSerializer; @@ -29,8 +32,10 @@ public abstract class AbstractSelectIterator implements ScanIterator { protected ScanIterator iterator; protected BinaryElementSerializer serializer; + protected final HugeGraphSupplier graph; - public AbstractSelectIterator() { + public AbstractSelectIterator(HugeGraphSupplier graph) { + this.graph = Objects.requireNonNull(graph, "graph"); this.serializer = new BinaryElementSerializer(); } @@ -39,9 +44,9 @@ public BaseElement parseEntry(BackendColumn column, boolean isVertex) { throw new IllegalArgumentException("BackendColumn cannot be null"); } if (isVertex) { - return serializer.parseVertex(null, column, null); + return serializer.parseSchemaVertex(this.graph, column, null); } else { - return serializer.parseEdge(null, column, null, true); + return serializer.parseSchemaEdge(this.graph, column, null, true); } } } diff --git a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/BusinessHandlerImpl.java b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/BusinessHandlerImpl.java index 38bad3b9e8..bc446afb31 100644 --- a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/BusinessHandlerImpl.java +++ b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/BusinessHandlerImpl.java @@ -61,7 +61,6 @@ import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.apache.hugegraph.HugeGraphSupplier; -import org.apache.hugegraph.SchemaGraph; import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.config.OptionSpace; @@ -112,6 +111,8 @@ import org.apache.hugegraph.store.query.QueryTypeParam; import org.apache.hugegraph.store.raft.RaftClosure; import org.apache.hugegraph.store.raft.RaftOperation; +import org.apache.hugegraph.store.schema.SchemaDriver; +import org.apache.hugegraph.store.schema.SchemaGraph; import org.apache.hugegraph.store.term.Bits; import org.apache.hugegraph.store.term.HgPair; import org.apache.hugegraph.store.util.DefaultThreadFactory; @@ -294,20 +295,32 @@ public static HugeGraphSupplier getGraphSupplier(String graph) { return mockGraphSupplier; } - if (GRAPH_SUPPLIER_CACHE.get(graph) == null) { + if (graph == null) { + throw new HgStoreException("Graph must include graph space and graph name"); + } + HugeGraphSupplier supplier = GRAPH_SUPPLIER_CACHE.get(graph); + if (supplier == null) { synchronized (BusinessHandlerImpl.class) { - if (GRAPH_SUPPLIER_CACHE.get(graph) == null) { + supplier = GRAPH_SUPPLIER_CACHE.get(graph); + if (supplier == null) { + if (HgStoreEngine.getInstance().isClosing().get()) { + throw new HgStoreException("Store is closing"); + } + String[] parts = graph.split("/", -1); + if (parts.length < 2 || parts[0].isEmpty() || parts[1].isEmpty()) { + throw new HgStoreException("Graph must include graph space and graph name: " + graph); + } var config = PDConfig.of(HgStoreEngine.getInstance().getOption().getPdAddress()); config.setAuthority(DefaultPdProvider.name, DefaultPdProvider.authority); - String[] parts = graph.split("/"); - assert (parts.length > 1); - GRAPH_SUPPLIER_CACHE.put(graph, new SchemaGraph(parts[0], parts[1], config)); + supplier = new SchemaGraph(parts[0], parts[1], config, + HgStoreEngine.getInstance().getOption().getPdCluster()); + GRAPH_SUPPLIER_CACHE.put(graph, supplier); } } } - return GRAPH_SUPPLIER_CACHE.get(graph); + return supplier; } @Override @@ -546,7 +559,17 @@ public ScanIterator scan(String graph, int code, String table, byte[] start, byt @Override public GraphStoreIterator scan(ScanPartitionRequest spr) throws HgStoreException { - return new GraphStoreIterator(scanOriginal(spr), spr); + ScanIterator original = scanOriginal(spr); + try { + return new GraphStoreIterator(original, spr); + } catch (RuntimeException failure) { + try { + original.close(); + } catch (RuntimeException closeFailure) { + failure.addSuppressed(closeFailure); + } + throw failure; + } } private ToLongFunction getBaseElementHashFunction() { @@ -739,7 +762,7 @@ public ScanIterator indexIntersection(String graph, String table, List { - if (filterTTL && isIndexExpire(column, now)) { + if (filterTTL && isIndexExpire(graph, column, now)) { return null; } - // todo: Use parseIndex(BackendColumn indexCol) later - var index = serializer.parseIndex(getGraphSupplier(graph), - BackendColumn.of(column.name, column.value), null); + var index = serializer.parseSchemaIndex(getGraphSupplier(graph), + BackendColumn.of(column.name, column.value)); if (param.getIdPrefix() != null && !Bytes.prefixWith(index.elementId().asBytes(), param.getIdPrefix())) { @@ -916,7 +938,7 @@ private ScanIterator scanIndexToBaseElement(String graph, QueryTypeParam param, param.getBoundary()) : scanPrefix(graph, param.getCode(), INDEX_TABLE, param.getStart(), param.getBoundary()), column -> { - if (filterTTL && isIndexExpire(column, now)) { + if (filterTTL && isIndexExpire(graph, column, now)) { return null; } @@ -934,8 +956,8 @@ private ScanIterator scanIndexToBaseElement(String graph, QueryTypeParam param, }, "trans-index-to-base-element"); } - private boolean isIndexExpire(RocksDBSession.BackendColumn column, long now) { - var e = directBinarySerializer.parseIndex(column.name, column.value); + private boolean isIndexExpire(String graph, RocksDBSession.BackendColumn column, long now) { + var e = directBinarySerializer.parseSchemaIndex(getGraphSupplier(graph), column.name, column.value); return e.expiredTime() > 0 && e.expiredTime() < now; } @@ -1131,9 +1153,13 @@ public void closeDB(int partId) { @Override public void closeAll() { log.warn("close all db!!! "); - factory.getGraphNames().forEach(dbName -> { - factory.releaseGraphDB(dbName); - }); + try { + factory.getGraphNames().forEach(dbName -> { + factory.releaseGraphDB(dbName); + }); + } finally { + closeSchemaResources(); + } } @Override @@ -1983,7 +2009,15 @@ private void release() { } } - public static void clearCache() { + public static synchronized void clearCache() { GRAPH_SUPPLIER_CACHE.clear(); } + + public static synchronized void closeSchemaResources() { + try { + SchemaDriver.destroy(); + } finally { + GRAPH_SUPPLIER_CACHE.clear(); + } + } } diff --git a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/DataManagerImpl.java b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/DataManagerImpl.java index 3a4b5ac26c..a27e6892ff 100644 --- a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/DataManagerImpl.java +++ b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/DataManagerImpl.java @@ -51,6 +51,7 @@ import org.apache.hugegraph.store.raft.RaftOperation; import org.apache.hugegraph.store.term.Bits; import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; import org.apache.hugegraph.structure.BaseEdge; import org.apache.hugegraph.structure.BaseElement; import org.apache.hugegraph.structure.BaseVertex; @@ -292,17 +293,21 @@ public Status doBuildIndex(Metapb.BuildIndexParam param, Metapb.Partition source try { if (param.getIsVertexLabel()) { - element = serializer.parseVertex(graphSupplier, column, null); + element = serializer.parseSchemaVertex(graphSupplier, column, null); } else { - element = serializer.parseEdge(graphSupplier, column, null, true); + element = serializer.parseSchemaEdge(graphSupplier, column, null, true); } } catch (Exception e) { log.error("parse element failed, graph:{}, key:{}", graphName, e); continue; } - // filter by label id - if (!element.schemaLabel().id().equals(labelId)) { + boolean matchesLabel = element.schemaLabel().id().equals(labelId); + if (!matchesLabel && element instanceof BaseEdge) { + EdgeLabel edgeLabel = (EdgeLabel) element.schemaLabel(); + matchesLabel = edgeLabel.hasFather() && labelId.equals(edgeLabel.fatherId()); + } + if (!matchesLabel) { continue; } @@ -327,7 +332,7 @@ public Status doBuildIndex(Metapb.BuildIndexParam param, Metapb.Partition source } for (var index : array) { - var col = serializer.writeIndex(index); + var col = serializer.writeSchemaIndex(index); int code = PartitionUtils.calcHashcode(KeyUtil.getOwnerId(index.elementId())); // same partition id with element batch.add(partitionId, BatchPutRequest.KV.of(INDEX_TABLE, code, col.name, diff --git a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/FilterIterator.java b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/FilterIterator.java index eb53a2d254..531df3e953 100644 --- a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/FilterIterator.java +++ b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/FilterIterator.java @@ -18,6 +18,7 @@ package org.apache.hugegraph.store.business; import org.apache.commons.lang3.ArrayUtils; +import org.apache.hugegraph.HugeGraphSupplier; import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.query.ConditionQuery; import org.apache.hugegraph.rocksdb.access.RocksDBSession; @@ -34,20 +35,32 @@ public class FilterIterator extends private final ConditionQuery query; T current = null; - public FilterIterator(ScanIterator iterator, ConditionQuery query) { - super(); + public FilterIterator(ScanIterator iterator, ConditionQuery query, HugeGraphSupplier graph) { + super(graph); this.iterator = iterator; this.query = query; // log.info("operator sinking is used to filter data:{}", // query.toString()); } - public static ScanIterator of(ScanIterator it, byte[] conditionQuery) { + public static ScanIterator of(ScanIterator it, byte[] conditionQuery, String graph) { if (ArrayUtils.isEmpty(conditionQuery)) { return it; } - ConditionQuery query = ConditionQuery.fromBytes(conditionQuery); - return new FilterIterator(it, query); + try { + ConditionQuery query = ConditionQuery.fromBytes(conditionQuery); + if (!query.resultType().isVertex() && !query.resultType().isEdge()) { + return it; + } + return new FilterIterator(it, query, BusinessHandlerImpl.getGraphSupplier(graph)); + } catch (RuntimeException failure) { + try { + it.close(); + } catch (RuntimeException closeFailure) { + failure.addSuppressed(closeFailure); + } + throw failure; + } } @Override @@ -60,11 +73,11 @@ public boolean hasNext() { current = iterator.next(); BaseElement element; if (this.query.resultType().isVertex()) { - element = serializer.parseVertex(null, + element = serializer.parseSchemaVertex(this.graph, BackendColumn.of(current.name, current.value), null); } else { - element = serializer.parseEdge(null, + element = serializer.parseSchemaEdge(this.graph, BackendColumn.of(current.name, current.value), null, true); } diff --git a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/GraphStoreIterator.java b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/GraphStoreIterator.java index 51b9c8d15c..254915032e 100644 --- a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/GraphStoreIterator.java +++ b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/GraphStoreIterator.java @@ -83,7 +83,7 @@ public class GraphStoreIterator extends AbstractSelectIterator public GraphStoreIterator(ScanIterator iterator, ScanPartitionRequest scanRequest) { - super(); + super(BusinessHandlerImpl.getGraphSupplier(scanRequest.getScanRequest().getGraphName())); this.iter = iterator; this.scanRequest = scanRequest; this.request = this.scanRequest.getScanRequest(); diff --git a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/SelectIterator.java b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/SelectIterator.java index 2b51e98778..542b91b5e2 100644 --- a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/SelectIterator.java +++ b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/business/SelectIterator.java @@ -17,56 +17,64 @@ package org.apache.hugegraph.store.business; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; +import java.util.Objects; import java.util.List; import java.util.Set; +import org.apache.hugegraph.HugeGraphSupplier; import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.rocksdb.access.RocksDBSession.BackendColumn; import org.apache.hugegraph.rocksdb.access.ScanIterator; import org.apache.hugegraph.serializer.BytesBuffer; -import org.apache.hugegraph.type.define.DataType; -import org.apache.hugegraph.type.define.SerialEnum; public class SelectIterator implements ScanIterator { - ScanIterator iter; - Set properties; + private final ScanIterator iter; + private final Set properties; + private final HugeGraphSupplier graph; + private final boolean isVertex; - public SelectIterator(ScanIterator iterator, List properties) { + public SelectIterator(ScanIterator iterator, List properties, + HugeGraphSupplier graph, boolean isVertex) { this.iter = iterator; - this.properties = new HashSet<>(properties); + this.properties = properties == null ? Collections.emptySet() : new HashSet<>(properties); + this.graph = this.properties.isEmpty() ? graph : Objects.requireNonNull(graph, "graph"); + this.isVertex = isVertex; } public BackendColumn select(BackendColumn column) { - int size; - if (properties == null || (size = properties.size()) == 0) { + if (this.properties.isEmpty() || column.value == null || column.value.length == 0) { return column; } - byte[] name = column.name; - byte[] value = column.value; - BytesBuffer buffer = BytesBuffer.wrap(value); - Id labelId = buffer.readId(); // label - int bpSize = buffer.readVInt(); // property - if (size == bpSize) { - return column; - } - BytesBuffer allocate = BytesBuffer.allocate(8 + 16 * size); - allocate.writeId(labelId); - allocate.writeVInt(size); - for (int i = 0; i < bpSize; i++) { + BytesBuffer buffer = BytesBuffer.wrap(column.value); + Id labelId = this.isVertex ? buffer.readId() : null; + int count = buffer.readVInt(); + List selected = new ArrayList<>(Math.min(count, this.properties.size())); + for (int i = 0; i < count; i++) { + int start = buffer.position(); int propertyId = buffer.readVInt(); - byte cat = buffer.read(); // cardinality and type - byte code = BytesBuffer.getType(cat); - DataType dataType = SerialEnum.fromCode(DataType.class, code); - Object bpValue = buffer.readProperty(dataType); - if (properties.contains(propertyId)) { - allocate.writeVInt(propertyId); - allocate.write(cat); - allocate.writeProperty(dataType, bpValue); + buffer.skipSchemaProperty(this.graph.propertyKey(IdGenerator.of(propertyId))); + if (this.properties.contains(propertyId)) { + // Preserve the stored bytes, including collection ordering and scalar representation. + selected.add(Arrays.copyOfRange(column.value, start, buffer.position())); } } - return BackendColumn.of(name, allocate.bytes()); + BytesBuffer output = BytesBuffer.allocate(column.value.length); + if (this.isVertex) { + output.writeId(labelId); + } + output.writeVInt(selected.size()); + for (byte[] property : selected) { + output.write(property); + } + // TTL belongs to the row, independently of which properties were selected. + output.write(buffer.remainingBytes()); + return BackendColumn.of(column.name, output.bytes()); } @Override diff --git a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/options/HgStoreEngineOptions.java b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/options/HgStoreEngineOptions.java index aa5a1af109..e15070bc1b 100644 --- a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/options/HgStoreEngineOptions.java +++ b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/options/HgStoreEngineOptions.java @@ -53,6 +53,8 @@ public class HgStoreEngineOptions { private QueryPushDownOption queryPushDownOption = new QueryPushDownOption(); // pd server address private String pdAddress; + // PD metadata namespace; must match Server cluster/pd.cluster. + private String pdCluster = "hg"; // External service address private String grpcAddress; // Raft external service address diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/SchemaDriver.java b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/schema/SchemaDriver.java similarity index 91% rename from hugegraph-struct/src/main/java/org/apache/hugegraph/SchemaDriver.java rename to hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/schema/SchemaDriver.java index 11849b80ae..c81b6e8868 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/SchemaDriver.java +++ b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/schema/SchemaDriver.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.hugegraph; +package org.apache.hugegraph.store.schema; import java.io.IOException; import java.util.ArrayList; @@ -32,6 +32,7 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; +import org.apache.hugegraph.HugeGraphSupplier; import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.exception.NotAllowException; import org.apache.hugegraph.id.Id; @@ -64,7 +65,7 @@ public class SchemaDriver { public static final String META_PATH_HUGEGRAPH = "HUGEGRAPH"; public static final String META_PATH_GRAPHSPACE = "GRAPHSPACE"; public static final String META_PATH_GRAPH = "GRAPH"; - public static final String META_PATH_CLUSTER = "hg"; + public static final String DEFAULT_CLUSTER = "hg"; public static final String META_PATH_SCHEMA = "SCHEMA"; public static final String META_PATH_GRAPH_CONF = "GRAPH_CONF"; public static final String META_PATH_PROPERTY_KEY = "PROPERTY_KEY"; @@ -84,16 +85,23 @@ public class SchemaDriver { private static CountDownLatch destroyCompletion = new CountDownLatch(0); // Client for accessing PD private final KvClient client; + private final String cluster; private final SchemaCaches caches; - private SchemaDriver(PDConfig pdConfig, int cacheSize, + private SchemaDriver(PDConfig pdConfig, String cluster, int cacheSize, long expiration) { - this(new KvClient<>(pdConfig), cacheSize, expiration); + this(new KvClient<>(pdConfig), cluster, cacheSize, expiration); } - SchemaDriver(KvClient client, int cacheSize, + SchemaDriver(KvClient client, int cacheSize, long expiration) { + this(client, DEFAULT_CLUSTER, cacheSize, expiration); + } + + SchemaDriver(KvClient client, String cluster, int cacheSize, long expiration) { + E.checkArgument(cluster != null && !cluster.isEmpty(), "PD cluster cannot be empty"); + this.cluster = cluster; this.client = Objects.requireNonNull(client, "client"); this.caches = new SchemaCaches(cacheSize, expiration); try { @@ -117,6 +125,11 @@ public static void init(PDConfig pdConfig) { } public static void init(PDConfig pdConfig, int cacheSize, long expiration) { + init(pdConfig, DEFAULT_CLUSTER, cacheSize, expiration); + } + + public static void init(PDConfig pdConfig, String cluster, int cacheSize, long expiration) { + E.checkArgument(cluster != null && !cluster.isEmpty(), "PD cluster cannot be empty"); synchronized (LIFECYCLE_LOCK) { if (destroying) { throw new NotAllowException("The SchemaDriver is being destroyed"); @@ -129,7 +142,25 @@ public static void init(PDConfig pdConfig, int cacheSize, long expiration) { "allowed to be initialized again", instance.caches.limit(), instance.caches.expiration(), instance.client); } - INSTANCE.set(new SchemaDriver(pdConfig, cacheSize, expiration)); + INSTANCE.set(new SchemaDriver(pdConfig, cluster, cacheSize, expiration)); + } + } + + public static SchemaDriver getOrInit(PDConfig pdConfig, String cluster) { + E.checkArgument(cluster != null && !cluster.isEmpty(), "PD cluster cannot be empty"); + synchronized (LIFECYCLE_LOCK) { + if (destroying) { + throw new NotAllowException("The SchemaDriver is being destroyed"); + } + SchemaDriver instance = INSTANCE.get(); + if (instance == null) { + instance = new SchemaDriver(pdConfig, cluster, 300, 300 * 1000); + INSTANCE.set(instance); + } else if (!instance.cluster.equals(cluster)) { + throw new NotAllowException("SchemaDriver already uses PD cluster '%s', requested '%s'", + instance.cluster, cluster); + } + return instance; } } @@ -206,13 +237,32 @@ private void listenMetaChanges() { private void schemaCacheClearHandler(T response) { List names = this.extractValuesFromResponse(response); - for (String gs : names) { - String[] arr = gs.split(DELIMITER); - assert arr.length == 2; - this.caches.clear(arr[0], arr[1]); + for (String value : names) { + String graph = schemaCacheClearGraph(value); + if (graph == null) { + continue; + } + this.caches.clearByGraphName(graph); log.info(String.format( "Graph '%s' schema clear event is received, deleting all " + - "schema caches under '%s'", gs, gs)); + "schema caches under '%s'", graph, graph)); + } + } + + private String schemaCacheClearGraph(String value) { + if (value == null || value.isEmpty()) { + return null; + } + String payload = value.trim(); + if (!payload.startsWith("{")) { + return value; + } + try { + Object graph = fromJson(payload, Map.class).get("graph"); + return graph instanceof String && !((String) graph).isEmpty() ? (String) graph : null; + } catch (HugeException e) { + log.warn("Ignoring malformed schema cache clear event", e); + return null; } } @@ -380,7 +430,7 @@ private String propertyKeyPrefix(String graphSpace, String graph) { // }/SCHEMA/PROPERTY_KEY/NAME return stringJoin(META_PATH_DELIMITER, META_PATH_HUGEGRAPH, - META_PATH_CLUSTER, + this.cluster, META_PATH_GRAPHSPACE, graphSpace, graph, @@ -394,7 +444,7 @@ private String vertexLabelPrefix(String graphSpace, String graph) { // }/SCHEMA/VERTEX_LABEL/NAME return stringJoin(META_PATH_DELIMITER, META_PATH_HUGEGRAPH, - META_PATH_CLUSTER, + this.cluster, META_PATH_GRAPHSPACE, graphSpace, graph, @@ -408,7 +458,7 @@ private String edgeLabelPrefix(String graphSpace, String graph) { // }/SCHEMA/EDGELABEL/NAME return stringJoin(META_PATH_DELIMITER, META_PATH_HUGEGRAPH, - META_PATH_CLUSTER, + this.cluster, META_PATH_GRAPHSPACE, graphSpace, graph, @@ -422,7 +472,7 @@ private String indexLabelPrefix(String graphSpace, String graph) { // }/SCHEMA/INDEX_LABEL/NAME return stringJoin(META_PATH_DELIMITER, META_PATH_HUGEGRAPH, - META_PATH_CLUSTER, + this.cluster, META_PATH_GRAPHSPACE, graphSpace, graph, @@ -681,7 +731,7 @@ private String graphSpaceRemoveKey() { // HUGEGRAPH/{cluster}/EVENT/GRAPHSPACE/REMOVE return stringJoin(META_PATH_DELIMITER, META_PATH_HUGEGRAPH, - META_PATH_CLUSTER, + this.cluster, META_PATH_EVENT, META_PATH_GRAPHSPACE, META_PATH_REMOVE); @@ -691,7 +741,7 @@ private String graphConfKey(String graphSpace, String graph) { // HUGEGRAPH/{cluster}/GRAPHSPACE/{graphspace}/GRAPH_CONF/{graph} return stringJoin(META_PATH_DELIMITER, META_PATH_HUGEGRAPH, - META_PATH_CLUSTER, + this.cluster, META_PATH_GRAPHSPACE, graphSpace, META_PATH_GRAPH_CONF, @@ -704,7 +754,7 @@ private String nameKey(String graphSpace, String graph, // /{META_PATH_TYPE}/NAME/{name} return stringJoin(META_PATH_DELIMITER, META_PATH_HUGEGRAPH, - META_PATH_CLUSTER, + this.cluster, META_PATH_GRAPHSPACE, graphSpace, graph, @@ -720,7 +770,7 @@ private String idKey(String graphSpace, String graph, // /{META_PATH_TYPE}/ID/{id} return stringJoin(META_PATH_DELIMITER, META_PATH_HUGEGRAPH, - META_PATH_CLUSTER, + this.cluster, META_PATH_GRAPHSPACE, graphSpace, graph, @@ -734,7 +784,7 @@ private String schemaCacheClearKey() { // HUGEGRAPH/{cluster}/EVENT/GRAPH/SCHEMA/CLEAR return stringJoin(META_PATH_DELIMITER, META_PATH_HUGEGRAPH, - META_PATH_CLUSTER, + this.cluster, META_PATH_EVENT, META_PATH_GRAPH, META_PATH_SCHEMA, @@ -745,7 +795,7 @@ private String graphClearKey() { // HUGEGRAPH/{cluster}/EVENT/GRAPH/CLEAR return stringJoin(META_PATH_DELIMITER, META_PATH_HUGEGRAPH, - META_PATH_CLUSTER, + this.cluster, META_PATH_EVENT, META_PATH_GRAPH, META_PATH_CLEAR); @@ -755,7 +805,7 @@ private String graphRemoveKey() { // HUGEGRAPH/{cluster}/EVENT/GRAPH/REMOVE return stringJoin(META_PATH_DELIMITER, META_PATH_HUGEGRAPH, - META_PATH_CLUSTER, + this.cluster, META_PATH_EVENT, META_PATH_GRAPH, META_PATH_REMOVE); @@ -899,9 +949,11 @@ public void clearAll() { } public void clear(String graphSpace, String graph) { - ConcurrentHashMap - schemaCaches = - this.caches.get(stringJoin(DELIMITER, graphSpace, graph)); + this.clearByGraphName(stringJoin(DELIMITER, graphSpace, graph)); + } + + public void clearByGraphName(String graphName) { + ConcurrentHashMap schemaCaches = this.caches.get(graphName); if (schemaCaches != null) { schemaCaches.clear(); } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/SchemaGraph.java b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/schema/SchemaGraph.java similarity index 91% rename from hugegraph-struct/src/main/java/org/apache/hugegraph/SchemaGraph.java rename to hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/schema/SchemaGraph.java index ed7241f7ad..ba9270e280 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/SchemaGraph.java +++ b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/schema/SchemaGraph.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.hugegraph; +package org.apache.hugegraph.store.schema; import java.util.ArrayList; import java.util.Collection; @@ -26,6 +26,7 @@ import org.apache.commons.configuration2.Configuration; import org.apache.commons.configuration2.MapConfiguration; +import org.apache.hugegraph.HugeGraphSupplier; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.id.Id; import org.apache.hugegraph.pd.client.PDConfig; @@ -40,30 +41,21 @@ public class SchemaGraph implements HugeGraphSupplier { private final String graphSpace; private final String graph; - private final PDConfig pdConfig; private final HugeConfig config; private final SchemaDriver schemaDriver; public SchemaGraph(String graphSpace, String graph, PDConfig pdConfig) { + this(graphSpace, graph, pdConfig, SchemaDriver.DEFAULT_CLUSTER); + } + + public SchemaGraph(String graphSpace, String graph, PDConfig pdConfig, String cluster) { this.graphSpace = graphSpace; this.graph = graph; - this.pdConfig = pdConfig; - this.schemaDriver = schemaDriverInit(); + this.schemaDriver = SchemaDriver.getOrInit(pdConfig, cluster); this.config = this.loadConfig(); } - private SchemaDriver schemaDriverInit() { - if (SchemaDriver.getInstance() == null) { - synchronized (SchemaDriver.class) { - if (SchemaDriver.getInstance() == null) { - SchemaDriver.init(this.pdConfig); - } - } - } - return SchemaDriver.getInstance(); - } - private HugeConfig loadConfig() { // Load configuration from PD Map configs = diff --git a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/util/UnsafeUtil.java b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/util/UnsafeUtil.java index bff726d4fd..e36565c858 100644 --- a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/util/UnsafeUtil.java +++ b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/util/UnsafeUtil.java @@ -52,11 +52,7 @@ public static boolean hasUnsafe() { public static Object getUnsafe0() { Object unsafe; try { - // Accessing the Unsafe class and its singleton instance - final Class unsafeClass = Class.forName("sun.misc.Unsafe"); - final Field unsafeField = unsafeClass.getDeclaredField("theUnsafe"); - unsafeField.setAccessible(true); // Bypass access checks - unsafe = unsafeField.get(null); // Get the Unsafe instance + unsafe = org.apache.hugegraph.util.UnsafeUtil.getUnsafe(); } catch (final Throwable t) { // Log a warning if Unsafe is not available if (log.isWarnEnabled()) { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/NotFoundException.java b/hugegraph-store/hg-store-grpc/src/main/dev/org/apache/hugegraph/store/grpc/query/QueryResultFormat.java similarity index 50% rename from hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/NotFoundException.java rename to hugegraph-store/hg-store-grpc/src/main/dev/org/apache/hugegraph/store/grpc/query/QueryResultFormat.java index 7fb8c2317a..132833cf9e 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/NotFoundException.java +++ b/hugegraph-store/hg-store-grpc/src/main/dev/org/apache/hugegraph/store/grpc/query/QueryResultFormat.java @@ -15,23 +15,25 @@ * limitations under the License. */ -package org.apache.hugegraph.exception; +package org.apache.hugegraph.store.grpc.query; -import org.apache.hugegraph.HugeException; - -public class NotFoundException extends HugeException { - - private static final long serialVersionUID = -5912665926327173032L; +/** + * Existing query responses carry either persistent rows or tagged graph elements. + * Keep their selection aligned with the node's deserialization stage. + */ +public final class QueryResultFormat { - public NotFoundException(String message) { - super(message); + private QueryResultFormat() { } - public NotFoundException(String message, Object... args) { - super(message, args); + public static boolean returnsTaggedElements(QueryRequest request) { + return request.getScanType() == ScanType.NO_SCAN && request.getLoadPropertyFromIndex() || + requiresElementDeserialization(request); } - public NotFoundException(String message, Throwable cause, Object... args) { - super(message, cause, args); + public static boolean requiresElementDeserialization(QueryRequest request) { + return request.getOrderByCount() > 0 || request.getPropertyCount() > 0 || + !request.getCondition().isEmpty() || + request.getFunctionsCount() > 0 && !request.getGroupBySchemaLabel(); } } diff --git a/hugegraph-store/hg-store-node/pom.xml b/hugegraph-store/hg-store-node/pom.xml index 9412c34107..a551aeb68e 100644 --- a/hugegraph-store/hg-store-node/pom.xml +++ b/hugegraph-store/hg-store-node/pom.xml @@ -148,6 +148,12 @@ log4j-jul 2.17.2 + + org.apache.hugegraph + hg-store-client + ${revision} + test + diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/AppConfig.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/AppConfig.java index 3f1624c087..c69f5fe89d 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/AppConfig.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/AppConfig.java @@ -40,6 +40,9 @@ public class AppConfig { @Value("${pdserver.address}") private String pdServerAddress; + @Value("${pd.cluster:hg}") + private String pdCluster = "hg"; + @Value("${grpc.host}") private String host; diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/HgStoreNodeService.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/HgStoreNodeService.java index 16592882b2..17cec42e71 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/HgStoreNodeService.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/HgStoreNodeService.java @@ -84,6 +84,7 @@ public void init() { setDataPath(appConfig.getDataPath()); setRaftPath(appConfig.getRaftPath()); setPdAddress(appConfig.getPdServerAddress()); + setPdCluster(appConfig.getPdCluster()); setFakePD(appConfig.isFakePd()); setRocksdbConfig(appConfig.getRocksdbConfig()); setGrpcAddress(appConfig.getStoreServerAddress()); diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/HgStoreWrapperEx.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/HgStoreWrapperEx.java index eae9534e89..54afcfda07 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/HgStoreWrapperEx.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/HgStoreWrapperEx.java @@ -52,7 +52,7 @@ public boolean doClean(String graph, int partId) { public ScanIterator scanAll(String graph, String table, byte[] query) { ScanIterator scanIterator = this.handler.scanAll(graph, table, query); - return FilterIterator.of(scanIterator, query); + return FilterIterator.of(scanIterator, query, graph); } public ScanIterator scan(String graph, int partId, String table, byte[] start, byte[] end, @@ -60,14 +60,14 @@ public ScanIterator scan(String graph, int partId, String table, byte[] start, b byte[] query) { ScanIterator scanIterator = this.handler.scan(graph, partId, table, start, end, scanType, query); - return FilterIterator.of(scanIterator, query); + return FilterIterator.of(scanIterator, query, graph); } public ScanIterator scanOrdered(String graph, String table, byte[] start, byte[] end, int scanType, byte[] query) { ScanIterator scanIterator = this.handler.scanOrdered(graph, table, start, end, scanType); - return FilterIterator.of(scanIterator, query); + return FilterIterator.of(scanIterator, query, graph); } public void batchGet(String graph, String table, Supplier> s, @@ -82,7 +82,7 @@ public ScanIterator scanPrefix(String graph, int partition, String table, byte[] byte[] query) { ScanIterator scanIterator = this.handler.scanPrefix(graph, partition, table, prefix, scanType); - return FilterIterator.of(scanIterator, query); + return FilterIterator.of(scanIterator, query, graph); } public void doBatch(String graph, int partId, List entryList) { diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/ScanUtil.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/ScanUtil.java index a1a706edcc..b7678f91d9 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/ScanUtil.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/ScanUtil.java @@ -35,7 +35,9 @@ import org.apache.hugegraph.pd.common.KVPair; import org.apache.hugegraph.rocksdb.access.ScanIterator; +import org.apache.hugegraph.store.business.BusinessHandlerImpl; import org.apache.hugegraph.store.business.SelectIterator; +import org.apache.hugegraph.store.constant.HugeServerTables; import org.apache.hugegraph.store.grpc.common.ScanMethod; import org.apache.hugegraph.store.grpc.common.ScanOrderType; import org.apache.hugegraph.store.grpc.stream.ScanQueryRequest; @@ -99,7 +101,23 @@ static ScanIterator getIterator(ScanStreamReq request, HgStoreWrapperEx wrapper) if (selects != null) { properties = selects.getPropertiesList(); } - iter = new SelectIterator(iter, properties); + if (properties != null && !properties.isEmpty()) { + boolean isVertex = HugeServerTables.VERTEX_TABLE.equals(table) || + HugeServerTables.TASK_TABLE.equals(table); + try { + if (!isVertex && !HugeServerTables.isEdgeTable(table)) { + throw new IllegalArgumentException("Property selection requires a vertex or edge table: " + table); + } + iter = new SelectIterator(iter, properties, BusinessHandlerImpl.getGraphSupplier(graph), isVertex); + } catch (RuntimeException failure) { + try { + iter.close(); + } catch (RuntimeException closeFailure) { + failure.addSuppressed(closeFailure); + } + throw failure; + } + } iter.seek(request.getPosition().toByteArray()); return iter; } diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/query/QueryUtil.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/query/QueryUtil.java index 5d961038e6..c6fbbeed23 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/query/QueryUtil.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/query/QueryUtil.java @@ -42,6 +42,7 @@ import org.apache.hugegraph.store.grpc.query.AggregationType; import org.apache.hugegraph.store.grpc.query.DeDupOption; import org.apache.hugegraph.store.grpc.query.QueryRequest; +import org.apache.hugegraph.store.grpc.query.QueryResultFormat; import org.apache.hugegraph.store.grpc.query.ScanType; import org.apache.hugegraph.store.grpc.query.ScanTypeParam; import org.apache.hugegraph.store.node.grpc.EmptyIterator; @@ -100,12 +101,12 @@ public static QueryPlan buildPlan(QueryRequest request) { } else { if (request.getCheckTtl()) { var ttl = QueryStages.ofTtlCheckStage(); - ttl.init(isVertex(request.getTable())); + ttl.init(isVertex(request.getTable()), getGraphSupplier(request.getGraph())); plan.addStage(ttl); } // when to de-serialization ? - if (needDeserialize(request)) { + if (QueryResultFormat.requiresElementDeserialization(request)) { var deserializeStage = QueryStages.ofDeserializationStage(); deserializeStage.init(request.getTable(), getGraphSupplier(request.getGraph())); @@ -196,18 +197,6 @@ private static boolean canOptimiseToTop(QueryRequest request) { request.getLimit() > 0; } - /** - * Determine whether deserialization is needed. - * - * @param request query request object. - * @return true if deserialization is needed, false otherwise. - */ - private static boolean needDeserialize(QueryRequest request) { - return !isEmpty(request.getOrderByList()) || !isEmpty(request.getPropertyList()) - || !request.getCondition().isEmpty() || !isEmpty(request.getFunctionsList()) - && !request.getGroupBySchemaLabel(); - } - /** * Get a scan iterator. * @@ -295,14 +284,14 @@ public static BaseElement parseEntry(HugeGraphSupplier graph, BackendColumn column, boolean isVertex) { if (isVertex) { - return serializer.parseVertex(graph, column, null); + return serializer.parseSchemaVertex(graph, column, null); } else { - return serializer.parseEdge(graph, column, null, true); + return serializer.parseSchemaEdge(graph, column, null, true); } } - public static BaseElement parseOlap(BackendColumn column, BaseVertex vertex) { - return serializer.parseVertexOlap(null, column, vertex); + public static BaseElement parseOlap(HugeGraphSupplier graph, BackendColumn column, BaseVertex vertex) { + return serializer.parseSchemaVertexOlap(graph, column, vertex); } /** @@ -312,9 +301,13 @@ public static BaseElement parseOlap(BackendColumn column, BaseVertex vertex) { * @param olap olap vertex * @return new vertex */ - public static BackendColumn combineColumn(BackendColumn vertexColumn, + public static BackendColumn combineColumn(HugeGraphSupplier graph, BackendColumn vertexColumn, List olap) { - return serializer.mergeCols(vertexColumn, olap.toArray(new BackendColumn[0])); + BaseVertex vertex = serializer.parseSchemaVertex(graph, vertexColumn, null); + for (BackendColumn column : olap) { + serializer.parseSchemaVertexOlap(graph, column, vertex); + } + return BackendColumn.of(vertexColumn.name, serializer.formatSchemaVertexValue(vertex)); } public static AggregationFunction createFunc(AggregationType funcType, String genericType) { diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/query/stages/OlapStage.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/query/stages/OlapStage.java index a3dc6edd40..f9377d8f3d 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/query/stages/OlapStage.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/query/stages/OlapStage.java @@ -22,13 +22,16 @@ import java.util.ArrayList; import java.util.List; +import org.apache.hugegraph.HugeGraphSupplier; import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.id.Id; import org.apache.hugegraph.pd.common.PartitionUtils; import org.apache.hugegraph.rocksdb.access.RocksDBSession; import org.apache.hugegraph.serializer.BinaryElementSerializer; +import org.apache.hugegraph.serializer.OlapKey; import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.store.business.BusinessHandler; +import org.apache.hugegraph.store.business.BusinessHandlerImpl; import org.apache.hugegraph.store.node.grpc.query.QueryStage; import org.apache.hugegraph.store.node.grpc.query.QueryUtil; import org.apache.hugegraph.store.node.grpc.query.model.PipelineResult; @@ -45,15 +48,25 @@ @Slf4j public class OlapStage implements QueryStage { - private final BusinessHandler handler = new QueryUtil().getHandler(); + private final BusinessHandler handler; private final BinaryElementSerializer serializer = new BinaryElementSerializer(); private String graph; + private HugeGraphSupplier supplier; private String table; private List properties; + public OlapStage() { + this(new QueryUtil().getHandler()); + } + + public OlapStage(BusinessHandler handler) { + this.handler = java.util.Objects.requireNonNull(handler, "handler"); + } + @Override public void init(Object... objects) { this.graph = (String) objects[0]; + this.supplier = BusinessHandlerImpl.getGraphSupplier(this.graph); this.table = (String) objects[1]; this.properties = QueryUtil.fromStringBytes((List) objects[2]); } @@ -70,32 +83,28 @@ public PipelineResult handle(PipelineResult result) { PartitionUtils.calcHashcode(BinaryElementSerializer.ownerId(element).asBytes()); for (Id property : properties) { - // Build key - var key = getOlapKey(property, element.id()); - var values = handler.doGet(this.graph, code, OLAP_TABLE, key); - if (values != null) { - var column = BackendColumn.of(key, values); - QueryUtil.parseOlap(column, (BaseVertex) element); + BackendColumn column = this.readProperty(code, property, element.id()); + if (column != null) { + QueryUtil.parseOlap(this.supplier, column, (BaseVertex) element); } } } else if (result.getResultType() == PipelineResultType.BACKEND_COLUMN) { var column = result.getColumn(); try { var vertexOnlyId = - serializer.parseVertex(null, BackendColumn.of(column.name, null), null); + serializer.parseSchemaVertex(this.supplier, BackendColumn.of(column.name, null), null); var code = PartitionUtils.calcHashcode( BinaryElementSerializer.ownerId(vertexOnlyId).asBytes()); // todo: Wait for structure to change to byte[] operations var list = new ArrayList(); for (Id property : properties) { - var key = getOlapKey(property, vertexOnlyId.id()); - var values = handler.doGet(this.graph, code, OLAP_TABLE, key); - if (values != null) { - list.add(BackendColumn.of(key, values)); + BackendColumn olap = this.readProperty(code, property, vertexOnlyId.id()); + if (olap != null) { + list.add(olap); } } var vertex = - QueryUtil.combineColumn(BackendColumn.of(column.name, column.value), list); + QueryUtil.combineColumn(this.supplier, BackendColumn.of(column.name, column.value), list); result.setColumn(RocksDBSession.BackendColumn.of(vertex.name, vertex.value)); } catch (Exception e) { log.error("parse olap error, graph: {}, table : {}", graph, table, e); @@ -105,11 +114,18 @@ public PipelineResult handle(PipelineResult result) { return result; } - private byte[] getOlapKey(Id propertyId, Id vertexId) { - BytesBuffer bufferName = - BytesBuffer.allocate(1 + propertyId.length() + 1 + vertexId.length()); - bufferName.writeId(propertyId); - return bufferName.writeId(vertexId).bytes(); + private BackendColumn readProperty(int code, Id propertyId, Id vertexId) { + byte[] key = OlapKey.format(propertyId, vertexId); + byte[] value = this.handler.doGet(this.graph, code, OLAP_TABLE, key); + if (value == null || value.length == 0) { + // Previous HStore writes used the standalone vertex-only key in the merged table. + byte[] legacyKey = BytesBuffer.allocate(vertexId.length() + 9).writeId(vertexId).bytes(); + value = this.handler.doGet(this.graph, code, OLAP_TABLE, legacyKey); + } + if (!OlapKey.matchesProperty(value, propertyId)) { + return null; + } + return BackendColumn.of(key, value); } @Override diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/query/stages/TtlCheckStage.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/query/stages/TtlCheckStage.java index 315ec2d31d..0185d52b13 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/query/stages/TtlCheckStage.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/query/stages/TtlCheckStage.java @@ -17,6 +17,7 @@ package org.apache.hugegraph.store.node.grpc.query.stages; +import org.apache.hugegraph.HugeGraphSupplier; import org.apache.hugegraph.serializer.DirectBinarySerializer; import org.apache.hugegraph.store.node.grpc.query.QueryStage; import org.apache.hugegraph.store.node.grpc.query.model.PipelineResult; @@ -31,6 +32,7 @@ public class TtlCheckStage implements QueryStage { private boolean isVertex; + private HugeGraphSupplier graph; private final DirectBinarySerializer serializer = new DirectBinarySerializer(); private long now; @@ -38,6 +40,7 @@ public class TtlCheckStage implements QueryStage { @Override public void init(Object... objects) { this.isVertex = (boolean) objects[0]; + this.graph = (HugeGraphSupplier) objects[1]; now = System.currentTimeMillis(); } @@ -46,8 +49,8 @@ public PipelineResult handle(PipelineResult result) { if (result.getResultType() == PipelineResultType.BACKEND_COLUMN) { var col = result.getColumn(); try { - var element = isVertex ? serializer.parseVertex(col.name, col.value) : - serializer.parseEdge(col.name, col.value); + var element = isVertex ? serializer.parseSchemaVertex(this.graph, col.name, col.value) : + serializer.parseSchemaEdge(this.graph, col.name, col.value); if (element.expiredTime() > 0 && element.expiredTime() < now) { return null; } diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/task/TTLCleaner.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/task/TTLCleaner.java index 6836fe20b7..6e40dc8ba2 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/task/TTLCleaner.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/task/TTLCleaner.java @@ -93,7 +93,6 @@ public class TTLCleaner implements Runnable { private ThreadPoolExecutor executor; private final Set failedPartitions = Sets.newConcurrentHashSet(); private final ScheduledFuture future; - private final String key = "HUGEGRAPH/hg/EXPIRED"; private final DirectBinarySerializer serializer = new DirectBinarySerializer(); @Autowired private HgStoreNodeService service; @@ -127,24 +126,27 @@ public void submit() { scheduler.submit(this); } - public BiFunction getJudge(String table) { + public BiFunction getJudge(String graph, String table) { try { switch (table) { case HugeServerTables.VERTEX_TABLE: return (key, value) -> { - DirectHugeElement el = serializer.parseVertex(key, value); + DirectHugeElement el = serializer.parseSchemaVertex( + BusinessHandlerImpl.getGraphSupplier(graph), key, value); return predicate(el); }; case HugeServerTables.OUT_EDGE_TABLE: case HugeServerTables.IN_EDGE_TABLE: return (key, value) -> { - DirectHugeElement el = serializer.parseEdge(key, value); + DirectHugeElement el = serializer.parseSchemaEdge( + BusinessHandlerImpl.getGraphSupplier(graph), key, value); return predicate(el); }; case HugeServerTables.INDEX_TABLE: return (key, value) -> { - DirectHugeElement el = serializer.parseIndex(key, value); + DirectHugeElement el = serializer.parseSchemaIndex( + BusinessHandlerImpl.getGraphSupplier(graph), key, value); return predicate(el); }; default: @@ -182,7 +184,7 @@ public void run() { config.setAuthority(DefaultPdProvider.name, DefaultPdProvider.authority); client = new KvClient(config); } - KResponse k = client.get(key); + KResponse k = client.get("HUGEGRAPH/" + appConfig.getPdCluster() + "/EXPIRED"); String g = k.getValue(); log.info("cleaner config:{}", jobConfig); @@ -290,7 +292,7 @@ private Runnable getTask( RocksDBSession session = handler.getSession(id); InnerKeyCreator keyCreator = handler.getKeyCreator(); SessionOperator op = session.sessionOp(); - BiFunction judge = getJudge(table); + BiFunction judge = getJudge(graph, table); scan = op.scan(table, keyCreator.getStartKey(id, graph), keyCreator.getEndKey(id, graph), diff --git a/hugegraph-store/hg-store-node/src/test/java/org/apache/hugegraph/store/business/StoredRowIngressTest.java b/hugegraph-store/hg-store-node/src/test/java/org/apache/hugegraph/store/business/StoredRowIngressTest.java new file mode 100644 index 0000000000..a8eb6c8761 --- /dev/null +++ b/hugegraph-store/hg-store-node/src/test/java/org/apache/hugegraph/store/business/StoredRowIngressTest.java @@ -0,0 +1,614 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.store.business; + +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import java.nio.ByteBuffer; +import java.util.Properties; +import java.util.Set; + +import org.apache.hugegraph.HugeGraphSupplier; +import org.apache.hugegraph.backend.BackendColumn; +import org.apache.hugegraph.config.HugeConfig; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.pd.grpc.Metapb; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.rocksdb.access.RocksDBSession; +import org.apache.hugegraph.rocksdb.access.ScanIterator; +import org.apache.hugegraph.serializer.BinaryElementSerializer; +import org.apache.hugegraph.serializer.BytesBuffer; +import org.apache.hugegraph.serializer.DirectBinarySerializer; +import org.apache.hugegraph.serializer.OlapKey; +import org.apache.hugegraph.store.client.query.QueryExecutor; +import org.apache.hugegraph.store.cmd.HgCmdClient; +import org.apache.hugegraph.store.cmd.HgCmdProcessor; +import org.apache.hugegraph.store.cmd.request.BatchPutRequest; +import org.apache.hugegraph.store.cmd.response.BatchPutResponse; +import org.apache.hugegraph.store.grpc.common.Kv; +import org.apache.hugegraph.store.grpc.query.QueryRequest; +import org.apache.hugegraph.store.grpc.query.QueryResultFormat; +import org.apache.hugegraph.store.grpc.query.ScanType; +import org.apache.hugegraph.store.HgStoreEngine; +import org.apache.hugegraph.store.node.grpc.query.QueryUtil; +import org.apache.hugegraph.store.node.grpc.query.model.PipelineResult; +import org.apache.hugegraph.store.node.grpc.query.stages.TtlCheckStage; +import org.apache.hugegraph.store.node.grpc.query.stages.OlapStage; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; +import org.apache.hugegraph.store.util.HgStoreException; +import org.apache.hugegraph.structure.BaseElement; +import org.apache.hugegraph.structure.BaseVertex; +import org.apache.hugegraph.structure.BaseEdge; +import org.apache.hugegraph.structure.Index; +import org.apache.hugegraph.structure.builder.IndexBuilder; +import org.apache.hugegraph.type.HugeType; +import org.apache.hugegraph.type.define.Cardinality; +import org.apache.hugegraph.type.define.DataType; +import org.apache.hugegraph.type.define.Directions; +import org.apache.hugegraph.type.define.EdgeLabelType; +import org.apache.hugegraph.type.define.Frequency; +import org.apache.hugegraph.type.define.IndexType; +import org.apache.hugegraph.type.define.WriteType; +import org.apache.hugegraph.util.Bytes; +import org.junit.Assert; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import com.google.protobuf.ByteString; + +public class StoredRowIngressTest { + + private static final String FIXTURE = "compatibility/2f827d6e8/core-rows.properties"; + private final BinaryElementSerializer serializer = new BinaryElementSerializer(); + private final DirectBinarySerializer directSerializer = new DirectBinarySerializer(); + private Properties rows; + private HugeGraphSupplier graph; + + @BeforeEach + public void setUp() throws Exception { + this.rows = new Properties(); + try (InputStream input = getClass().getClassLoader().getResourceAsStream(FIXTURE)) { + Assert.assertNotNull("Frozen baseline BinarySerializer rows must be present", input); + this.rows.load(input); + } + this.graph = Mockito.mock(HugeGraphSupplier.class); + Mockito.when(this.graph.configuration()).thenReturn(new HugeConfig(Map.of())); + property(1, Cardinality.SINGLE, WriteType.OLTP); + property(2, Cardinality.LIST, WriteType.OLTP); + property(3, Cardinality.SET, WriteType.OLTP); + property(9, Cardinality.SINGLE, WriteType.OLAP_COMMON); + property(16, DataType.LONG, Cardinality.SINGLE, WriteType.OLTP); + property(17, DataType.TEXT, Cardinality.SINGLE, WriteType.OLTP); + VertexLabel vertex = new VertexLabel(this.graph, id(4), "person"); + vertex.properties(Set.of(id(1), id(2), id(3))); + vertex.ttl(60_000L); + Mockito.when(this.graph.vertexLabelOrNone(id(4))).thenReturn(vertex); + Mockito.when(this.graph.vertexLabel(id(4))).thenReturn(vertex); + EdgeLabel edge = new EdgeLabel(this.graph, id(5), "knows"); + edge.properties(Set.of(id(1), id(2), id(3))); + edge.sourceLabel(id(4)); + edge.targetLabel(id(4)); + edge.frequency(Frequency.MULTIPLE); + edge.ttl(60_000L); + Mockito.when(this.graph.edgeLabelOrNone(id(5))).thenReturn(edge); + Mockito.when(this.graph.edgeLabel(id(5))).thenReturn(edge); + index(6, IndexType.SECONDARY); + index(7, IndexType.RANGE_INT); + index(8, IndexType.RANGE_LONG); + index(15, IndexType.SECONDARY); + } + + @Test + public void testFilterIteratorReadsFrozenServerVertexAndEdges() { + for (String row : List.of("vertex", "edge.out", "edge.in")) { + BackendColumn column = column(row); + RocksDBSession.BackendColumn stored = RocksDBSession.BackendColumn.of(column.name, column.value); + ConditionQuery condition = new ConditionQuery(row.equals("vertex") ? HugeType.VERTEX : HugeType.EDGE); + condition.query(Condition.eq(id(1), 7)); + FilterIterator iterator = new FilterIterator<>(iterator(stored), condition, this.graph); + Assert.assertTrue(row, iterator.hasNext()); + Assert.assertSame(stored, iterator.next()); + Assert.assertFalse(iterator.hasNext()); + iterator.close(); + + ConditionQuery noMatch = new ConditionQuery(condition.resultType()); + noMatch.query(Condition.eq(id(1), 8)); + FilterIterator rejected = new FilterIterator<>(iterator(stored), noMatch, this.graph); + Assert.assertFalse(row, rejected.hasNext()); + rejected.close(); + } + } + + @Test + public void testSchemaLookupFailureClosesAlreadyOpenedFilterIterator() { + ScanIterator source = Mockito.mock(ScanIterator.class); + ConditionQuery query = new ConditionQuery(HugeType.VERTEX); + query.query(Condition.eq(id(1), 7)); + HgStoreEngine engine = HgStoreEngine.getInstance(); + boolean previousClosing = engine.isClosing().getAndSet(false); + try { + FilterIterator.of(source, query.bytes(), "invalid-namespace"); + Assert.fail("Malformed metadata namespace must fail initialization"); + } catch (HgStoreException expected) { + Assert.assertTrue(expected.getMessage().contains("Graph must include")); + Mockito.verify(source).close(); + } finally { + engine.isClosing().set(previousClosing); + } + } + + @Test + public void testSelectionCountsActualMatchesAndPreservesCollectionsAndTtl() { + for (String row : List.of("vertex", "edge.out", "edge.in")) { + BackendColumn column = column(row); + RocksDBSession.BackendColumn stored = RocksDBSession.BackendColumn.of(column.name, column.value); + boolean isVertex = row.equals("vertex"); + // Requested count equals stored count, but one requested ID is absent. + SelectIterator iterator = new SelectIterator(iterator(stored), List.of(2, 3, 99), + this.graph, isVertex); + RocksDBSession.BackendColumn selected = iterator.next(); + Assert.assertArrayEquals(stored.name, selected.name); + BaseElement element = QueryUtil.parseEntry(this.graph, + BackendColumn.of(selected.name, selected.value), isVertex); + Assert.assertEquals(2, element.sizeOfProperties()); + Assert.assertEquals(List.of(7, -1, 7), element.getPropertyValue(id(2))); + Assert.assertEquals(Set.of(-1, 7), element.getPropertyValue(id(3))); + Assert.assertNull(element.getPropertyValue(id(1))); + Assert.assertEquals(expiry(), element.expiredTime()); + iterator.close(); + } + } + + @Test + public void testSelectionOfMissingPropertiesWritesZeroCountAndKeepsTtl() { + BackendColumn column = column("vertex"); + RocksDBSession.BackendColumn stored = RocksDBSession.BackendColumn.of(column.name, column.value); + SelectIterator iterator = new SelectIterator(iterator(stored), List.of(99), this.graph, true); + RocksDBSession.BackendColumn selected = iterator.next(); + BaseVertex vertex = this.serializer.parseSchemaVertex(this.graph, + BackendColumn.of(selected.name, selected.value), null); + Assert.assertEquals(0, vertex.sizeOfProperties()); + Assert.assertEquals(expiry(), vertex.expiredTime()); + iterator.close(); + } + + @Test + public void testOlapMergeKeepsPersistentSchemaFormatAndTtl() { + BackendColumn merged = QueryUtil.combineColumn(this.graph, column("vertex"), List.of(column("olap"))); + BaseVertex vertex = this.serializer.parseSchemaVertex(this.graph, merged, null); + Assert.assertEquals(4, vertex.sizeOfProperties()); + Assert.assertEquals(Integer.valueOf(42), vertex.getPropertyValue(id(9))); + Assert.assertEquals(expiry(), vertex.expiredTime()); + } + + @Test + public void testDirectTtlReaderUsesFrozenRowSchemaAndIndexNameSuffix() { + BackendColumn vertex = column("vertex"); + Assert.assertEquals(expiry(), this.directSerializer.parseSchemaVertex( + this.graph, vertex.name, vertex.value).expiredTime()); + for (String row : List.of("edge.out", "edge.in")) { + BackendColumn edge = column(row); + Assert.assertEquals(expiry(), this.directSerializer.parseSchemaEdge( + this.graph, edge.name, edge.value).expiredTime()); + } + for (String row : List.of("index.secondary", "index.int", "index.long")) { + BackendColumn index = column(row); + Assert.assertEquals(expiry(), this.directSerializer.parseSchemaIndex( + this.graph, index.name, index.value).expiredTime()); + Assert.assertEquals(expiry(), this.serializer.parseSchemaIndex(this.graph, index).expiredTime()); + } + } + + @Test + public void testTtlPipelineAcceptsLiveFixtureAndRejectsExpiredFixture() throws Exception { + Field now = TtlCheckStage.class.getDeclaredField("now"); + now.setAccessible(true); + for (String row : List.of("vertex", "edge.out", "edge.in")) { + TtlCheckStage stage = new TtlCheckStage(); + stage.init(row.equals("vertex"), this.graph); + BackendColumn column = column(row); + PipelineResult input = new PipelineResult(RocksDBSession.BackendColumn.of(column.name, column.value)); + now.setLong(stage, Long.parseLong(this.rows.getProperty("now"))); + Assert.assertSame(row, input, stage.handle(input)); + now.setLong(stage, expiry() + 1); + Assert.assertNull(row, stage.handle(input)); + } + } + + @Test + public void testClientDecodesPersistentRowsAndTaggedElementResponsesExplicitly() throws Exception { + QueryExecutor executor = new QueryExecutor(null, this.graph, 60_000L); + Method decode = QueryExecutor.class.getDeclaredMethod("fromKv", String.class, Kv.class, + boolean.class, boolean.class); + decode.setAccessible(true); + BackendColumn stored = column("vertex"); + BaseVertex persistent = (BaseVertex) decode.invoke(executor, "g+v", kv(stored), false, true); + Assert.assertNotNull(persistent); + Assert.assertEquals(List.of(7, -1, 7), persistent.getPropertyValue(id(2))); + BackendColumn tagged = this.serializer.writeVertex(persistent); + BaseVertex response = (BaseVertex) decode.invoke(executor, "g+v", kv(tagged), false, false); + Assert.assertNotNull(response); + Set expectedGroups = persistent.getPropertyValue(id(3)); + Set actualGroups = response.getPropertyValue(id(3)); + Assert.assertEquals(expectedGroups, actualGroups); + Assert.assertEquals(expiry(), response.expiredTime()); + } + + @Test + public void testUntimedAndSystemRowsDoNotRequireTrailingTtl() { + VertexLabel untimed = new VertexLabel(this.graph, id(10), "untimed"); + untimed.properties(Set.of(id(1), id(2), id(3))); + Mockito.when(this.graph.vertexLabel(id(10))).thenReturn(untimed); + Mockito.when(this.graph.vertexLabelOrNone(id(10))).thenReturn(untimed); + EdgeLabel edge = new EdgeLabel(this.graph, id(11), "untimedEdge"); + edge.properties(Set.of(id(1), id(2), id(3))); + edge.sourceLabel(id(4)); + edge.targetLabel(id(4)); + edge.frequency(Frequency.MULTIPLE); + Mockito.when(this.graph.edgeLabel(id(11))).thenReturn(edge); + Mockito.when(this.graph.edgeLabelOrNone(id(11))).thenReturn(edge); + for (int number : List.of(12, 13, 14)) { + IndexLabel label = new IndexLabel(this.graph, id(number), "untimedIndex" + number); + label.baseType(HugeType.VERTEX_LABEL); + label.baseValue(id(10)); + label.indexType(number == 12 ? IndexType.SECONDARY : + number == 13 ? IndexType.RANGE_INT : IndexType.RANGE_LONG); + label.indexFields(id(number == 12 ? 17 : number == 13 ? 1 : 16)); + Mockito.when(this.graph.indexLabel(id(number))).thenReturn(label); + } + BackendColumn vertex = column("vertex.untimed"); + Assert.assertEquals(0L, this.serializer.parseSchemaVertex(this.graph, vertex, null).expiredTime()); + BackendColumn untimedEdge = column("edge.untimed"); + Assert.assertEquals(0L, this.serializer.parseSchemaEdge(this.graph, untimedEdge, null, true).expiredTime()); + for (String row : List.of("index.secondary.untimed", "index.int.untimed", "index.long.untimed", + "index.system")) { + BackendColumn column = column(row); + Assert.assertEquals(row, 0L, this.serializer.parseSchemaIndex(this.graph, column).expiredTime()); + Assert.assertEquals(row, 0L, this.directSerializer.parseSchemaIndex( + this.graph, column.name, column.value).expiredTime()); + } + } + + @Test + public void testRebuiltIndexWriterMatchesFrozenServerColumnsAndStoreReader() { + BaseVertex vertex = this.serializer.parseSchemaVertex(this.graph, column("vertex"), null); + vertex.addProperty(this.graph.propertyKey(id(16)), 7L); + vertex.addProperty(this.graph.propertyKey(id(17)), "alice"); + IndexBuilder builder = new IndexBuilder(this.graph); + Map fixtures = Map.of(6, "index.secondary", 7, "index.int", 8, "index.long"); + for (Map.Entry fixture : fixtures.entrySet()) { + List indexes = builder.buildIndex(vertex, this.graph.indexLabel(id(fixture.getKey()))); + Assert.assertEquals(1, indexes.size()); + assertPersistentIndex(indexes.get(0), fixture.getValue()); + } + vertex.addProperty(this.graph.propertyKey(id(17)), "long-field-".repeat(20)); + List longString = builder.buildIndex(vertex, this.graph.indexLabel(id(15))); + Assert.assertEquals(1, longString.size()); + assertPersistentIndex(longString.get(0), "index.hashed"); + } + + @Test + public void testSchemaIndexWriterHashingMatchesFrozenServerColumn() { + // Also verify hashing at the serializer boundary without depending on the builder. + // The frozen Server producer supplies the same complete field value. + Index index = new Index(this.graph, this.graph.indexLabel(id(15)), true); + index.fieldValues("long-field-".repeat(20)); + index.elementIds(id(1), expiry()); + assertPersistentIndex(index, "index.hashed"); + } + + @Test + public void testStringIndexBranchesPreserveLongValuesAndCanonicalEscapes() { + BaseVertex vertex = this.serializer.parseSchemaVertex(this.graph, column("vertex"), null); + IndexBuilder builder = new IndexBuilder(this.graph); + String longValue = "long-field-".repeat(20); + for (IndexType type : List.of(IndexType.SECONDARY, IndexType.SHARD, IndexType.UNIQUE)) { + IndexLabel label = new IndexLabel(this.graph, id(20), "stringIndex"); + label.baseType(HugeType.VERTEX_LABEL); + label.baseValue(id(4)); + label.indexType(type); + label.indexFields(id(17)); + vertex.addProperty(this.graph.propertyKey(id(17)), longValue); + Assert.assertEquals(type.name(), longValue, builder.buildIndex(vertex, label).get(0).fieldValues()); + vertex.addProperty(this.graph.propertyKey(id(17)), ""); + Assert.assertEquals(type.name(), "\u0002", builder.buildIndex(vertex, label).get(0).fieldValues()); + vertex.addProperty(this.graph.propertyKey(id(17)), "prefix!tail"); + Assert.assertEquals(type.name(), "prefix`!tail", builder.buildIndex(vertex, label).get(0).fieldValues()); + vertex.addProperty(this.graph.propertyKey(id(17)), "\u0001illegal"); + try { + builder.buildIndex(vertex, label); + Assert.fail("Reserved leading index symbols must remain illegal: " + type); + } catch (IllegalArgumentException expected) { + Assert.assertTrue(expected.getMessage().contains("Illegal leading char")); + } + } + } + + @Test + public void testUniqueNullableFieldUsesCanonicalNullSentinel() { + property(18, DataType.TEXT, Cardinality.SINGLE, WriteType.OLTP); + this.graph.vertexLabel(id(4)).nullableKeys(id(18)); + BaseVertex vertex = this.serializer.parseSchemaVertex(this.graph, column("vertex"), null); + vertex.addProperty(this.graph.propertyKey(id(17)), "prefix"); + IndexLabel label = new IndexLabel(this.graph, id(21), "nullableUnique"); + label.baseType(HugeType.VERTEX_LABEL); + label.baseValue(id(4)); + label.indexType(IndexType.UNIQUE); + label.indexFields(id(17), id(18)); + List indexes = new IndexBuilder(this.graph).buildIndex(vertex, label); + Assert.assertEquals(1, indexes.size()); + Assert.assertEquals("prefix!\u0001", indexes.get(0).fieldValues()); + } + + @Test + public void testFrozenLegacyStoreTtlEnvelopeRemainsReadable() throws Exception { + Properties legacy = new Properties(); + try (InputStream input = getClass().getClassLoader().getResourceAsStream( + "compatibility/2f827d6e8/store-index-rows.properties")) { + Assert.assertNotNull("Frozen baseline Store index writer output must be present", input); + legacy.load(input); + } + for (String row : List.of("secondary", "int", "long", "system")) { + BackendColumn column = BackendColumn.of(Bytes.fromHex(legacy.getProperty(row + ".name")), + Bytes.fromHex(legacy.getProperty(row + ".value"))); + long expectedExpiry = Long.parseLong(legacy.getProperty(row + ".expiry")); + Assert.assertEquals(row, expectedExpiry, + this.serializer.parseSchemaIndex(this.graph, column).expiredTime()); + Assert.assertEquals(row, expectedExpiry, this.directSerializer.parseSchemaIndex( + this.graph, column.name, column.value).expiredTime()); + } + } + + @Test + public void testOlapStageReadsFrozenLegacyRowsWithoutCrossPropertyLeakage() throws Exception { + property(18, Cardinality.SINGLE, WriteType.OLAP_COMMON); + BackendColumn legacy = column("olap"); + Map rows = new HashMap<>(); + rows.put(ByteBuffer.wrap(legacy.name), legacy.value); + for (boolean tagged : List.of(false, true)) { + BaseVertex merged = runOlapStage(rows, tagged, id(9), id(18)); + Assert.assertEquals(42, (Object) merged.getProperty(id(9)).value()); + Assert.assertNull(merged.getProperty(id(18))); + Assert.assertArrayEquals(legacy.value, rows.get(ByteBuffer.wrap(legacy.name))); + Assert.assertEquals(1, rows.size()); + } + } + + @Test + public void testOlapStageMergesMultiplePropertiesAndPrefersNamespacedValues() throws Exception { + property(18, Cardinality.SINGLE, WriteType.OLAP_COMMON); + BackendColumn legacy = column("olap"); + Map rows = new HashMap<>(); + rows.put(ByteBuffer.wrap(legacy.name), legacy.value); + rows.put(ByteBuffer.wrap(OlapKey.format(id(9), id(1))), schemaOlapValue(id(9), 99)); + rows.put(ByteBuffer.wrap(OlapKey.format(id(18), id(1))), schemaOlapValue(id(18), 123)); + for (boolean tagged : List.of(false, true)) { + BaseVertex merged = runOlapStage(rows, tagged, id(9), id(18)); + Assert.assertEquals(99, (Object) merged.getProperty(id(9)).value()); + Assert.assertEquals(123, (Object) merged.getProperty(id(18)).value()); + Assert.assertArrayEquals(legacy.value, rows.get(ByteBuffer.wrap(legacy.name))); + } + } + + private byte[] schemaOlapValue(Id property, int value) { + BaseVertex vertex = new BaseVertex(id(1), VertexLabel.OLAP_VL); + vertex.addProperty(this.graph.propertyKey(property), value); + BytesBuffer buffer = BytesBuffer.allocate(16); + this.serializer.formatSchemaProperty(vertex.getProperty(property), buffer); + return buffer.bytes(); + } + + private BaseVertex runOlapStage(Map rows, boolean tagged, Id... properties) throws Exception { + String graphName = "CODEC_TEST/olap/g"; + BusinessHandler handler = Mockito.mock(BusinessHandler.class); + Mockito.when(handler.doGet(Mockito.eq(graphName), Mockito.anyInt(), Mockito.eq("g+olap"), + Mockito.any(byte[].class))).thenAnswer(call -> + rows.get(ByteBuffer.wrap(call.getArgument(3)))); + Field mock = BusinessHandlerImpl.class.getDeclaredField("mockGraphSupplier"); + mock.setAccessible(true); + HugeGraphSupplier previous = (HugeGraphSupplier) mock.get(null); + BusinessHandlerImpl.setMockGraphSupplier(this.graph); + OlapStage stage = new OlapStage(handler); + try { + List requested = new ArrayList<>(); + for (Id property : properties) { + requested.add(ByteString.copyFrom(BytesBuffer.allocate(16).writeId(property).bytes())); + } + stage.init(graphName, "g+v", requested); + BackendColumn vertex = column("vertex"); + BaseVertex decoded = this.serializer.parseSchemaVertex(this.graph, vertex, null); + PipelineResult input = tagged ? new PipelineResult(decoded) : + new PipelineResult(RocksDBSession.BackendColumn.of(vertex.name, vertex.value)); + Assert.assertSame(input, stage.handle(input)); + if (tagged) { + return (BaseVertex) input.getElement(); + } + return this.serializer.parseSchemaVertex(this.graph, + BackendColumn.of(input.getColumn().name, input.getColumn().value), null); + } finally { + stage.close(); + BusinessHandlerImpl.setMockGraphSupplier(previous); + } + } + + private void assertPersistentIndex(Index rebuilt, String fixture) { + BackendColumn expected = column(fixture); + BackendColumn written = this.serializer.writeSchemaIndex(rebuilt); + // DataManager's persisted batch normalizes an absent payload to zero bytes. + byte[] value = written.value == null ? new byte[0] : written.value; + Assert.assertArrayEquals(fixture, expected.name, written.name); + Assert.assertArrayEquals(fixture, expected.value, value); + Index decoded = this.serializer.parseSchemaIndex(this.graph, BackendColumn.of(written.name, value)); + Assert.assertEquals(rebuilt.elementId(), decoded.elementId()); + Assert.assertEquals(rebuilt.fieldValues(), decoded.fieldValues()); + Assert.assertEquals(expiry(), decoded.expiredTime()); + } + + @Test + public void testParentRequestedRebuildIndexesChildRowsAndExcludesUnrelatedLabels() throws Exception { + EdgeLabel parent = new EdgeLabel(this.graph, id(100), "parent"); + EdgeLabel child = new EdgeLabel(this.graph, id(101), "child"); + child.edgeLabelType(EdgeLabelType.SUB); + child.fatherId(parent.id()); + EdgeLabel unrelated = new EdgeLabel(this.graph, id(102), "unrelated"); + for (EdgeLabel label : List.of(parent, child, unrelated)) { + label.properties(Set.of(id(17))); + // Real sublabels persist their own endpoint links; they do not inherit them on read. + label.sourceLabel(id(4)); + label.targetLabel(id(4)); + Assert.assertEquals(id(4), label.sourceLabel()); + Assert.assertEquals(id(4), label.targetLabel()); + Mockito.when(this.graph.edgeLabel(label.id())).thenReturn(label); + Mockito.when(this.graph.edgeLabelOrNone(label.id())).thenReturn(label); + } + IndexLabel index = new IndexLabel(this.graph, id(103), "parentIndex"); + index.baseType(HugeType.EDGE_LABEL); + index.baseValue(parent.id()); + index.indexType(IndexType.SECONDARY); + index.indexFields(id(17)); + Mockito.when(this.graph.indexLabel(index.id())).thenReturn(index); + BaseEdge childEdge = new BaseEdge(new EdgeId(id(1), Directions.OUT, parent.id(), child.id(), "", id(2)), child); + childEdge.isOutEdge(true); + childEdge.addProperty(this.graph.propertyKey(id(17)), "child record"); + BaseEdge otherEdge = new BaseEdge(new EdgeId(id(3), Directions.OUT, unrelated.id(), unrelated.id(), "", id(4)), + unrelated); + otherEdge.isOutEdge(true); + otherEdge.addProperty(this.graph.propertyKey(id(17)), "unrelated record"); + ScanIterator source = Mockito.mock(ScanIterator.class); + Mockito.when(source.hasNext()).thenReturn(true, true, false); + Mockito.when(source.next()).thenReturn(rebuildInput(childEdge), rebuildInput(otherEdge)); + BusinessHandler handler = Mockito.mock(BusinessHandler.class); + String graphName = "CODEC_TEST/rebuild/g"; + Mockito.when(handler.scan(graphName, "g+oe", 0, 65536)).thenReturn(source); + List written = new ArrayList<>(); + HgCmdClient client = Mockito.mock(HgCmdClient.class); + Mockito.when(client.batchPut(Mockito.any(BatchPutRequest.class))).thenAnswer(call -> { + BatchPutRequest request = call.getArgument(0); + written.addAll(request.getEntries()); + BatchPutResponse response = new BatchPutResponse(); + response.setStatus(HgCmdProcessor.Status.OK); + return response; + }); + DataManagerImpl manager = new DataManagerImpl(); + manager.setBusinessHandler(handler); + manager.setCmdClient(client); + Metapb.BuildIndexParam request = Metapb.BuildIndexParam.newBuilder().setGraph(graphName) + .setLabelId(ByteString.copyFrom(BytesBuffer.allocate(8).writeId(parent.id()).bytes())) + .setIsVertexLabel(false) + .setIndexLabel(ByteString.copyFrom(BytesBuffer.allocate(8).writeId(index.id()).bytes())).build(); + Metapb.Partition partition = Metapb.Partition.newBuilder().setId(9999).setStartKey(0).setEndKey(65536).build(); + Field mock = BusinessHandlerImpl.class.getDeclaredField("mockGraphSupplier"); + mock.setAccessible(true); + HugeGraphSupplier previous = (HugeGraphSupplier) mock.get(null); + BusinessHandlerImpl.setMockGraphSupplier(this.graph); + try { + Assert.assertTrue(manager.doBuildIndex(request, partition).isOk()); + Assert.assertEquals(1, written.size()); + BatchPutRequest.KV row = written.get(0); + Index decoded = this.serializer.parseSchemaIndex(this.graph, + BackendColumn.of(row.getKey(), row.getValue())); + Assert.assertEquals(parent.id(), decoded.indexLabel().baseValue()); + Assert.assertEquals(childEdge.id(), decoded.elementId()); + Assert.assertEquals("child record", decoded.fieldValues()); + Mockito.verify(source).close(); + } finally { + BusinessHandlerImpl.setMockGraphSupplier(previous); + } + } + + private RocksDBSession.BackendColumn rebuildInput(BaseEdge edge) { + byte[] name = this.serializer.formatEdgeName(edge); + // Range scans remove the graph prefix but retain the physical hash-code suffix. + return RocksDBSession.BackendColumn.of(Arrays.copyOf(name, name.length + Short.BYTES), + this.serializer.formatSchemaEdgeValue(edge)); + } + + @Test + public void testResponseFormatMatchesDeserializationPlanning() { + QueryRequest.Builder request = QueryRequest.newBuilder().setScanType(ScanType.TABLE_SCAN); + Assert.assertFalse(QueryResultFormat.returnsTaggedElements(request.build())); + request.setCheckTtl(true); + Assert.assertFalse(QueryResultFormat.returnsTaggedElements(request.build())); + request.addProperty(ByteString.copyFromUtf8("property")); + Assert.assertTrue(QueryResultFormat.requiresElementDeserialization(request.build())); + Assert.assertTrue(QueryResultFormat.returnsTaggedElements(request.build())); + request.clearProperty().addOrderBy(ByteString.copyFromUtf8("order")); + Assert.assertTrue(QueryResultFormat.returnsTaggedElements(request.build())); + request.clearOrderBy().setCondition(ByteString.copyFromUtf8("condition")); + Assert.assertTrue(QueryResultFormat.returnsTaggedElements(request.build())); + } + + private void property(int value, Cardinality cardinality, WriteType writeType) { + property(value, DataType.INT, cardinality, writeType); + } + + private void property(int value, DataType type, Cardinality cardinality, WriteType writeType) { + PropertyKey key = new PropertyKey(this.graph, id(value), "property" + value); + key.dataType(type); + key.cardinality(cardinality); + key.writeType(writeType); + Mockito.when(this.graph.propertyKey(id(value))).thenReturn(key); + } + + private void index(int value, IndexType type) { + IndexLabel label = new IndexLabel(this.graph, id(value), "index" + value); + label.baseType(HugeType.VERTEX_LABEL); + label.baseValue(id(4)); + label.indexType(type); + label.indexFields(id(type == IndexType.RANGE_LONG ? 16 : type == IndexType.SECONDARY ? 17 : 1)); + Mockito.when(this.graph.indexLabel(id(value))).thenReturn(label); + } + + private BackendColumn column(String row) { + return BackendColumn.of(Bytes.fromHex(this.rows.getProperty(row + ".column.0.name")), + Bytes.fromHex(this.rows.getProperty(row + ".column.0.value"))); + } + + private long expiry() { + return Long.parseLong(this.rows.getProperty("expiry")); + } + + private static Id id(int value) { + return IdGenerator.of(value); + } + + private static Kv kv(BackendColumn column) { + return Kv.newBuilder().setKey(ByteString.copyFrom(column.name)) + .setValue(ByteString.copyFrom(column.value)).build(); + } + + private static ScanIterator iterator(RocksDBSession.BackendColumn column) { + ScanIterator iterator = Mockito.mock(ScanIterator.class); + Mockito.when(iterator.hasNext()).thenReturn(true, false); + Mockito.when(iterator.next()).thenReturn(column); + return iterator; + } +} diff --git a/hugegraph-store/hg-store-node/src/test/resources/compatibility/2f827d6e8/README.md b/hugegraph-store/hg-store-node/src/test/resources/compatibility/2f827d6e8/README.md new file mode 100644 index 0000000000..a195c50a35 --- /dev/null +++ b/hugegraph-store/hg-store-node/src/test/resources/compatibility/2f827d6e8/README.md @@ -0,0 +1,22 @@ + + +# Historical fixtures for Store ingress tests + +`StoredRowIngressTest` loads `core-rows.properties` for complete legacy Server rows (properties, TTL, OLAP and indexes), and `store-index-rows.properties` for original Store index-expiry envelopes. + +These byte-identical copies allow tests to load fixtures from this module's own resource classpath. Keep them synchronized with the shared resources. The [canonical fixture guide](../../../../../../../hugegraph-struct/src/test/resources/compatibility/2f827d6e8/README.md) contains the pinned source revision, historical producers, regeneration instructions, compatibility limits and SHA-256 checksums. Regenerate against those historical writers only, never the current writer. diff --git a/hugegraph-store/hg-store-node/src/test/resources/compatibility/2f827d6e8/core-rows.properties b/hugegraph-store/hg-store-node/src/test/resources/compatibility/2f827d6e8/core-rows.properties new file mode 100644 index 0000000000..fd489e58c1 --- /dev/null +++ b/hugegraph-store/hg-store-node/src/test/resources/compatibility/2f827d6e8/core-rows.properties @@ -0,0 +1,108 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # +now=1609459200000 +expiry=1609459260000 +vertex.type=VERTEX +vertex.id=0801 +vertex.ttl=60000 +vertex.columns=1 +vertex.column.0.name=0801 +vertex.column.0.value=08040301070203078fffffff7f0703028fffffff7f07aeebd9fdb460 +edge.out.type=EDGE_OUT +edge.out.id=08018208050805323032362178000802 +edge.out.ttl=60000 +edge.out.columns=1 +edge.out.column.0.name=08018208050805323032362178000802 +edge.out.column.0.value=0301070203078fffffff7f0703028fffffff7f07aeebd9fdb460 +edge.in.type=EDGE_IN +edge.in.id=08028c08050805323032362178000801 +edge.in.ttl=60000 +edge.in.columns=1 +edge.in.column.0.name=08028c08050805323032362178000801 +edge.in.column.0.value=0301070203078fffffff7f0703028fffffff7f07aeebd9fdb460 +olap.type=OLAP +olap.id=0801 +olap.ttl=0 +olap.columns=1 +olap.column.0.name=0801 +olap.column.0.value=092a +index.secondary.type=SECONDARY_INDEX +index.secondary.id=53493a363a616c69636500 +index.secondary.ttl=60000 +index.secondary.columns=1 +index.secondary.column.0.name=53493a363a616c696365000801aeebd9fdb460 +index.secondary.column.0.value= +index.int.type=RANGE_INT_INDEX +index.int.id=a00000000780000007 +index.int.ttl=60000 +index.int.columns=1 +index.int.column.0.name=a000000007800000070801aeebd9fdb460 +index.int.column.0.value= +index.long.type=RANGE_LONG_INDEX +index.long.id=a2000000088000000000000007 +index.long.ttl=60000 +index.long.columns=1 +index.long.column.0.name=a20000000880000000000000070801aeebd9fdb460 +index.long.column.0.value= +vertex.untimed.type=VERTEX +vertex.untimed.id=0803 +vertex.untimed.ttl=0 +vertex.untimed.columns=1 +vertex.untimed.column.0.name=0803 +vertex.untimed.column.0.value=080a0301070203078fffffff7f0703028fffffff7f07 +edge.untimed.type=EDGE_OUT +edge.untimed.id=080182080b080b000802 +edge.untimed.ttl=0 +edge.untimed.columns=1 +edge.untimed.column.0.name=080182080b080b000802 +edge.untimed.column.0.value=0301070203078fffffff7f0703028fffffff7f07 +index.secondary.untimed.type=SECONDARY_INDEX +index.secondary.untimed.id=53493a433a616c69636500 +index.secondary.untimed.ttl=0 +index.secondary.untimed.columns=1 +index.secondary.untimed.column.0.name=53493a433a616c696365000801 +index.secondary.untimed.column.0.value= +index.int.untimed.type=RANGE_INT_INDEX +index.int.untimed.id=a00000000d80000007 +index.int.untimed.ttl=0 +index.int.untimed.columns=1 +index.int.untimed.column.0.name=a00000000d800000070801 +index.int.untimed.column.0.value= +index.long.untimed.type=RANGE_LONG_INDEX +index.long.untimed.id=a20000000e8000000000000007 +index.long.untimed.ttl=0 +index.long.untimed.columns=1 +index.long.untimed.column.0.name=a20000000e80000000000000070801 +index.long.untimed.column.0.value= +index.hashed.type=SECONDARY_INDEX +index.hashed.id=53493a463a323234303534613200 +index.hashed.ttl=60000 +index.hashed.columns=1 +index.hashed.column.0.name=53493a463a3232343035346132000801aeebd9fdb460 +index.hashed.column.0.value=6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d +index.system.type=VERTEX_LABEL_INDEX +index.system.id=56493a2d313a3400 +index.system.ttl=0 +index.system.columns=1 +index.system.column.0.name=56493a2d313a34000801 +index.system.column.0.value= +index.system.edge.type=EDGE_LABEL_INDEX +index.system.edge.id=45493a2d323a3500 +index.system.edge.ttl=0 +index.system.edge.columns=1 +index.system.edge.column.0.name=45493a2d323a35007e08018208050805323032362178000802 +index.system.edge.column.0.value= diff --git a/hugegraph-store/hg-store-node/src/test/resources/compatibility/2f827d6e8/store-index-rows.properties b/hugegraph-store/hg-store-node/src/test/resources/compatibility/2f827d6e8/store-index-rows.properties new file mode 100644 index 0000000000..7f5a599ed4 --- /dev/null +++ b/hugegraph-store/hg-store-node/src/test/resources/compatibility/2f827d6e8/store-index-rows.properties @@ -0,0 +1,31 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # +secondary.name=53493a363a616c696365000801 +secondary.value=00414141426472732f576d413d +secondary.expiry=1609459260000 +int.name=a000000007800000070801 +int.value=00414141426472732f576d413d +int.expiry=1609459260000 +long.name=a20000000880000000000000070801 +long.value=00414141426472732f576d413d +long.expiry=1609459260000 +system.name=56493a2d313a34000801 +system.value=00414141426472732f576d413d +system.expiry=1609459260000 +system.edge.name=45493a2d323a35007e08018208050805323032362178000802 +system.edge.value=00414141426472732f576d413d +system.edge.expiry=1609459260000 diff --git a/hugegraph-store/hg-store-test/pom.xml b/hugegraph-store/hg-store-test/pom.xml index bf1bc6f30c..cfe8a83cfd 100644 --- a/hugegraph-store/hg-store-test/pom.xml +++ b/hugegraph-store/hg-store-test/pom.xml @@ -163,33 +163,6 @@ - - org.powermock - powermock-classloading-xstream - 2.0.0-RC.3 - - - org.powermock - powermock-module-junit4-rule - 2.0.0-RC.3 - - - org.powermock - powermock-api-support - 2.0.0-RC.3 - - - org.powermock - powermock-module-junit4 - 2.0.0-RC.3 - compile - - - org.powermock - powermock-api-mockito2 - 2.0.0-RC.3 - compile - org.apache.hugegraph hg-store-client @@ -205,12 +178,6 @@ - - org.apache.hugegraph - hg-store-node - ${revision} - compile - @@ -258,6 +225,7 @@ **/PartitionEngineErrorTest.java **/BatchGraphIsolationTest.java **/GraphIDManagerTest.java + **/SchemaDriverTest.java diff --git a/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/schema/SchemaDriverTest.java b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/schema/SchemaDriverTest.java new file mode 100644 index 0000000000..4040451427 --- /dev/null +++ b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/schema/SchemaDriverTest.java @@ -0,0 +1,548 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.store.schema; + +import java.lang.reflect.Field; +import java.lang.reflect.Proxy; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; + +import org.apache.hugegraph.HugeGraphSupplier; +import org.apache.hugegraph.exception.HugeException; +import org.apache.hugegraph.exception.NotAllowException; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.pd.client.KvClient; +import org.apache.hugegraph.pd.client.PDConfig; +import org.apache.hugegraph.pd.common.PDException; +import org.apache.hugegraph.pd.grpc.kv.KResponse; +import org.apache.hugegraph.pd.grpc.kv.ScanPrefixResponse; +import org.apache.hugegraph.pd.grpc.kv.WatchEvent; +import org.apache.hugegraph.pd.grpc.kv.WatchKv; +import org.apache.hugegraph.pd.grpc.kv.WatchResponse; +import org.apache.hugegraph.pd.grpc.kv.WatchType; +import org.apache.hugegraph.store.HgStoreEngine; +import org.apache.hugegraph.store.business.BusinessHandlerImpl; +import org.apache.hugegraph.store.options.HgStoreEngineOptions; +import org.apache.hugegraph.store.util.HgStoreException; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.junit.Assert; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class SchemaDriverTest { + + private AtomicReference instance; + private SchemaDriver previousInstance; + + @Before + public void setUp() throws Exception { + this.instance = instanceReference(); + this.previousInstance = this.instance.getAndSet(null); + } + + @After + public void tearDown() { + this.instance.set(this.previousInstance); + } + + @Test + public void testDestroyClosesOwnedKvClient() { + TrackingKvClient client = new TrackingKvClient(); + SchemaDriver driver = new SchemaDriver(client, 10, 60_000L); + this.instance.set(driver); + + try { + SchemaDriver.destroy(); + + Assert.assertTrue(client.closed); + Assert.assertNull(SchemaDriver.getInstance()); + } finally { + client.close(); + } + } + + @Test + public void testDestroyUnpublishesInstanceBeforeClosingResources() throws Exception { + BlockingCloseKvClient client = new BlockingCloseKvClient(); + SchemaDriver driver = new SchemaDriver(client, 10, 60_000L); + this.instance.set(driver); + Thread destroyThread = new Thread(SchemaDriver::destroy, "schema-driver-destroy"); + try { + destroyThread.start(); + client.awaitCloseStarted(); + + Assert.assertNull(SchemaDriver.getInstance()); + } finally { + client.allowClose.countDown(); + destroyThread.join(5000L); + client.close(); + } + + Assert.assertFalse(destroyThread.isAlive()); + Assert.assertTrue(client.closed); + } + + @Test + public void testInitDoesNotWaitForDestroyCleanup() throws Exception { + BlockingCloseKvClient client = new BlockingCloseKvClient(); + SchemaDriver driver = new SchemaDriver(client, 10, 60_000L); + this.instance.set(driver); + AtomicReference initFailure = new AtomicReference<>(); + CountDownLatch initFinished = new CountDownLatch(1); + Thread destroyThread = new Thread(SchemaDriver::destroy, "schema-driver-destroy"); + Thread initThread = new Thread(() -> { + try { + SchemaDriver.init(PDConfig.of("127.0.0.1:8686"), 10, 60_000L); + } catch (Throwable throwable) { + initFailure.set(throwable); + } finally { + initFinished.countDown(); + } + }, "schema-driver-init"); + boolean initCompletedDuringCleanup; + try { + destroyThread.start(); + client.awaitCloseStarted(); + initThread.start(); + initCompletedDuringCleanup = initFinished.await(1L, TimeUnit.SECONDS); + } finally { + client.allowClose.countDown(); + destroyThread.join(5000L); + initThread.join(5000L); + client.close(); + } + + Assert.assertTrue(initCompletedDuringCleanup); + Assert.assertTrue(initFailure.get() instanceof NotAllowException); + Assert.assertFalse(destroyThread.isAlive()); + Assert.assertFalse(initThread.isAlive()); + } + + @Test + public void testConcurrentDestroyWaitsForCleanup() throws Exception { + BlockingCloseKvClient client = new BlockingCloseKvClient(); + SchemaDriver driver = new SchemaDriver(client, 10, 60_000L); + this.instance.set(driver); + CountDownLatch secondDestroyStarted = new CountDownLatch(1); + CountDownLatch secondDestroyReturned = new CountDownLatch(1); + Thread firstDestroy = new Thread(SchemaDriver::destroy, "schema-driver-destroy-first"); + Thread secondDestroy = new Thread(() -> { + secondDestroyStarted.countDown(); + SchemaDriver.destroy(); + secondDestroyReturned.countDown(); + }, "schema-driver-destroy-second"); + boolean returnedBeforeCleanup; + try { + firstDestroy.start(); + client.awaitCloseStarted(); + secondDestroy.start(); + Assert.assertTrue(secondDestroyStarted.await(5L, TimeUnit.SECONDS)); + returnedBeforeCleanup = secondDestroyReturned.await(500L, TimeUnit.MILLISECONDS); + } finally { + client.allowClose.countDown(); + firstDestroy.join(5000L); + secondDestroy.join(5000L); + client.close(); + } + + Assert.assertFalse(returnedBeforeCleanup); + Assert.assertFalse(firstDestroy.isAlive()); + Assert.assertFalse(secondDestroy.isAlive()); + } + + @Test + public void testConstructorFailureClosesOwnedKvClient() { + FailingListenKvClient client = new FailingListenKvClient(); + + try { + new SchemaDriver(client, 10, 60_000L); + Assert.fail("SchemaDriver construction should fail"); + } catch (HugeException expected) { + Assert.assertEquals(2, client.listenCalls); + Assert.assertTrue(client.closed); + } finally { + client.close(); + } + } + + @Test + @SuppressWarnings("unchecked") + public void testStoreCleanupClosesDriverAndReleasesGraphWrappers() throws Exception { + Field cacheField = BusinessHandlerImpl.class.getDeclaredField("GRAPH_SUPPLIER_CACHE"); + cacheField.setAccessible(true); + Map cache = (Map) cacheField.get(null); + Map previousCache = new HashMap<>(cache); + HugeGraphSupplier supplier = (HugeGraphSupplier) Proxy.newProxyInstance( + HugeGraphSupplier.class.getClassLoader(), new Class[]{HugeGraphSupplier.class}, + (proxy, method, args) -> null); + TrackingKvClient client = new TrackingKvClient(); + SchemaDriver driver = new SchemaDriver(client, 10, 60_000L); + this.instance.set(driver); + try { + cache.put("space/graph", supplier); + BusinessHandlerImpl.clearCache(); + Assert.assertTrue(cache.isEmpty()); + Assert.assertFalse(client.closed); + Assert.assertSame(driver, SchemaDriver.getInstance()); + + cache.put("space/graph", supplier); + BusinessHandlerImpl.closeSchemaResources(); + Assert.assertTrue(client.closed); + Assert.assertNull(SchemaDriver.getInstance()); + Assert.assertTrue(cache.isEmpty()); + BusinessHandlerImpl.closeSchemaResources(); + + TrackingKvClient replacementClient = new TrackingKvClient(); + this.instance.set(new SchemaDriver(replacementClient, 10, 60_000L)); + BusinessHandlerImpl.closeSchemaResources(); + Assert.assertTrue(replacementClient.closed); + } finally { + SchemaDriver.destroy(); + cache.putAll(previousCache); + } + } + + @Test + @SuppressWarnings("unchecked") + public void testStoreCleanupReleasesWrappersWhenClientCloseFails() throws Exception { + Field cacheField = BusinessHandlerImpl.class.getDeclaredField("GRAPH_SUPPLIER_CACHE"); + cacheField.setAccessible(true); + Map cache = (Map) cacheField.get(null); + Map previousCache = new HashMap<>(cache); + HugeGraphSupplier supplier = (HugeGraphSupplier) Proxy.newProxyInstance( + HugeGraphSupplier.class.getClassLoader(), new Class[]{HugeGraphSupplier.class}, + (proxy, method, args) -> null); + TrackingKvClient client = new TrackingKvClient() { + @Override + public void close() { + super.close(); + throw new IllegalStateException("close failed"); + } + }; + this.instance.set(new SchemaDriver(client, 10, 60_000L)); + try { + cache.put("space/graph", supplier); + try { + BusinessHandlerImpl.closeSchemaResources(); + Assert.fail("Client close failure must propagate"); + } catch (IllegalStateException expected) { + Assert.assertEquals("close failed", expected.getMessage()); + } + Assert.assertTrue(client.closed); + Assert.assertNull(SchemaDriver.getInstance()); + Assert.assertTrue(cache.isEmpty()); + BusinessHandlerImpl.closeSchemaResources(); + } finally { + SchemaDriver.destroy(); + cache.putAll(previousCache); + } + } + + @Test + public void testClosingStoreRejectsNewGraphSupplierWithoutOpeningPdClient() { + HgStoreEngine engine = HgStoreEngine.getInstance(); + boolean previousClosing = engine.isClosing().getAndSet(true); + try { + BusinessHandlerImpl.getGraphSupplier("schema-driver-test/closing"); + Assert.fail("Closing Store must reject schema client creation"); + } catch (HgStoreException expected) { + Assert.assertEquals("Store is closing", expected.getMessage()); + Assert.assertNull(SchemaDriver.getInstance()); + } finally { + engine.isClosing().set(previousClosing); + } + } + + @Test + public void testSchemaLookupCachesByIdAndNameAndWatchClearsOnlyTargetGraph() { + CachingKvClient client = new CachingKvClient(); + SchemaDriver driver = new SchemaDriver(client, 10, 60_000L); + this.instance.set(driver); + try { + Assert.assertEquals(4, client.listeners.size()); + PropertyKey first = driver.propertyKey("space", "graph", IdGenerator.of(1), null); + Assert.assertSame(first, driver.propertyKey("space", "graph", "name", null)); + PropertyKey other = driver.propertyKey("space", "other", IdGenerator.of(1), null); + Assert.assertEquals(2, client.getCalls); + + client.publish("HUGEGRAPH/hg/EVENT/GRAPH/SCHEMA/CLEAR", "space-graph"); + Assert.assertNotSame(first, driver.propertyKey("space", "graph", IdGenerator.of(1), null)); + Assert.assertSame(other, driver.propertyKey("space", "other", IdGenerator.of(1), null)); + Assert.assertEquals(3, client.getCalls); + } finally { + SchemaDriver.destroy(); + } + } + + @Test + public void testSchemaClearJsonFromServerEvictsOnlyNamedGraphAndKeepsLegacyFormat() { + CachingKvClient client = new CachingKvClient(); + SchemaDriver driver = new SchemaDriver(client, "alternate", 10, 60_000L); + this.instance.set(driver); + String eventKey = "HUGEGRAPH/alternate/EVENT/GRAPH/SCHEMA/CLEAR"; + try { + PropertyKey first = driver.propertyKey("space", "graph-with-hyphen", IdGenerator.of(1), null); + PropertyKey other = driver.propertyKey("space", "other", IdGenerator.of(1), null); + // Current Server CachedSchemaTransactionV2 publishes a source-bearing JSON event. + client.publish(eventKey, "{\"graph\":\"space-graph-with-hyphen\",\"source\":\"server-process-1\"}"); + PropertyKey refreshed = driver.propertyKey("space", "graph-with-hyphen", IdGenerator.of(1), null); + Assert.assertNotSame(first, refreshed); + Assert.assertSame(other, driver.propertyKey("space", "other", IdGenerator.of(1), null)); + Assert.assertEquals(3, client.getCalls); + + client.publish(eventKey, "space-graph-with-hyphen"); + Assert.assertNotSame(refreshed, + driver.propertyKey("space", "graph-with-hyphen", IdGenerator.of(1), null)); + Assert.assertSame(other, driver.propertyKey("space", "other", IdGenerator.of(1), null)); + Assert.assertEquals(4, client.getCalls); + } finally { + SchemaDriver.destroy(); + } + } + + @Test + public void testMalformedSchemaClearPayloadDoesNotInvalidateUnrelatedCaches() { + CachingKvClient client = new CachingKvClient(); + SchemaDriver driver = new SchemaDriver(client, 10, 60_000L); + this.instance.set(driver); + String eventKey = "HUGEGRAPH/hg/EVENT/GRAPH/SCHEMA/CLEAR"; + try { + PropertyKey cached = driver.propertyKey("space", "graph", IdGenerator.of(1), null); + for (String payload : new String[]{"{broken", "{\"source\":\"server-process-1\"}", "{\"graph\":null}"}) { + client.publish(eventKey, payload); + } + Assert.assertSame(cached, driver.propertyKey("space", "graph", IdGenerator.of(1), null)); + Assert.assertEquals(1, client.getCalls); + } finally { + SchemaDriver.destroy(); + } + } + + @Test + public void testGraphAndGraphSpaceRemovalInvalidateSchemaCaches() { + CachingKvClient client = new CachingKvClient(); + SchemaDriver driver = new SchemaDriver(client, 10, 60_000L); + this.instance.set(driver); + try { + PropertyKey first = driver.propertyKey("space", "graph", IdGenerator.of(1), null); + PropertyKey other = driver.propertyKey("space", "other", IdGenerator.of(1), null); + PropertyKey elsewhere = driver.propertyKey("elsewhere", "graph", IdGenerator.of(1), null); + + client.publish("HUGEGRAPH/hg/EVENT/GRAPH/REMOVE", "space-graph"); + Assert.assertNotSame(first, driver.propertyKey("space", "graph", IdGenerator.of(1), null)); + Assert.assertSame(other, driver.propertyKey("space", "other", IdGenerator.of(1), null)); + Assert.assertEquals(4, client.getCalls); + + client.publish("HUGEGRAPH/hg/EVENT/GRAPHSPACE/REMOVE", "space"); + Assert.assertNotSame(other, driver.propertyKey("space", "other", IdGenerator.of(1), null)); + Assert.assertSame(elsewhere, driver.propertyKey("elsewhere", "graph", IdGenerator.of(1), null)); + Assert.assertEquals(5, client.getCalls); + } finally { + SchemaDriver.destroy(); + } + } + + @Test + public void testMetadataKeysAndWatchSubscriptionsUseConfiguredCluster() { + CachingKvClient client = new CachingKvClient(); + SchemaDriver driver = new SchemaDriver(client, "alternate", 10, 60_000L); + this.instance.set(driver); + try { + Assert.assertEquals(4, client.listeners.size()); + for (String key : client.listeners.keySet()) { + Assert.assertTrue(key, key.startsWith("HUGEGRAPH/alternate/EVENT/")); + } + SchemaGraph graph = new SchemaGraph("DEFAULT", "hugegraph", PDConfig.of("127.0.0.1:8686"), + "alternate"); + Assert.assertEquals("HUGEGRAPH/alternate/GRAPHSPACE/DEFAULT/GRAPH_CONF/hugegraph", + client.lastGetKey); + graph.propertyKey(IdGenerator.of(1)); + Assert.assertEquals("HUGEGRAPH/alternate/GRAPHSPACE/DEFAULT/hugegraph/SCHEMA/PROPERTY_KEY/ID/1", + client.lastGetKey); + driver.propertyKeys("DEFAULT", "hugegraph", graph); + Assert.assertEquals("HUGEGRAPH/alternate/GRAPHSPACE/DEFAULT/hugegraph/SCHEMA/PROPERTY_KEY/NAME", + client.lastScanPrefix); + } finally { + SchemaDriver.destroy(); + } + } + + @Test + public void testStoreSupplierMapsRpcNamespaceToSchemaGraphAndConfiguredCluster() throws Exception { + CachingKvClient client = new CachingKvClient(); + this.instance.set(new SchemaDriver(client, "alternate", 10, 60_000L)); + HgStoreEngine engine = HgStoreEngine.getInstance(); + Field optionsField = HgStoreEngine.class.getDeclaredField("options"); + optionsField.setAccessible(true); + Object previousOptions = optionsField.get(engine); + boolean previousClosing = engine.isClosing().getAndSet(false); + Field cacheField = BusinessHandlerImpl.class.getDeclaredField("GRAPH_SUPPLIER_CACHE"); + cacheField.setAccessible(true); + @SuppressWarnings("unchecked") + Map cache = (Map) cacheField.get(null); + Map previousCache = new HashMap<>(cache); + HgStoreEngineOptions options = new HgStoreEngineOptions(); + options.setPdAddress("127.0.0.1:8686"); + options.setPdCluster("alternate"); + optionsField.set(engine, options); + cache.clear(); + try { + HugeGraphSupplier graph = BusinessHandlerImpl.getGraphSupplier("CODEC_TEST/row_graph/g"); + Assert.assertEquals("CODEC_TEST-row_graph", graph.name()); + Assert.assertEquals("HUGEGRAPH/alternate/GRAPHSPACE/CODEC_TEST/GRAPH_CONF/row_graph", + client.lastGetKey); + graph.propertyKey(IdGenerator.of(1)); + Assert.assertEquals("HUGEGRAPH/alternate/GRAPHSPACE/CODEC_TEST/row_graph/SCHEMA/PROPERTY_KEY/ID/1", + client.lastGetKey); + Assert.assertSame(graph, BusinessHandlerImpl.getGraphSupplier("CODEC_TEST/row_graph/g")); + for (String invalid : new String[]{"plain", "/row_graph/g", "CODEC_TEST//g"}) { + try { + BusinessHandlerImpl.getGraphSupplier(invalid); + Assert.fail("Invalid graph namespace must be rejected: " + invalid); + } catch (HgStoreException expected) { + Assert.assertTrue(expected.getMessage().contains("Graph must include")); + } + } + } finally { + BusinessHandlerImpl.closeSchemaResources(); + cache.putAll(previousCache); + optionsField.set(engine, previousOptions); + engine.isClosing().set(previousClosing); + } + } + + @Test + public void testSharedDriverRejectsConflictingClusterAndReusesMatchingCluster() { + CachingKvClient client = new CachingKvClient(); + SchemaDriver driver = new SchemaDriver(client, "alternate", 10, 60_000L); + this.instance.set(driver); + PDConfig config = PDConfig.of("127.0.0.1:8686"); + try { + Assert.assertSame(driver, SchemaDriver.getOrInit(config, "alternate")); + try { + SchemaDriver.getOrInit(config, "hg"); + Assert.fail("Conflicting metadata cluster must fail before reusing the driver"); + } catch (NotAllowException expected) { + Assert.assertTrue(expected.getMessage().contains("alternate")); + } + Assert.assertSame(driver, SchemaDriver.getInstance()); + } finally { + SchemaDriver.destroy(); + } + } + + @SuppressWarnings("unchecked") + private static AtomicReference instanceReference() throws Exception { + Field field = SchemaDriver.class.getDeclaredField("INSTANCE"); + field.setAccessible(true); + return (AtomicReference) field.get(null); + } + + private static class TrackingKvClient extends KvClient { + + protected volatile boolean closed; + + TrackingKvClient() { + super(PDConfig.of("127.0.0.1:8686")); + } + + @Override + public void listen(String key, Consumer consumer) throws PDException { + // Avoid opening a real PD stream while constructing SchemaDriver. + } + + @Override + public void close() { + this.closed = true; + super.close(); + } + } + + private static class CachingKvClient extends TrackingKvClient { + + private final Map> listeners = new HashMap<>(); + private int getCalls; + private String lastGetKey; + private String lastScanPrefix; + + @Override + public void listen(String key, Consumer consumer) { + this.listeners.put(key, consumer); + } + + @Override + public KResponse get(String key) { + this.getCalls++; + this.lastGetKey = key; + return KResponse.newBuilder().setValue("{\"id\":1,\"name\":\"name\"}").build(); + } + + @Override + public ScanPrefixResponse scanPrefix(String prefix) { + this.lastScanPrefix = prefix; + return ScanPrefixResponse.getDefaultInstance(); + } + + private void publish(String key, String graph) { + WatchEvent event = WatchEvent.newBuilder() + .setType(WatchType.Put) + .setCurrent(WatchKv.newBuilder().setValue(graph)) + .build(); + this.listeners.get(key).accept(WatchResponse.newBuilder().addEvents(event).build()); + } + } + + private static class BlockingCloseKvClient extends TrackingKvClient { + + private final CountDownLatch closeStarted = new CountDownLatch(1); + private final CountDownLatch allowClose = new CountDownLatch(1); + + @Override + public void close() { + this.closeStarted.countDown(); + try { + this.allowClose.await(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new IllegalStateException("Client close was interrupted", e); + } + super.close(); + } + + private void awaitCloseStarted() throws InterruptedException { + Assert.assertTrue(this.closeStarted.await(5L, TimeUnit.SECONDS)); + } + } + + private static class FailingListenKvClient extends TrackingKvClient { + + private int listenCalls; + + @Override + public void listen(String key, Consumer consumer) throws PDException { + if (++this.listenCalls == 2) { + throw new PDException(-1, "listener startup failed"); + } + } + } +} diff --git a/hugegraph-struct/README.md b/hugegraph-struct/README.md index f004bc0c23..12b29d33c2 100644 --- a/hugegraph-struct/README.md +++ b/hugegraph-struct/README.md @@ -1,209 +1,50 @@ # HugeGraph-Struct -### Overview +`hugegraph-struct` owns the shared foundations used by Server and Store: IDs, schema metadata, base graph elements, query conditions, type codes and binary encoding. Core builds the graph engine on these implementations instead of maintaining a second copy. -**hugegraph-struct** is a foundational data structures module that defines the core abstractions and type definitions shared across HugeGraph's distributed components. It serves as the "data contract layer" enabling type-safe communication between hugegraph-pd (Placement Driver), hugegraph-store (distributed storage), and hugegraph-server (graph engine). +## Responsibilities -**Key Characteristics**: -- Pure data structure definitions without business logic -- Lightweight and stateless (no `HugeGraph` instance dependencies) -- Shared type system for distributed RPC communication -- Binary serialization for efficient storage and network transmission +| Owner | Responsibility | +|-------|----------------| +| `hugegraph-struct` | Shared models, queries, codecs, index building and analyzers | +| `hugegraph-common` | General utilities, shared JWT verification/signing and RPC configuration interfaces | +| `hugegraph-core` | Graph/TinkerPop adapters, transactions, traversal, backend execution and jobs | +| `hg-store-core` | Store execution and schema metadata access through PD | +| PD service | Placement/metadata service and its own authentication/transport adaptation | -### Why hugegraph-struct? +Struct is not a DTO-only module or dependency-free library. It retains the libraries required by shared codecs, collections and analyzers, including TinkerPop interfaces and shaded Kryo compatibility. It must not depend on core or own PD connections, listeners and caches. -#### The Problem +`HugeGraphSupplier` lets shared operations obtain schema without a concrete `HugeGraph`. It also supplies naming, configuration and time. Store's `SchemaGraph` and `SchemaDriver` live in Store. The caller owns their PD lifecycle. -Originally, all data structures and graph engine logic resided in `hugegraph-server/hugegraph-core`. As HugeGraph evolved toward a distributed architecture, this created several challenges: +Core's `HugeVertex`/`HugeEdge` wrap shared `BaseVertex`/`BaseEdge` state and add engine behavior. `BaseVertex` owns adjacency; core only caches wrapper identities. Shared `Index` replaces `HugeIndex`, including index IDs and values. Index/OLAP selection uses caller-supplied candidates and sinks; core still executes transactions and backend updates. Engine serializers retain backend adaptation and delegate shared encoding. These adapters have different responsibilities from the shared implementation; a second algorithm or state collection is not an adapter. -1. **Tight Coupling**: PD and Store components needed schema definitions but not the entire graph engine -2. **Circular Dependencies**: Distributed components couldn't share types without pulling in heavy dependencies -3. **Build Inefficiency**: Changes to core required rebuilding all dependent modules -4. **Large Dependencies**: PD/Store had to depend on Jersey, JRaft, K8s client, and other server-specific libraries +## Packages and migration -#### The Solution +| Package under `org.apache.hugegraph` | Content | +|------------------------------------|---------| +| `struct.schema` | Schema metadata | +| `structure` | Base elements, indexes and shared index builder | +| `id`, `query`, `serializer` | IDs, query conditions and encoding | +| `type`, `backend` | Type codes and shared backend values | +| `analyzer`, `util`, `exception` | Shared analysis, codec helpers and exceptions | -We extracted **stateless data structures** from `hugegraph-core` into a separate `hugegraph-struct` module: +The 1.8.0 Java API migration removes the old core copies. For example, schema metadata moves from `org.apache.hugegraph.schema` to `org.apache.hugegraph.struct.schema`; engine schema mutation builders remain in core. Applications using internal Java APIs must update imports and compile against a consistent set of artifacts. -``` -Before (Monolithic): -hugegraph-server/hugegraph-core (everything together) - ├─ Data structures (schema, types, IDs) - ├─ Graph engine (traversal, optimization) - ├─ Transactions (GraphTransaction, SchemaTransaction) - ├─ Storage backends (memory, raft, cache) - └─ Business logic (jobs, tasks, auth) - -After (Modular): -hugegraph-struct (shared foundation) - ├─ Schema definitions (VertexLabel, EdgeLabel, PropertyKey, IndexLabel) - ├─ Type system (HugeType, DataType, IdStrategy) - ├─ Data structures (BaseVertex, BaseEdge, BaseProperty) - ├─ Serialization (BytesBuffer, BinarySerializer) - ├─ Query abstractions (Query, ConditionQuery, Aggregate) - └─ Utilities (ID generation, text analyzers, exceptions) - -hugegraph-core (graph engine only) - ├─ Depends on hugegraph-struct - ├─ Implements graph engine logic - ├─ Manages transactions and storage - └─ Provides TinkerPop API -``` - -### Module Responsibilities +See the [shared-foundation migration guide](../docs/shared-foundation-migration.md) for ownership, upgrade requirements and compatibility checks. Existing client REST DTOs need not be replaced merely because their names resemble these types. -| Module | Purpose | Dependencies | -|--------|---------|--------------| -| **hugegraph-struct** | Shared data structures, type definitions, serialization | Minimal (Guava, TinkerPop, serialization libs) | -| **hugegraph-core** | Graph engine, traversal, transactions, storage abstraction | hugegraph-struct + heavy libs (Jersey, JRaft, K8s) | -| **hugegraph-pd** | Metadata coordination, service discovery | hugegraph-struct only | -| **hugegraph-store** | Distributed storage with Raft | hugegraph-struct only | +## Development and validation -### Dependency Architecture - -``` - hugegraph-struct (foundational) - ↑ - ┌──────────────────┼──────────────────┐ - │ │ │ - hugegraph-pd hugegraph-store hugegraph-core - │ │ │ - └──────────────────┼──────────────────┘ - ↓ - hugegraph-server (REST API) -``` +Run from the repository root: -**Build Order**: ```bash -# 1. Build struct first (required dependency) mvn install -pl hugegraph-struct -am -DskipTests - -# 2. Then build dependent modules -mvn install -pl hugegraph-pd -am -DskipTests -mvn install -pl hugegraph-store -am -DskipTests -mvn install -pl hugegraph-server -am -DskipTests +mvn test -pl hugegraph-struct -am ``` -### Migration Plan - -**Current Status (Transition Period)**: - -Both `hugegraph-struct` and `hugegraph-core` contain similar data structures for backward compatibility. This is a **temporary state** during the migration period. - -**Future Direction**: - -- ✅ **hugegraph-struct**: Will become the **single source of truth** for all data structure definitions -- ⚠️ **hugegraph-core**: Data structure definitions will be **gradually removed** and replaced with references to hugegraph-struct -- 🎯 **End Goal**: hugegraph-core will only contain graph engine logic and depend on hugegraph-struct for all type definitions - -**Migration Strategy**: - -1. **Phase 1 (Current)**: Both modules coexist; new features use struct -2. **Phase 2 (In Progress)**: Gradually migrate core's data structures to import from struct -3. **Phase 3 (Future)**: Remove duplicate definitions from core completely - -**Example Migration**: - -```java -// OLD (hugegraph-core) -import org.apache.hugegraph.schema.SchemaElement; // ❌ Will be deprecated - -// NEW (hugegraph-struct) -import org.apache.hugegraph.struct.schema.SchemaElement; // ✅ Use this -``` - -### Developer Guide - -#### When to Use hugegraph-struct - -Use struct when: -- Building distributed components (PD, Store) -- Defining data transfer objects (DTOs) for RPC -- Implementing serialization/deserialization logic -- Working with type definitions, schema elements, or IDs -- Creating shared utilities needed across modules - -#### When to Use hugegraph-core - -Use core when: -- Implementing graph engine features -- Working with TinkerPop API (Gremlin traversal) -- Managing transactions or backend storage -- Implementing graph algorithms or jobs -- Building server-side business logic - -#### Adding New Data Structures - -**Rule**: All new shared data structures should go into `hugegraph-struct`, not `hugegraph-core`. - -Example: -```java -// ✅ Correct: Add to hugegraph-struct/src/main/java/org/apache/hugegraph/struct/ -public class NewSchemaType extends SchemaElement { - // Pure data structure, no HugeGraph dependency -} - -// ❌ Wrong: Don't add to hugegraph-core unless it's graph engine logic -``` - -#### Modifying Existing Structures - -If you need to modify a data structure: - -1. **Check if it exists in struct**: Modify the struct version -2. **If it only exists in core**: Consider migrating it to struct first -3. **Update serialization**: Ensure binary compatibility or provide migration - -### Package Structure - -``` -org.apache.hugegraph/ -├── struct/schema/ # Schema definitions (VertexLabel, EdgeLabel, etc.) -├── structure/ # Graph elements (BaseVertex, BaseEdge, BaseProperty) -├── type/ # Type system (HugeType, DataType, IdStrategy) -├── id/ # ID generation and management -├── serializer/ # Binary serialization (BytesBuffer, BinarySerializer) -├── query/ # Query abstractions (Query, ConditionQuery, Aggregate) -├── analyzer/ # Text analyzers (8 Chinese NLP implementations) -├── auth/ # Auth utilities (JWT, constants) -├── backend/ # Backend abstractions (BinaryId, BackendColumn, Shard) -├── options/ # Configuration options -├── util/ # Utilities (encoding, compression, collections) -└── exception/ # Exception hierarchy -``` - -### Key Design Principles - -1. **Stateless**: No `HugeGraph` instance dependencies in struct -2. **Minimal Dependencies**: Only essential libraries (no Jersey, JRaft, K8s) -3. **Serialization-Friendly**: All structures support binary serialization -4. **Type Safety**: Strong typing for distributed RPC communication -5. **Backward Compatible**: Careful versioning to avoid breaking changes - -### Building and Testing - -```bash -# Build struct module -mvn clean install -DskipTests - -# Build with tests (when tests are added) -mvn clean install - -# From parent directory -cd /path/to/hugegraph -mvn install -pl hugegraph-struct -am -DskipTests -``` - -### Contributing - -When contributing to hugegraph-struct: +The first command builds without tests. Tests exist under `src/test/java`; a successful build alone does not prove compatibility or distributed startup. See [BUILDING](../docs/BUILDING.md) and module CI for service prerequisites. -1. **No Business Logic**: Keep it pure data structures -2. **No Graph Instances**: Avoid `HugeGraph graph` fields -3. **Document Changes**: Update AGENTS.md if adding new packages -4. **Binary Compatibility**: Consider serialization impact -5. **Minimal Dependencies**: Justify any new dependency additions +Change shared behavior once, in its canonical owner, and migrate consumers. Changes to type codes, ID encoding, binary layout, query JSON or classification must be checked against historical fixtures and Server/Store readers. Do not restore deleted copies to resolve an import or dependency problem. -### License +## License -Apache License 2.0 - See [LICENSE](../LICENSE) file for details. +Apache License 2.0; see [LICENSE](../LICENSE). diff --git a/hugegraph-struct/pom.xml b/hugegraph-struct/pom.xml index a65c294681..763036833b 100644 --- a/hugegraph-struct/pom.xml +++ b/hugegraph-struct/pom.xml @@ -33,25 +33,20 @@ UTF-8 25.1-jre 3.8.1 + 8.11.2 - - org.apache.hugegraph - hg-pd-client - ${project.version} - - - - jakarta.ws.rs - jakarta.ws.rs-api - 3.0.0 - - org.apache.tinkerpop gremlin-core ${tinkerpop.version} + + + org.apache.commons + commons-configuration2 + + @@ -60,6 +55,18 @@ ${tinkerpop.version} test + + com.carrotsearch + hppc + 0.7.1 + + + + junit + junit + 4.13.2 + test + com.google.code.gson @@ -83,11 +90,12 @@ guava ${guava.version} - - - - - + + + org.apache.commons + commons-lang3 + 3.18.0 + org.apache.tinkerpop gremlin-shaded @@ -149,34 +157,22 @@ com.hankcs hanlp - portable-1.5.0 + portable-1.8.3 org.apache.lucene lucene-analyzers-smartcn - 7.4.0 + ${lucene.version} org.apache.lucene - lucene-core - 7.4.0 - - - io.jsonwebtoken - jjwt-api - 0.11.2 - - - io.jsonwebtoken - jjwt-impl - 0.11.2 - runtime + lucene-analyzers-common + ${lucene.version} - io.jsonwebtoken - jjwt-jackson - 0.11.2 - runtime + org.apache.lucene + lucene-core + ${lucene.version} com.huaban @@ -186,7 +182,7 @@ org.lionsoul jcseg-core - 2.2.0 + 2.6.2 com.chenlb.mmseg4j @@ -197,8 +193,47 @@ com.janeluo ikanalyzer 2012_u6 + + + org.apache.lucene + lucene-core + + + org.apache.lucene + lucene-analyzers-common + + + + + + org.codehaus.mojo + flatten-maven-plugin + 1.2.7 + + true + resolveCiFriendliesOnly + + + + flatten + process-resources + + flatten + + + + flatten.clean + clean + + clean + + + + + + diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/HugeGraphSupplier.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/HugeGraphSupplier.java index 2ac547db8a..97eb045eed 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/HugeGraphSupplier.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/HugeGraphSupplier.java @@ -19,9 +19,14 @@ package org.apache.hugegraph; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; import java.util.Collection; import java.util.List; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.hugegraph.struct.schema.SchemaElement; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.id.Id; import org.apache.hugegraph.struct.schema.EdgeLabel; @@ -31,8 +36,7 @@ import org.apache.hugegraph.util.DateUtil; /** - * Actually, it would be better if this interface be called - * "HugeGraphSchemaSupplier". + * Provides shared schema, configuration and time access without requiring a graph engine. */ public interface HugeGraphSupplier { @@ -70,9 +74,33 @@ default EdgeLabel edgeLabelOrNone(Id id) { String name(); + default String spaceGraphName() { + return this.name(); + } + HugeConfig configuration(); default long now() { return DateUtil.now().getTime(); } + + + default List mapElId2Name(Collection ids) { + List names = new ArrayList<>(ids.size()); + for (Id id : ids) { + SchemaElement schema = this.edgeLabel(id); + names.add(schema.name()); + } + return names; + } + + default Set> mapPairId2Name( + Set> pairs) { + Set> results = new HashSet<>(pairs.size()); + for (Pair pair : pairs) { + results.add(Pair.of(this.vertexLabel(pair.getLeft()).name(), + this.vertexLabel(pair.getRight()).name())); + } + return results; + } } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/Analyzer.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/Analyzer.java index 4edd2ffa9b..8e7537e072 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/Analyzer.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/Analyzer.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.analyzer; @@ -23,5 +21,5 @@ public interface Analyzer { - public Set segment(String text); + Set segment(String text); } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/AnalyzerFactory.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/AnalyzerFactory.java index bff18ab7b0..2cf1dc1b03 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/AnalyzerFactory.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/AnalyzerFactory.java @@ -1,36 +1,33 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.analyzer; - -import org.apache.hugegraph.exception.HugeException; - import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import org.apache.hugegraph.exception.HugeException; + public class AnalyzerFactory { - private static Map> analyzers; + private static final Map> ANALYZERS; static { - analyzers = new ConcurrentHashMap<>(); + ANALYZERS = new ConcurrentHashMap<>(); } public static Analyzer analyzer(String name, String mode) { @@ -58,7 +55,7 @@ public static Analyzer analyzer(String name, String mode) { } private static Analyzer customizedAnalyzer(String name, String mode) { - Class clazz = analyzers.get(name); + Class clazz = ANALYZERS.get(name); if (clazz == null) { throw new HugeException("Not exists analyzer: %s", name); } @@ -68,12 +65,12 @@ private static Analyzer customizedAnalyzer(String name, String mode) { return clazz.getConstructor(String.class).newInstance(mode); } catch (Exception e) { throw new HugeException( - "Failed to construct analyzer '%s' with mode '%s'", - e, name, mode); + "Failed to construct analyzer '%s' with mode '%s'", + e, name, mode); } } - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SuppressWarnings({"rawtypes", "unchecked"}) public static void register(String name, String classPath) { ClassLoader classLoader = AnalyzerFactory.class.getClassLoader(); Class clazz; @@ -91,12 +88,12 @@ public static void register(String name, String classPath) { } // Check exists - if (analyzers.containsKey(name)) { + if (ANALYZERS.containsKey(name)) { throw new HugeException("Exists analyzer: %s(%s)", - name, analyzers.get(name).getName()); + name, ANALYZERS.get(name).getName()); } // Register class - analyzers.put(name, (Class) clazz); + ANALYZERS.put(name, (Class) clazz); } } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/AnsjAnalyzer.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/AnsjAnalyzer.java index 3f041d31f8..2f857cd171 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/AnsjAnalyzer.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/AnsjAnalyzer.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.analyzer; @@ -34,7 +32,7 @@ import com.google.common.collect.ImmutableList; /** - * Reference from https://my.oschina.net/apdplat/blog/412921 + * Reference from https://github.com/NLPchina/ansj_seg/wiki */ public class AnsjAnalyzer implements Analyzer { @@ -45,20 +43,20 @@ public class AnsjAnalyzer implements Analyzer { "NlpAnalysis" ); - private String analysis; + private final String analysis; public AnsjAnalyzer(String mode) { if (!SUPPORT_MODES.contains(mode)) { throw new ConfigException( - "Unsupported segment mode '%s' for ansj analyzer, " + - "the available values are %s", mode, SUPPORT_MODES); + "Unsupported segment mode '%s' for ansj analyzer, " + + "the available values are %s", mode, SUPPORT_MODES); } this.analysis = mode; } @Override public Set segment(String text) { - Result terms = null; + Result terms; switch (this.analysis) { case "BaseAnalysis": terms = BaseAnalysis.parse(text); @@ -74,7 +72,7 @@ public Set segment(String text) { break; default: throw new AssertionError(String.format( - "Unsupported segment mode '%s'", this.analysis)); + "Unsupported segment mode '%s'", this.analysis)); } assert terms != null; diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/HanLPAnalyzer.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/HanLPAnalyzer.java index b8175e400c..8b5fa6aa0a 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/HanLPAnalyzer.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/HanLPAnalyzer.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.analyzer; @@ -22,6 +20,8 @@ import java.util.List; import java.util.Set; +import org.apache.hugegraph.config.ConfigException; +import org.apache.hugegraph.util.InsertionOrderUtil; import com.google.common.collect.ImmutableList; import com.hankcs.hanlp.seg.Dijkstra.DijkstraSegment; @@ -33,23 +33,20 @@ import com.hankcs.hanlp.tokenizer.SpeedTokenizer; import com.hankcs.hanlp.tokenizer.StandardTokenizer; -import org.apache.hugegraph.config.ConfigException; -import org.apache.hugegraph.util.InsertionOrderUtil; - /** - * Reference from https://my.oschina.net/apdplat/blog/412921 + * Reference from https://github.com/hankcs/HanLP/wiki */ public class HanLPAnalyzer implements Analyzer { public static final List SUPPORT_MODES = - ImmutableList.builder() - .add("standard") - .add("nlp") - .add("index") - .add("nShort") - .add("shortest") - .add("speed") - .build(); + ImmutableList.builder() + .add("standard") + .add("nlp") + .add("index") + .add("nShort") + .add("shortest") + .add("speed") + .build(); private static final Segment N_SHORT_SEGMENT = new NShortSegment().enableCustomDictionary(false) @@ -60,20 +57,20 @@ public class HanLPAnalyzer implements Analyzer { .enablePlaceRecognize(true) .enableOrganizationRecognize(true); - private String tokenizer; + private final String tokenizer; public HanLPAnalyzer(String mode) { if (!SUPPORT_MODES.contains(mode)) { throw new ConfigException( - "Unsupported segment mode '%s' for hanlp analyzer, " + - "the available values are %s", mode, SUPPORT_MODES); + "Unsupported segment mode '%s' for hanlp analyzer, " + + "the available values are %s", mode, SUPPORT_MODES); } this.tokenizer = mode; } @Override public Set segment(String text) { - List terms = null; + List terms; switch (this.tokenizer) { case "standard": terms = StandardTokenizer.segment(text); @@ -95,7 +92,7 @@ public Set segment(String text) { break; default: throw new AssertionError(String.format( - "Unsupported segment mode '%s'", this.tokenizer)); + "Unsupported segment mode '%s'", this.tokenizer)); } assert terms != null; diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/IKAnalyzer.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/IKAnalyzer.java index a938e8e01f..bf97437fdd 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/IKAnalyzer.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/IKAnalyzer.java @@ -1,38 +1,36 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.analyzer; -import com.google.common.collect.ImmutableList; +import java.io.StringReader; +import java.util.List; +import java.util.Set; -import org.apache.hugegraph.config.ConfigException; import org.apache.hugegraph.exception.HugeException; +import org.apache.hugegraph.config.ConfigException; import org.apache.hugegraph.util.InsertionOrderUtil; import org.wltea.analyzer.core.IKSegmenter; import org.wltea.analyzer.core.Lexeme; -import java.io.StringReader; -import java.util.List; -import java.util.Set; +import com.google.common.collect.ImmutableList; /** - * Reference from https://my.oschina.net/apdplat/blog/412921 + * Reference from https://github.com/yyn0210/IKAnalyzer */ public class IKAnalyzer implements Analyzer { @@ -41,26 +39,24 @@ public class IKAnalyzer implements Analyzer { "max_word" ); - private boolean smartSegMode; - private final IKSegmenter ik; + private final boolean smartSegMode; public IKAnalyzer(String mode) { if (!SUPPORT_MODES.contains(mode)) { throw new ConfigException( - "Unsupported segment mode '%s' for ikanalyzer, " + - "the available values are %s", mode, SUPPORT_MODES); + "Unsupported segment mode '%s' for ikanalyzer, " + + "the available values are %s", mode, SUPPORT_MODES); } this.smartSegMode = SUPPORT_MODES.get(0).equals(mode); - this.ik = new IKSegmenter(new StringReader(""), - this.smartSegMode); } @Override public Set segment(String text) { Set result = InsertionOrderUtil.newSet(); - ik.reset(new StringReader(text)); + IKSegmenter ik = new IKSegmenter(new StringReader(text), + this.smartSegMode); try { - Lexeme word = null; + Lexeme word; while ((word = ik.next()) != null) { result.add(word.getLexemeText()); } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/JcsegAnalyzer.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/JcsegAnalyzer.java index 0a69af8384..7e7b9321bf 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/JcsegAnalyzer.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/JcsegAnalyzer.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.analyzer; @@ -23,19 +21,19 @@ import java.util.List; import java.util.Set; -import org.apache.hugegraph.config.ConfigException; import org.apache.hugegraph.exception.HugeException; +import org.apache.hugegraph.config.ConfigException; import org.apache.hugegraph.util.InsertionOrderUtil; -import org.lionsoul.jcseg.tokenizer.core.ADictionary; -import org.lionsoul.jcseg.tokenizer.core.DictionaryFactory; -import org.lionsoul.jcseg.tokenizer.core.ISegment; -import org.lionsoul.jcseg.tokenizer.core.IWord; -import org.lionsoul.jcseg.tokenizer.core.JcsegTaskConfig; -import org.lionsoul.jcseg.tokenizer.core.SegmentFactory; +import org.lionsoul.jcseg.ISegment; +import org.lionsoul.jcseg.IWord; +import org.lionsoul.jcseg.dic.ADictionary; +import org.lionsoul.jcseg.dic.DictionaryFactory; +import org.lionsoul.jcseg.segmenter.SegmenterConfig; + import com.google.common.collect.ImmutableList; /** - * Reference from https://my.oschina.net/apdplat/blog/412921 + * Reference from https://github.com/lionsoul2014/jcseg */ public class JcsegAnalyzer implements Analyzer { @@ -44,29 +42,34 @@ public class JcsegAnalyzer implements Analyzer { "Complex" ); - private static final JcsegTaskConfig CONFIG = new JcsegTaskConfig(); - private static final ADictionary DIC = - DictionaryFactory.createDefaultDictionary(new JcsegTaskConfig()); + private static final SegmenterConfig CONFIG = new SegmenterConfig(); + private static final ADictionary DIC = DictionaryFactory.createDefaultDictionary(CONFIG); - private int segMode; + private final ISegment.Type type; public JcsegAnalyzer(String mode) { if (!SUPPORT_MODES.contains(mode)) { throw new ConfigException( - "Unsupported segment mode '%s' for jcseg analyzer, " + - "the available values are %s", mode, SUPPORT_MODES); + "Unsupported segment mode '%s' for jcseg analyzer, " + + "the available values are %s", mode, SUPPORT_MODES); + } + + if ("Simple".equals(mode)) { + this.type = ISegment.SIMPLE; + } else { + this.type = ISegment.COMPLEX; } - this.segMode = SUPPORT_MODES.indexOf(mode) + 1; } @Override public Set segment(String text) { Set result = InsertionOrderUtil.newSet(); try { - Object[] args = new Object[]{new StringReader(text), CONFIG, DIC}; - ISegment seg = SegmentFactory.createJcseg(this.segMode, args); - IWord word = null; - while ((word = seg.next()) != null) { + ISegment segmentor = this.type.factory.create(CONFIG, DIC); + segmentor.reset(new StringReader(text)); + + IWord word; + while ((word = segmentor.next()) != null) { result.add(word.getValue()); } } catch (Exception e) { diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/JiebaAnalyzer.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/JiebaAnalyzer.java index 70cae33268..7c280a50a1 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/JiebaAnalyzer.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/JiebaAnalyzer.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.analyzer; @@ -30,7 +28,7 @@ import com.huaban.analysis.jieba.SegToken; /** - * Reference from https://my.oschina.net/apdplat/blog/412921 + * Reference from https://github.com/huaban/jieba-analysis */ public class JiebaAnalyzer implements Analyzer { @@ -41,13 +39,13 @@ public class JiebaAnalyzer implements Analyzer { private static final JiebaSegmenter JIEBA_SEGMENTER = new JiebaSegmenter(); - private JiebaSegmenter.SegMode segMode; + private final JiebaSegmenter.SegMode segMode; public JiebaAnalyzer(String mode) { if (!SUPPORT_MODES.contains(mode)) { throw new ConfigException( - "Unsupported segment mode '%s' for jieba analyzer, " + - "the available values are %s", mode, SUPPORT_MODES); + "Unsupported segment mode '%s' for jieba analyzer, " + + "the available values are %s", mode, SUPPORT_MODES); } this.segMode = JiebaSegmenter.SegMode.valueOf(mode); } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/MMSeg4JAnalyzer.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/MMSeg4JAnalyzer.java index 3316582f73..a4415911fa 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/MMSeg4JAnalyzer.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/MMSeg4JAnalyzer.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.analyzer; @@ -23,10 +21,10 @@ import java.util.List; import java.util.Set; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.config.ConfigException; import org.apache.hugegraph.util.InsertionOrderUtil; -import org.apache.hugegraph.exception.HugeException; import com.chenlb.mmseg4j.ComplexSeg; import com.chenlb.mmseg4j.Dictionary; import com.chenlb.mmseg4j.MMSeg; @@ -37,7 +35,7 @@ import com.google.common.collect.ImmutableList; /** - * Reference from https://my.oschina.net/apdplat/blog/412921 + * Reference from https://github.com/chenlb/mmseg4j-core */ public class MMSeg4JAnalyzer implements Analyzer { @@ -49,13 +47,13 @@ public class MMSeg4JAnalyzer implements Analyzer { private static final Dictionary DIC = Dictionary.getInstance(); - private Seg seg; + private final Seg seg; public MMSeg4JAnalyzer(String mode) { if (!SUPPORT_MODES.contains(mode)) { throw new ConfigException( - "Unsupported segment mode '%s' for mmseg4j analyzer, " + - "the available values are %s", mode, SUPPORT_MODES); + "Unsupported segment mode '%s' for mmseg4j analyzer, " + + "the available values are %s", mode, SUPPORT_MODES); } int index = SUPPORT_MODES.indexOf(mode); switch (index) { @@ -70,7 +68,7 @@ public MMSeg4JAnalyzer(String mode) { break; default: throw new AssertionError(String.format( - "Unsupported segment mode '%s'", this.seg)); + "Unsupported segment mode '%s'", mode)); } } @@ -79,7 +77,7 @@ public Set segment(String text) { Set result = InsertionOrderUtil.newSet(); MMSeg mmSeg = new MMSeg(new StringReader(text), this.seg); try { - Word word = null; + Word word; while ((word = mmSeg.next()) != null) { result.add(word.getString()); } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/SmartCNAnalyzer.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/SmartCNAnalyzer.java index 34c0ea2fba..7b00aa59dd 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/SmartCNAnalyzer.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/analyzer/SmartCNAnalyzer.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.analyzer; @@ -24,23 +22,23 @@ import java.util.List; import java.util.Set; +import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.util.InsertionOrderUtil; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; -import org.apache.hugegraph.exception.HugeException; import com.google.common.collect.ImmutableList; /** - * Reference from https://my.oschina.net/apdplat/blog/412921 + * Reference from https://lucene.apache.org/core/8_11_2/analyzers-smartcn/index.html */ public class SmartCNAnalyzer implements Analyzer { public static final List SUPPORT_MODES = ImmutableList.of(); private static final SmartChineseAnalyzer ANALYZER = - new SmartChineseAnalyzer(); + new SmartChineseAnalyzer(); public SmartCNAnalyzer(String mode) { // pass @@ -52,7 +50,7 @@ public Set segment(String text) { Reader reader = new StringReader(text); try (TokenStream tokenStream = ANALYZER.tokenStream("text", reader)) { tokenStream.reset(); - CharTermAttribute term = null; + CharTermAttribute term; while (tokenStream.incrementToken()) { term = tokenStream.getAttribute(CharTermAttribute.class); result.add(term.toString()); diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/auth/AuthConstant.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/auth/AuthConstant.java deleted file mode 100644 index 97bd1a0e1c..0000000000 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/auth/AuthConstant.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2017 HugeGraph Authors - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package org.apache.hugegraph.auth; - -public interface AuthConstant { - - /* - * Fields in token - */ - String TOKEN_USER_NAME = "user_name"; - String TOKEN_USER_ID = "user_id"; - String TOKEN_USER_PASSWORD = "user_password"; -} diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/backend/BinaryId.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/backend/BinaryId.java index 685a934fd7..3b72d707cc 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/backend/BinaryId.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/backend/BinaryId.java @@ -1,36 +1,33 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.backend; -import org.apache.hugegraph.id.Id; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.apache.hugegraph.id.Id; import org.apache.hugegraph.util.Bytes; import org.apache.hugegraph.util.E; -import java.nio.ByteBuffer; -import java.util.Arrays; - -public final class BinaryId implements Id { +public class BinaryId implements Id { - private final byte[] bytes; - private final Id id; + protected byte[] bytes; + protected Id id; public BinaryId(byte[] bytes, Id id) { this.bytes = bytes; diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/exception/ErrorCodeProvider.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/exception/ErrorCodeProvider.java index d5034b703a..a5777f9fd1 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/exception/ErrorCodeProvider.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/exception/ErrorCodeProvider.java @@ -21,7 +21,7 @@ public interface ErrorCodeProvider { - public String format(Object... args); + String format(Object... args); - public String with(String message); + String with(String message); } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/exception/LimitExceedException.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/exception/LimitExceedException.java index 10652dca2c..6defbf7a44 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/exception/LimitExceedException.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/exception/LimitExceedException.java @@ -1,24 +1,24 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.exception; +import org.apache.hugegraph.exception.HugeException; + public class LimitExceedException extends HugeException { private static final long serialVersionUID = 7384276720045597709L; diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/exception/NotAllowException.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/exception/NotAllowException.java index 3781b6d482..75e4f9b597 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/exception/NotAllowException.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/exception/NotAllowException.java @@ -1,24 +1,24 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.exception; +import org.apache.hugegraph.exception.HugeException; + public class NotAllowException extends HugeException { private static final long serialVersionUID = -1407924451828873200L; diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/exception/NotFoundException.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/exception/NotFoundException.java index 8567ceb018..7eaadd3fb6 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/exception/NotFoundException.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/exception/NotFoundException.java @@ -1,24 +1,24 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.exception; +import org.apache.hugegraph.exception.HugeException; + public class NotFoundException extends HugeException { private static final long serialVersionUID = -5912665926327173032L; diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/exception/NotSupportException.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/exception/NotSupportException.java index 49d3dad49c..713295af70 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/exception/NotSupportException.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/exception/NotSupportException.java @@ -1,24 +1,24 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.exception; +import org.apache.hugegraph.exception.HugeException; + public class NotSupportException extends HugeException { private static final long serialVersionUID = -2914329541122906234L; diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/id/EdgeId.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/id/EdgeId.java index 2b03e97d33..dfb530702f 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/id/EdgeId.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/id/EdgeId.java @@ -1,50 +1,45 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.id; -import org.apache.hugegraph.perf.PerfUtil.Watched; -import org.apache.hugegraph.testutil.Assert; -import org.apache.hugegraph.util.E; - import org.apache.hugegraph.exception.NotFoundException; +import org.apache.hugegraph.perf.PerfUtil.Watched; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Directions; import org.apache.hugegraph.type.define.HugeKeys; +import org.apache.hugegraph.util.E; import org.apache.hugegraph.util.StringEncoding; /** * Class used to format and parse id of edge, the edge id consists of: * EdgeId = { source-vertex-id > direction > parentEdgeLabelId > subEdgeLabelId - * >sortKeys > target-vertex-id } + * > sortKeys > target-vertex-id } * NOTE: - * 1. for edges with edgeLabel-type=NORMAL,edgelabelId=parentEdgeLabelId=subEdgeLabelId, - * for edges with edgeLabel type=PARENT,edgelabelId = subEdgeLabelId , - * parentEdgeLabelId = edgelabelId.fatherId - * - * 2.if we use `entry.type()` which is IN or OUT as a part of id, + *

1. for edges with edgeLabelType = NORMAL: edgeLabelId = parentEdgeLabelId = subEdgeLabelId; + * for edges with edgeLabelType = PARENT: edgeLabelId = subEdgeLabelId, parentEdgeLabelId = + * edgeLabelId.fatherId + *

2.if we use `entry.type()` which is IN or OUT as a part of id, * an edge's id will be different due to different directions (belongs * to 2 owner vertex) */ public class EdgeId implements Id { - public static final HugeKeys[] KEYS = new HugeKeys[] { + public static final HugeKeys[] KEYS = new HugeKeys[]{ HugeKeys.OWNER_VERTEX, HugeKeys.DIRECTION, HugeKeys.LABEL, @@ -53,32 +48,28 @@ public class EdgeId implements Id { HugeKeys.OTHER_VERTEX }; - private final Id ownerVertexId; - private final Directions direction; - private final Id edgeLabelId; - private final Id subLabelId; - private final String sortValues; - private final Id otherVertexId; - - private final boolean directed; - private String cache; - + protected final Id ownerVertexId; + protected final Id edgeLabelId; + protected final Id subLabelId; + protected final Id otherVertexId; + protected final Directions direction; + protected final boolean directed; + protected String sortValues; + protected String cache; - public EdgeId(Id ownerVertexId, Directions direction, Id edgeLabelId, - Id subLabelId, String sortValues, - Id otherVertexId) { - this(ownerVertexId, direction, edgeLabelId, - subLabelId, sortValues, otherVertexId, false); + public EdgeId(Id ownerVertexId, Directions direction, Id edgeLabelId, Id subLabelId, + String sortValues, Id otherVertexId) { + this(ownerVertexId, direction, edgeLabelId, subLabelId, + sortValues, otherVertexId, false); } - public EdgeId(Id ownerVertexId, Directions direction, Id edgeLabelId, - Id subLabelId, String sortValues, - Id otherVertexId, boolean directed) { + public EdgeId(Id ownerVertexId, Directions direction, Id edgeLabelId, Id subLabelId, + String sortValues, Id otherVertexId, boolean directed) { this.ownerVertexId = ownerVertexId; this.direction = direction; this.edgeLabelId = edgeLabelId; - this.sortValues = sortValues; this.subLabelId = subLabelId; + this.sortValues = sortValues; this.otherVertexId = otherVertexId; this.directed = directed; this.cache = null; @@ -87,14 +78,13 @@ public EdgeId(Id ownerVertexId, Directions direction, Id edgeLabelId, @Watched public EdgeId switchDirection() { Directions direction = this.direction.opposite(); - return new EdgeId(this.otherVertexId, direction, this.edgeLabelId, - this.subLabelId, this.sortValues, this.ownerVertexId, - this.directed); + return new EdgeId(this.otherVertexId, direction, this.edgeLabelId, this.subLabelId, + this.sortValues, this.ownerVertexId, this.directed); } public EdgeId directed(boolean directed) { - return new EdgeId(this.ownerVertexId, this.direction, this.edgeLabelId, - this.subLabelId, this.sortValues, this.otherVertexId, directed); + return new EdgeId(this.ownerVertexId, this.direction, this.edgeLabelId, this.subLabelId, + this.sortValues, this.otherVertexId, directed); } private Id sourceVertexId() { @@ -109,10 +99,6 @@ private Id targetVertexId() { this.ownerVertexId; } - public Id subLabelId(){ - return this.subLabelId; - } - public Id ownerVertexId() { return this.ownerVertexId; } @@ -121,6 +107,10 @@ public Id edgeLabelId() { return this.edgeLabelId; } + public Id subLabelId() { + return this.subLabelId; + } + public Directions direction() { return this.direction; } @@ -147,23 +137,34 @@ public String asString() { if (this.cache != null) { return this.cache; } + this.cache = this.formatString(); + return this.cache; + } + + /** + * Format the shared edge identity without retaining a heap cache. Read + * components through accessors so storage adapters can keep them off heap. + */ + protected final String formatString() { + Id owner = this.ownerVertexId(); + Id other = this.otherVertexId(); if (this.directed) { - this.cache = SplicingIdGenerator.concat( - IdUtil.writeString(this.ownerVertexId), - this.direction.type().string(), - IdUtil.writeLong(this.edgeLabelId), - IdUtil.writeLong(this.subLabelId), - this.sortValues, - IdUtil.writeString(this.otherVertexId)); - } else { - this.cache = SplicingIdGenerator.concat( - IdUtil.writeString(this.sourceVertexId()), - IdUtil.writeLong(this.edgeLabelId), - IdUtil.writeLong(this.subLabelId), - this.sortValues, - IdUtil.writeString(this.targetVertexId())); + return SplicingIdGenerator.concat( + IdUtil.writeString(owner), + this.direction().type().string(), + IdUtil.writeLong(this.edgeLabelId()), + IdUtil.writeLong(this.subLabelId()), + this.sortValues(), + IdUtil.writeString(other)); } - return this.cache; + Id source = this.direction() == Directions.OUT ? owner : other; + Id target = this.direction() == Directions.OUT ? other : owner; + return SplicingIdGenerator.concat( + IdUtil.writeString(source), + IdUtil.writeLong(this.edgeLabelId()), + IdUtil.writeLong(this.subLabelId()), + this.sortValues(), + IdUtil.writeString(target)); } @Override @@ -219,14 +220,14 @@ public boolean equals(Object object) { return this.ownerVertexId.equals(other.ownerVertexId) && this.direction == other.direction && this.edgeLabelId.equals(other.edgeLabelId) && - this.sortValues.equals(other.sortValues) && this.subLabelId.equals(other.subLabelId) && + this.sortValues.equals(other.sortValues) && this.otherVertexId.equals(other.otherVertexId); } else { return this.sourceVertexId().equals(other.sourceVertexId()) && this.edgeLabelId.equals(other.edgeLabelId) && - this.sortValues.equals(other.sortValues) && this.subLabelId.equals(other.subLabelId) && + this.sortValues.equals(other.sortValues) && this.targetVertexId().equals(other.targetVertexId()); } } @@ -241,7 +242,7 @@ public static byte directionToCode(Directions direction) { } public static Directions directionFromCode(byte code) { - return (code == HugeType.EDGE_OUT.code()) ? Directions.OUT : Directions.IN; + return Directions.convert(HugeType.fromCode(code)); } public static boolean isOutDirectionFromCode(byte code) { @@ -253,7 +254,7 @@ public static EdgeId parse(String id) throws NotFoundException { } public static EdgeId parse(String id, boolean returnNullIfError) - throws NotFoundException { + throws NotFoundException { String[] idParts = SplicingIdGenerator.split(id); if (!(idParts.length == 5 || idParts.length == 6)) { if (returnNullIfError) { @@ -270,8 +271,8 @@ public static EdgeId parse(String id, boolean returnNullIfError) Id subLabelId = IdUtil.readLong(idParts[2]); String sortValues = idParts[3]; Id otherVertexId = IdUtil.readString(idParts[4]); - return new EdgeId(ownerVertexId, Directions.OUT, edgeLabelId, - subLabelId, sortValues, otherVertexId); + return new EdgeId(ownerVertexId, Directions.OUT, edgeLabelId, subLabelId, + sortValues, otherVertexId); } else { assert idParts.length == 6; Id ownerVertexId = IdUtil.readString(idParts[0]); @@ -281,8 +282,7 @@ public static EdgeId parse(String id, boolean returnNullIfError) String sortValues = idParts[4]; Id otherVertexId = IdUtil.readString(idParts[5]); return new EdgeId(ownerVertexId, Directions.convert(direction), - edgeLabelId, subLabelId, - sortValues, otherVertexId); + edgeLabelId, subLabelId, sortValues, otherVertexId); } } catch (Throwable e) { if (returnNullIfError) { @@ -301,8 +301,8 @@ public static Id parseStoredString(String id) { Id subLabelId = IdGenerator.ofStoredString(idParts[2], IdType.LONG); String sortValues = idParts[3]; Id otherVertexId = IdUtil.readStoredString(idParts[4]); - return new EdgeId(ownerVertexId, Directions.OUT, edgeLabelId, - subLabelId, sortValues, otherVertexId); + return new EdgeId(ownerVertexId, Directions.OUT, edgeLabelId, subLabelId, + sortValues, otherVertexId); } public static String asStoredString(Id id) { @@ -326,25 +326,4 @@ public static String[] split(Id id) { public static String[] split(String id) { return SplicingIdGenerator.split(id); } - - - public static void main(String[] args) { - EdgeId edgeId1 = new EdgeId(IdGenerator.of("1:marko"), Directions.OUT, - IdGenerator.of(1), - IdGenerator.of(1), "", - IdGenerator.of("1:josh")); - EdgeId edgeId2 = new EdgeId(IdGenerator.of("1:marko"), Directions.OUT, - IdGenerator.of(1), - IdGenerator.of(1), "", - IdGenerator.of("1:josh")); - EdgeId edgeId3 = new EdgeId(IdGenerator.of("1:josh"), Directions.IN, - IdGenerator.of(1), - IdGenerator.of(1), "", - IdGenerator.of("1:marko")); - Assert.assertTrue(edgeId1.equals(edgeId2)); - Assert.assertTrue(edgeId2.equals(edgeId1)); - Assert.assertTrue(edgeId1.equals(edgeId3)); - Assert.assertTrue(edgeId3.equals(edgeId1)); - } - } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/id/Id.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/id/Id.java index aeb7810a9d..89f61d9583 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/id/Id.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/id/Id.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.id; @@ -25,37 +23,37 @@ public interface Id extends Comparable, Serializable { - public static final int UUID_LENGTH = 16; + int UUID_LENGTH = 16; - public Object asObject(); + Object asObject(); - public String asString(); + String asString(); - public long asLong(); + long asLong(); - public byte[] asBytes(); + byte[] asBytes(); - public int length(); + int length(); - public IdType type(); + IdType type(); - public default boolean number() { + default boolean number() { return this.type() == IdType.LONG; } - public default boolean uuid() { + default boolean uuid() { return this.type() == IdType.UUID; } - public default boolean string() { + default boolean string() { return this.type() == IdType.STRING; } - public default boolean edge() { + default boolean edge() { return this.type() == IdType.EDGE; } - public enum IdType { + enum IdType { UNKNOWN, LONG, @@ -71,8 +69,7 @@ public char prefix() { } public static IdType valueOfPrefix(String id) { - E.checkArgument(id != null && id.length() > 0, - "Invalid id '%s'", id); + E.checkArgument(id != null && !id.isEmpty(), "Invalid id '%s'", id); switch (id.charAt(0)) { case 'L': return IdType.LONG; diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/id/IdGenerator.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/id/IdGenerator.java index b6687262db..8eb746e400 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/id/IdGenerator.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/id/IdGenerator.java @@ -1,36 +1,33 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.id; +import java.util.Objects; +import java.util.UUID; + +import org.apache.hugegraph.id.Id.IdType; import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.structure.BaseVertex; -import org.apache.hugegraph.util.StringEncoding; -import com.google.common.primitives.Longs; - +import org.apache.hugegraph.util.Bytes; import org.apache.hugegraph.util.E; import org.apache.hugegraph.util.LongEncoding; import org.apache.hugegraph.util.NumericUtil; - -import java.nio.charset.Charset; -import java.util.Objects; -import java.util.UUID; +import org.apache.hugegraph.util.StringEncoding; public abstract class IdGenerator { @@ -38,19 +35,19 @@ public abstract class IdGenerator { public abstract Id generate(BaseVertex vertex); - public final static Id of(String id) { + public static Id of(String id) { return new StringId(id); } - public final static Id of(UUID id) { + public static Id of(UUID id) { return new UuidId(id); } - public final static Id of(String id, boolean uuid) { + public static Id of(String id, boolean uuid) { return uuid ? new UuidId(id) : new StringId(id); } - public final static Id of(long id) { + public static Id of(long id) { return new LongId(id); } @@ -67,7 +64,7 @@ public static Id of(Object id) { return new ObjectId(id); } - public final static Id of(byte[] bytes, Id.IdType type) { + public static Id of(byte[] bytes, IdType type) { switch (type) { case LONG: return new LongId(bytes); @@ -80,13 +77,13 @@ public final static Id of(byte[] bytes, Id.IdType type) { } } - public final static Id ofStoredString(String id, Id.IdType type) { + public static Id ofStoredString(String id, IdType type) { switch (type) { case LONG: return of(LongEncoding.decodeSignedB64(id)); case UUID: byte[] bytes = StringEncoding.decodeBase64(id); - return of(bytes, Id.IdType.UUID); + return of(bytes, IdType.UUID); case STRING: return of(id); default: @@ -94,7 +91,7 @@ public final static Id ofStoredString(String id, Id.IdType type) { } } - public final static String asStoredString(Id id) { + public static String asStoredString(Id id) { switch (id.type()) { case LONG: return LongEncoding.encodeSignedB64(id.asLong()); @@ -107,40 +104,45 @@ public final static String asStoredString(Id id) { } } - public final static Id.IdType idType(Id id) { + public static IdType idType(Id id) { if (id instanceof LongId) { - return Id.IdType.LONG; + return IdType.LONG; } if (id instanceof UuidId) { - return Id.IdType.UUID; + return IdType.UUID; } if (id instanceof StringId) { - return Id.IdType.STRING; + return IdType.STRING; } if (id instanceof EdgeId) { - return Id.IdType.EDGE; + return IdType.EDGE; } - return Id.IdType.UNKNOWN; + return IdType.UNKNOWN; } - private final static int compareType(Id id1, Id id2) { + public static int compareType(Id id1, Id id2) { return idType(id1).ordinal() - idType(id2).ordinal(); } /****************************** id defines ******************************/ - public static final class StringId implements Id { + public static class StringId implements Id { - private final String id; - private static final Charset CHARSET = Charset.forName("UTF-8"); + protected String id; + protected byte[] bytes; public StringId(String id) { - E.checkArgument(!id.isEmpty(), "The id can't be empty"); + E.checkArgument(id != null && !id.isEmpty(), + "The id can't be null or empty"); this.id = id; + this.bytes = null; } public StringId(byte[] bytes) { - this.id = StringEncoding.decode(bytes); + E.checkArgument(bytes != null && bytes.length > 0, + "The id bytes can't be null or empty"); + this.bytes = bytes; + this.id = null; } @Override @@ -150,27 +152,35 @@ public IdType type() { @Override public Object asObject() { - return this.id; + return this.asString(); } @Override public String asString() { + if (this.id == null) { + assert this.bytes != null; + this.id = StringEncoding.decode(this.bytes); + } return this.id; } @Override public long asLong() { - return Long.parseLong(this.id); + return Long.parseLong(this.asString()); } @Override public byte[] asBytes() { - return this.id.getBytes(CHARSET); + if (this.bytes == null) { + assert this.id != null; + this.bytes = StringEncoding.encode(this.id); + } + return this.bytes; } @Override public int length() { - return this.id.length(); + return this.asString().length(); } @Override @@ -179,33 +189,41 @@ public int compareTo(Id other) { if (cmp != 0) { return cmp; } - return this.id.compareTo(other.asString()); + return this.asString().compareTo(other.asString()); } @Override public int hashCode() { - return this.id.hashCode(); + return this.asString().hashCode(); } @Override - public boolean equals(Object other) { - if (!(other instanceof StringId)) { + public boolean equals(Object obj) { + if (!(obj instanceof StringId)) { return false; } - return this.id.equals(((StringId) other).id); + StringId other = (StringId) obj; + if (this.id != null) { + return this.id.equals(other.asString()); + } else if (other.bytes == null) { + return this.asString().equals(other.asString()); + } else { + assert this.bytes != null; + return Bytes.equals(this.bytes, other.asBytes()); + } } @Override public String toString() { - return this.id; + return this.asString(); } } - public static final class LongId extends Number implements Id { + public static class LongId extends Number implements Id { private static final long serialVersionUID = -7732461469037400190L; - private final long id; + protected Long id; public LongId(long id) { this.id = id; @@ -238,8 +256,7 @@ public long asLong() { @Override public byte[] asBytes() { - return Longs.toByteArray(this.id); - // return NumericUtil.longToBytes(this.id); + return NumericUtil.longToBytes(this.id); } @Override @@ -264,26 +281,11 @@ public int hashCode() { @Override public boolean equals(Object other) { if (!(other instanceof Number)) { - if (idDigitalObject(other)) { - return this.id == (long) Double.parseDouble(other.toString()); - } return false; } return this.id == ((Number) other).longValue(); } - private static boolean idDigitalObject(Object object) { - String string = object.toString(); - for (int i = string.length(); --i >= 0; ) { - char c = string.charAt(i); - if (!Character.isDigit(c) && - '.' != c) { - return false; - } - } - return true; - } - @Override public String toString() { return String.valueOf(this.id); @@ -291,7 +293,7 @@ public String toString() { @Override public int intValue() { - return (int) this.id; + return this.id.intValue(); } @Override @@ -310,9 +312,9 @@ public double doubleValue() { } } - public static final class UuidId implements Id { + public static class UuidId implements Id { - private final UUID uuid; + protected UUID uuid; public UuidId(String string) { this(StringEncoding.uuid(string)); @@ -400,9 +402,9 @@ public String toString() { /** * This class is just used by backend store for wrapper object as Id */ - public static final class ObjectId implements Id { + public static class ObjectId implements Id { - private final Object object; + protected Object object; public ObjectId(Object object) { E.checkNotNull(object, "object"); diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/id/IdUtil.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/id/IdUtil.java index b394c79a12..ce7c970edc 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/id/IdUtil.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/id/IdUtil.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.id; @@ -22,7 +20,7 @@ import java.nio.ByteBuffer; import org.apache.commons.lang3.StringUtils; - +import org.apache.hugegraph.id.Id.IdType; import org.apache.hugegraph.serializer.BytesBuffer; public final class IdUtil { @@ -45,7 +43,7 @@ public static String writeStoredString(Id id) { } public static Id readStoredString(String id) { - Id.IdType type = Id.IdType.valueOfPrefix(id); + IdType type = IdType.valueOfPrefix(id); String idContent = id.substring(1); switch (type) { case LONG: @@ -82,23 +80,20 @@ public static Id fromBytes(byte[] bytes) { return buffer.readId(); } - public static String writeString(Id id) { String idString = id.asString(); - StringBuilder sb = new StringBuilder(1 + idString.length()); - sb.append(id.type().prefix()).append(idString); - return sb.toString(); + return id.type().prefix() + idString; } public static Id readString(String id) { - Id.IdType type = Id.IdType.valueOfPrefix(id); + IdType type = IdType.valueOfPrefix(id); String idContent = id.substring(1); switch (type) { case LONG: return IdGenerator.of(Long.parseLong(idContent)); case STRING: case UUID: - return IdGenerator.of(idContent, type == Id.IdType.UUID); + return IdGenerator.of(idContent, type == IdType.UUID); case EDGE: return EdgeId.parse(idContent); default: @@ -145,12 +140,13 @@ public static String escape(char splitor, char escape, String... values) { public static String[] unescape(String id, String splitor, String escape) { /* - * Note that the `splitor`/`escape` maybe special characters in regular + * Note that the `splitter`/`escape` maybe special characters in regular * expressions, but this is a frequently called method, for faster * execution, we forbid the use of special characters as delimiter * or escape sign. + * * The `limit` param -1 in split method can ensure empty string be - * splited to a part. + * split to a part. */ String[] parts = id.split("(? values) { // Convert the object list to string array @@ -108,8 +109,9 @@ public static String concatValues(List values) { /** * Concat property values with NAME_SPLITOR + * * @param values the property values to be concatted - * @return concatted string value + * @return concatted string value */ public static String concatValues(Object... values) { return concatValues(Arrays.asList(values)); @@ -117,8 +119,9 @@ public static String concatValues(Object... values) { /** * Concat multiple parts into a single id with ID_SPLITOR + * * @param parts the string id values to be spliced - * @return spliced id object + * @return spliced id object */ public static Id splicing(String... parts) { String escaped = IdUtil.escape(ID_SPLITOR, ESCAPE, parts); @@ -141,8 +144,9 @@ public static Id generateBinaryId(Id id) { /** * Parse a single id into multiple parts with ID_SPLITOR + * * @param id the id object to be parsed - * @return parsed string id parts + * @return parsed string id parts */ public static String[] parse(Id id) { return IdUtil.unescape(id.asString(), ID_SPLITOR_STR, ESCAPE_STR); diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/options/AuthOptions.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/options/AuthOptions.java deleted file mode 100644 index 27bbb963b5..0000000000 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/options/AuthOptions.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2017 HugeGraph Authors - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package org.apache.hugegraph.options; - -import org.apache.hugegraph.config.ConfigOption; -import org.apache.hugegraph.config.OptionHolder; - -import static org.apache.hugegraph.config.OptionChecker.*; - -public class AuthOptions extends OptionHolder { - - private AuthOptions() { - super(); - } - - private static volatile AuthOptions instance; - - public static synchronized AuthOptions instance() { - if (instance == null) { - instance = new AuthOptions(); - instance.registerOptions(); - } - return instance; - } - - public static final ConfigOption AUTH_AUDIT_LOG_RATE = - new ConfigOption<>( - "auth.audit_log_rate", - "The max rate of audit log output per user, " + - "default value is 1000 records per second.", - rangeDouble(0.0, Double.MAX_VALUE), - 1000.0 - ); - - public static final ConfigOption AUTH_PROXY_CACHE_EXPIRE = - new ConfigOption<>( - "auth.proxy_cache_expire", - "The expiration time in seconds of auth cache in " + - "auth client.", - rangeInt(0L, Long.MAX_VALUE), - (1 * 60L) - ); - - public static final ConfigOption AUTH_CACHE_CAPACITY = - new ConfigOption<>( - "auth.cache_capacity", - "The max cache capacity of each auth cache item.", - rangeInt(0L, Long.MAX_VALUE), - (1024 * 10L) - ); - - public static final ConfigOption AUTHENTICATOR = - new ConfigOption<>( - "auth.authenticator", - "The class path of authenticator implementation. " + - "e.g., org.apache.hugegraph.auth.StandardAuthenticator.", - null, - "" - ); - - public static final ConfigOption AUTH_GRAPH_STORE = - new ConfigOption<>( - "auth.graph_store", - "The name of graph used to store authentication information, " + - "like users, only for org.apache.hugegraph.auth.StandardAuthenticator.", - disallowEmpty(), - "hugegraph" - ); - - public static final ConfigOption AUTH_REMOTE_URL = - new ConfigOption<>( - "auth.remote_url", - "If the address is empty, it provide auth service, " + - "otherwise it is auth client and also provide auth service " + - "through rpc forwarding. The remote url can be set to " + - "multiple addresses, which are concat by ','.", - null, - "" - ); - - public static final ConfigOption AUTH_CACHE_EXPIRE = - new ConfigOption<>( - "auth.cache_expire", - "The expiration time in seconds of auth cache in " + - "auth client and auth server.", - rangeInt(0L, Long.MAX_VALUE), - (60 * 10L) - ); - - public static final ConfigOption AUTH_TOKEN_EXPIRE = - new ConfigOption<>( - "auth.token_expire", - "The expiration time in seconds after token created", - rangeInt(0L, Long.MAX_VALUE), - (3600 * 24L) - ); -} diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/options/CoreOptions.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/options/CoreOptions.java deleted file mode 100644 index e11f76d349..0000000000 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/options/CoreOptions.java +++ /dev/null @@ -1,660 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph.options; - -import org.apache.hugegraph.config.ConfigConvOption; -import org.apache.hugegraph.config.ConfigOption; -import org.apache.hugegraph.config.OptionHolder; -import org.apache.hugegraph.query.Query; -import org.apache.hugegraph.type.define.CollectionType; -import org.apache.hugegraph.util.Bytes; - -import static org.apache.hugegraph.config.OptionChecker.*; -import static org.apache.hugegraph.query.Query.COMMIT_BATCH; - -public class CoreOptions extends OptionHolder { - - public static final int CPUS = Runtime.getRuntime().availableProcessors(); - public static final ConfigOption GREMLIN_GRAPH = - new ConfigOption<>( - "gremlin.graph", - "Gremlin entrance to create graph.", - disallowEmpty(), - "org.apache.hugegraph.HugeFactory" - ); - public static final ConfigOption BACKEND = - new ConfigOption<>( - "backend", - "The data store type.", - disallowEmpty(), - "memory" - ); - public static final ConfigOption STORE = - new ConfigOption<>( - "store", - "The backend database name.", - disallowEmpty(), - "hugegraph" - ); - public static final ConfigOption STORE_GRAPH = - new ConfigOption<>( - "store.graph", - "The graph table name, which store vertex, edge and property.", - disallowEmpty(), - "g" - ); - public static final ConfigOption ALIAS_NAME = - new ConfigOption<>( - "alias.graph.id", - "The graph alias id.", - "" - ); - public static final ConfigOption SERIALIZER = - new ConfigOption<>( - "serializer", - "The serializer for backend store, like: text/binary.", - disallowEmpty(), - "text" - ); - public static final ConfigOption RAFT_MODE = - new ConfigOption<>( - "raft.mode", - "Whether the backend storage works in raft mode.", - disallowEmpty(), - false - ); - public static final ConfigOption RAFT_SAFE_READ = - new ConfigOption<>( - "raft.safe_read", - "Whether to use linearly consistent read.", - disallowEmpty(), - false - ); - public static final ConfigOption RAFT_PATH = - new ConfigOption<>( - "raft.path", - "The log path of current raft node.", - disallowEmpty(), - "./raftlog" - ); - public static final ConfigOption RAFT_REPLICATOR_PIPELINE = - new ConfigOption<>( - "raft.use_replicator_pipeline", - "Whether to use replicator line, when turned on it " + - "multiple logs can be sent in parallel, and the next log " + - "doesn't have to wait for the ack message of the current " + - "log to be sent.", - disallowEmpty(), - true - ); - public static final ConfigOption RAFT_ELECTION_TIMEOUT = - new ConfigOption<>( - "raft.election_timeout", - "Timeout in milliseconds to launch a round of election.", - rangeInt(0, Integer.MAX_VALUE), - 10000 - ); - public static final ConfigOption RAFT_SNAPSHOT_INTERVAL = - new ConfigOption<>( - "raft.snapshot_interval", - "The interval in seconds to trigger snapshot save.", - rangeInt(0, Integer.MAX_VALUE), - 3600 - ); - public static final ConfigOption RAFT_SNAPSHOT_THREADS = - new ConfigOption<>( - "raft.snapshot_threads", - "The thread number used to do snapshot.", - rangeInt(0, Integer.MAX_VALUE), - 4 - ); - public static final ConfigOption RAFT_SNAPSHOT_PARALLEL_COMPRESS = - new ConfigOption<>( - "raft.snapshot_parallel_compress", - "Whether to enable parallel compress.", - disallowEmpty(), - false - ); - public static final ConfigOption RAFT_SNAPSHOT_COMPRESS_THREADS = - new ConfigOption<>( - "raft.snapshot_compress_threads", - "The thread number used to do snapshot compress.", - rangeInt(0, Integer.MAX_VALUE), - 4 - ); - public static final ConfigOption RAFT_SNAPSHOT_DECOMPRESS_THREADS = - new ConfigOption<>( - "raft.snapshot_decompress_threads", - "The thread number used to do snapshot decompress.", - rangeInt(0, Integer.MAX_VALUE), - 4 - ); - public static final ConfigOption RAFT_BACKEND_THREADS = - new ConfigOption<>( - "raft.backend_threads", - "The thread number used to apply task to backend.", - rangeInt(0, Integer.MAX_VALUE), - CPUS - ); - public static final ConfigOption RAFT_READ_INDEX_THREADS = - new ConfigOption<>( - "raft.read_index_threads", - "The thread number used to execute reading index.", - rangeInt(0, Integer.MAX_VALUE), - 8 - ); - public static final ConfigOption RAFT_READ_STRATEGY = - new ConfigOption<>( - "raft.read_strategy", - "The linearizability of read strategy.", - allowValues("ReadOnlyLeaseBased", "ReadOnlySafe"), - "ReadOnlyLeaseBased" - ); - public static final ConfigOption RAFT_APPLY_BATCH = - new ConfigOption<>( - "raft.apply_batch", - "The apply batch size to trigger disruptor event handler.", - positiveInt(), - // jraft default value is 32 - 1 - ); - public static final ConfigOption RAFT_QUEUE_SIZE = - new ConfigOption<>( - "raft.queue_size", - "The disruptor buffers size for jraft RaftNode, " + - "StateMachine and LogManager.", - positiveInt(), - // jraft default value is 16384 - 16384 - ); - public static final ConfigOption RAFT_QUEUE_PUBLISH_TIMEOUT = - new ConfigOption<>( - "raft.queue_publish_timeout", - "The timeout in second when publish event into disruptor.", - positiveInt(), - // jraft default value is 10(sec) - 60 - ); - public static final ConfigOption RAFT_RPC_THREADS = - new ConfigOption<>( - "raft.rpc_threads", - "The rpc threads for jraft RPC layer", - positiveInt(), - // jraft default value is 80 - Math.max(CPUS * 2, 80) - ); - public static final ConfigOption RAFT_RPC_CONNECT_TIMEOUT = - new ConfigOption<>( - "raft.rpc_connect_timeout", - "The rpc connect timeout for jraft rpc.", - positiveInt(), - // jraft default value is 1000(ms) - 5000 - ); - public static final ConfigOption RAFT_RPC_TIMEOUT = - new ConfigOption<>( - "raft.rpc_timeout", - "The general rpc timeout in seconds for jraft rpc.", - positiveInt(), - // jraft default value is 5s - 60 - ); - public static final ConfigOption RAFT_INSTALL_SNAPSHOT_TIMEOUT = - new ConfigOption<>( - "raft.install_snapshot_rpc_timeout", - "The install snapshot rpc timeout in seconds for jraft rpc.", - positiveInt(), - // jraft default value is 5 minutes - 10 * 60 * 60 - ); - public static final ConfigOption RAFT_RPC_BUF_LOW_WATER_MARK = - new ConfigOption<>( - "raft.rpc_buf_low_water_mark", - "The ChannelOutboundBuffer's low water mark of netty, " + - "when buffer size less than this size, the method " + - "ChannelOutboundBuffer.isWritable() will return true, " + - "it means that low downstream pressure or good network.", - positiveInt(), - 10 * 1024 * 1024 - ); - public static final ConfigOption RAFT_RPC_BUF_HIGH_WATER_MARK = - new ConfigOption<>( - "raft.rpc_buf_high_water_mark", - "The ChannelOutboundBuffer's high water mark of netty, " + - "only when buffer size exceed this size, the method " + - "ChannelOutboundBuffer.isWritable() will return false, " + - "it means that the downstream pressure is too great to " + - "process the request or network is very congestion, " + - "upstream needs to limit rate at this time.", - positiveInt(), - 20 * 1024 * 1024 - ); - public static final ConfigOption RATE_LIMIT_WRITE = - new ConfigOption<>( - "rate_limit.write", - "The max rate(items/s) to add/update/delete vertices/edges.", - rangeInt(0, Integer.MAX_VALUE), - 0 - ); - public static final ConfigOption RATE_LIMIT_READ = - new ConfigOption<>( - "rate_limit.read", - "The max rate(times/s) to execute query of vertices/edges.", - rangeInt(0, Integer.MAX_VALUE), - 0 - ); - public static final ConfigOption TASK_SCHEDULE_PERIOD = - new ConfigOption<>( - "task.schedule_period", - "Period time when scheduler to schedule task", - rangeInt(0L, Long.MAX_VALUE), - 10L - ); - public static final ConfigOption TASK_WAIT_TIMEOUT = - new ConfigOption<>( - "task.wait_timeout", - "Timeout in seconds for waiting for the task to " + - "complete, such as when truncating or clearing the " + - "backend.", - rangeInt(0L, Long.MAX_VALUE), - 10L - ); - public static final ConfigOption TASK_INPUT_SIZE_LIMIT = - new ConfigOption<>( - "task.input_size_limit", - "The job input size limit in bytes.", - rangeInt(0L, Bytes.GB), - 16 * Bytes.MB - ); - public static final ConfigOption TASK_RESULT_SIZE_LIMIT = - new ConfigOption<>( - "task.result_size_limit", - "The job result size limit in bytes.", - rangeInt(0L, Bytes.GB), - 16 * Bytes.MB - ); - public static final ConfigOption TASK_TTL_DELETE_BATCH = - new ConfigOption<>( - "task.ttl_delete_batch", - "The batch size used to delete expired data.", - rangeInt(1, 500), - 1 - ); - - public static final ConfigOption TASK_SYNC_DELETION = - new ConfigOption<>( - "task.sync_deletion", - "Whether to delete schema or expired data synchronously.", - disallowEmpty(), - false - ); - public static final ConfigOption TASK_RETRY = - new ConfigOption<>( - "task.retry", - "Task retry times.", - rangeInt(0, 3), - 0 - ); - public static final ConfigOption STORE_CONN_DETECT_INTERVAL = - new ConfigOption<>( - "store.connection_detect_interval", - "The interval in seconds for detecting connections, " + - "if the idle time of a connection exceeds this value, " + - "detect it and reconnect if needed before using, " + - "value 0 means detecting every time.", - rangeInt(0L, Long.MAX_VALUE), - 600L - ); - public static final ConfigOption VERTEX_DEFAULT_LABEL = - new ConfigOption<>( - "vertex.default_label", - "The default vertex label.", - disallowEmpty(), - "vertex" - ); - public static final ConfigOption VERTEX_CHECK_CUSTOMIZED_ID_EXIST = - new ConfigOption<>( - "vertex.check_customized_id_exist", - "Whether to check the vertices exist for those using " + - "customized id strategy.", - disallowEmpty(), - false - ); - public static final ConfigOption VERTEX_REMOVE_LEFT_INDEX = - new ConfigOption<>( - "vertex.remove_left_index_at_overwrite", - "Whether remove left index at overwrite.", - disallowEmpty(), - false - ); - public static final ConfigOption VERTEX_ADJACENT_VERTEX_EXIST = - new ConfigOption<>( - "vertex.check_adjacent_vertex_exist", - "Whether to check the adjacent vertices of edges exist.", - disallowEmpty(), - false - ); - public static final ConfigOption VERTEX_ADJACENT_VERTEX_LAZY = - new ConfigOption<>( - "vertex.lazy_load_adjacent_vertex", - "Whether to lazy load adjacent vertices of edges.", - disallowEmpty(), - true - ); - public static final ConfigOption VERTEX_PART_EDGE_COMMIT_SIZE = - new ConfigOption<>( - "vertex.part_edge_commit_size", - "Whether to enable the mode to commit part of edges of " + - "vertex, enabled if commit size > 0, 0 meas disabled.", - rangeInt(0, (int) Query.DEFAULT_CAPACITY), - 5000 - ); - public static final ConfigOption VERTEX_ENCODE_PK_NUMBER = - new ConfigOption<>( - "vertex.encode_primary_key_number", - "Whether to encode number value of primary key " + - "in vertex id.", - disallowEmpty(), - true - ); - public static final ConfigOption VERTEX_TX_CAPACITY = - new ConfigOption<>( - "vertex.tx_capacity", - "The max size(items) of vertices(uncommitted) in " + - "transaction.", - rangeInt((int) COMMIT_BATCH, 1000000), - 10000 - ); - public static final ConfigOption QUERY_IGNORE_INVALID_DATA = - new ConfigOption<>( - "query.ignore_invalid_data", - "Whether to ignore invalid data of vertex or edge.", - disallowEmpty(), - true - ); - public static final ConfigOption QUERY_OPTIMIZE_AGGR_BY_INDEX = - new ConfigOption<>( - "query.optimize_aggregate_by_index", - "Whether to optimize aggregate query(like count) by index.", - disallowEmpty(), - false - ); - public static final ConfigOption QUERY_BATCH_SIZE = - new ConfigOption<>( - "query.batch_size", - "The size of each batch when querying by batch.", - rangeInt(1, (int) Query.DEFAULT_CAPACITY), - 1000 - ); - public static final ConfigOption QUERY_PAGE_SIZE = - new ConfigOption<>( - "query.page_size", - "The size of each page when querying by paging.", - rangeInt(1, (int) Query.DEFAULT_CAPACITY), - 500 - ); - public static final ConfigOption QUERY_INDEX_INTERSECT_THRESHOLD = - new ConfigOption<>( - "query.index_intersect_threshold", - "The maximum number of intermediate results to " + - "intersect indexes when querying by multiple single " + - "index properties.", - rangeInt(1, (int) Query.DEFAULT_CAPACITY), - 1000 - ); - public static final ConfigOption SCHEMA_INIT_TEMPLATE = - new ConfigOption<>( - "schema.init_template", - "The template schema used to init graph", - null, - "" - ); - public static final ConfigOption SCHEMA_INDEX_REBUILD_USING_PUSHDOWN = - new ConfigOption<>( - "schema.index_rebuild_using_pushdown", - "Whether to use pushdown when to create/rebuid index.", - true - ); - public static final ConfigOption QUERY_RAMTABLE_ENABLE = - new ConfigOption<>( - "query.ramtable_enable", - "Whether to enable ramtable for query of adjacent edges.", - disallowEmpty(), - false - ); - public static final ConfigOption QUERY_RAMTABLE_VERTICES_CAPACITY = - new ConfigOption<>( - "query.ramtable_vertices_capacity", - "The maximum number of vertices in ramtable, " + - "generally the largest vertex id is used as capacity.", - rangeInt(1L, Integer.MAX_VALUE * 2L), - 10000000L - ); - public static final ConfigOption QUERY_RAMTABLE_EDGES_CAPACITY = - new ConfigOption<>( - "query.ramtable_edges_capacity", - "The maximum number of edges in ramtable, " + - "include OUT and IN edges.", - rangeInt(1, Integer.MAX_VALUE), - 20000000 - ); - /** - * The schema name rule: - * 1. Not allowed end with spaces - * 2. Not allowed start with '~' - */ - public static final ConfigOption SCHEMA_ILLEGAL_NAME_REGEX = - new ConfigOption<>( - "schema.illegal_name_regex", - "The regex specified the illegal format for schema name.", - disallowEmpty(), - ".*\\s+$|~.*" - ); - public static final ConfigOption SCHEMA_CACHE_CAPACITY = - new ConfigOption<>( - "schema.cache_capacity", - "The max cache size(items) of schema cache.", - rangeInt(0L, Long.MAX_VALUE), - 10000L - ); - public static final ConfigOption VERTEX_CACHE_TYPE = - new ConfigOption<>( - "vertex.cache_type", - "The type of vertex cache, allowed values are [l1, l2].", - allowValues("l1", "l2"), - "l2" - ); - public static final ConfigOption VERTEX_CACHE_CAPACITY = - new ConfigOption<>( - "vertex.cache_capacity", - "The max cache size(items) of vertex cache.", - rangeInt(0L, Long.MAX_VALUE), - (1000 * 1000 * 10L) - ); - public static final ConfigOption VERTEX_CACHE_EXPIRE = - new ConfigOption<>( - "vertex.cache_expire", - "The expiration time in seconds of vertex cache.", - rangeInt(0, Integer.MAX_VALUE), - (60 * 10) - ); - public static final ConfigOption EDGE_CACHE_TYPE = - new ConfigOption<>( - "edge.cache_type", - "The type of edge cache, allowed values are [l1, l2].", - allowValues("l1", "l2"), - "l2" - ); - public static final ConfigOption EDGE_CACHE_CAPACITY = - new ConfigOption<>( - "edge.cache_capacity", - "The max cache size(items) of edge cache.", - rangeInt(0L, Long.MAX_VALUE), - ((long) 1000 * 1000) - ); - public static final ConfigOption EDGE_CACHE_EXPIRE = - new ConfigOption<>( - "edge.cache_expire", - "The expiration time in seconds of edge cache.", - rangeInt(0, Integer.MAX_VALUE), - (60 * 10) - ); - public static final ConfigOption SNOWFLAKE_WORKER_ID = - new ConfigOption<>( - "snowflake.worker_id", - "The worker id of snowflake id generator.", - disallowEmpty(), - 0L - ); - public static final ConfigOption SNOWFLAKE_DATACENTER_ID = - new ConfigOption<>( - "snowflake.datacenter_id", - "The datacenter id of snowflake id generator.", - disallowEmpty(), - 0L - ); - public static final ConfigOption SNOWFLAKE_FORCE_STRING = - new ConfigOption<>( - "snowflake.force_string", - "Whether to force the snowflake long id to be a string.", - disallowEmpty(), - false - ); - public static final ConfigOption TEXT_ANALYZER = - new ConfigOption<>( - "search.text_analyzer", - "Choose a text analyzer for searching the " + - "vertex/edge properties, available type are " + - "[ansj, hanlp, smartcn, jieba, jcseg, " + - "mmseg4j, ikanalyzer].", - disallowEmpty(), - "ikanalyzer" - ); - public static final ConfigOption TEXT_ANALYZER_MODE = - new ConfigOption<>( - "search.text_analyzer_mode", - "Specify the mode for the text analyzer, " + - "the available mode of analyzer are " + - "ansj: [BaseAnalysis, IndexAnalysis, ToAnalysis, " + - "NlpAnalysis], " + - "hanlp: [standard, nlp, index, nShort, shortest, speed], " + - "smartcn: [], " + - "jieba: [SEARCH, INDEX], " + - "jcseg: [Simple, Complex], " + - "mmseg4j: [Simple, Complex, MaxWord], " + - "ikanalyzer: [smart, max_word]" + - "}.", - disallowEmpty(), - "smart" - ); - public static final ConfigOption COMPUTER_CONFIG = - new ConfigOption<>( - "computer.config", - "The config file path of computer job.", - disallowEmpty(), - "./conf/computer.yaml" - ); - public static final ConfigOption K8S_OPERATOR_TEMPLATE = - new ConfigOption<>( - "k8s.operator_template", - "the path of operator container template.", - disallowEmpty(), - "./conf/operator-template.yaml" - ); - public static final ConfigOption K8S_QUOTA_TEMPLATE = - new ConfigOption<>( - "k8s.quota_template", - "the path of resource quota template.", - disallowEmpty(), - "./conf/resource-quota-template.yaml" - ); - public static final ConfigOption OLTP_CONCURRENT_THREADS = - new ConfigOption<>( - "oltp.concurrent_threads", - "Thread number to concurrently execute oltp algorithm.", - rangeInt(0, 65535), - 10 - ); - public static final ConfigOption OLTP_CONCURRENT_DEPTH = - new ConfigOption<>( - "oltp.concurrent_depth", - "The min depth to enable concurrent oltp algorithm.", - rangeInt(0, 65535), - 10 - ); - public static final ConfigConvOption OLTP_COLLECTION_TYPE = - new ConfigConvOption<>( - "oltp.collection_type", - "The implementation type of collections " + - "used in oltp algorithm.", - allowValues("JCF", "EC", "FU"), - CollectionType::valueOf, - "EC" - ); - public static final ConfigOption PD_PEERS = new ConfigOption<>( - "pd.peers", - "The addresses of pd nodes, separated with commas.", - disallowEmpty(), - "127.0.0.1:8686" - ); - public static final ConfigOption MEMORY_MODE = new ConfigOption<>( - "memory.mode", - "The memory mode used for query in HugeGraph.", - disallowEmpty(), - "off-heap" - ); - public static final ConfigOption MAX_MEMORY_CAPACITY = new ConfigOption<>( - "memory.max_capacity", - "The maximum memory capacity that can be managed for all queries in HugeGraph.", - nonNegativeInt(), - Bytes.GB - ); - public static final ConfigOption ONE_QUERY_MAX_MEMORY_CAPACITY = new ConfigOption<>( - "memory.one_query_max_capacity", - "The maximum memory capacity that can be managed for a query in HugeGraph.", - nonNegativeInt(), - Bytes.MB * 100 - ); - public static final ConfigOption MEMORY_ALIGNMENT = new ConfigOption<>( - "memory.alignment", - "The alignment used for round memory size.", - nonNegativeInt(), - 8L - ); - public static final ConfigOption GRAPH_SPACE = - new ConfigOption<>( - "graphspace", - "The graph space name.", - null, - "DEFAULT" - ); - private static volatile CoreOptions instance; - - private CoreOptions() { - super(); - } - - public static synchronized CoreOptions instance() { - if (instance == null) { - instance = new CoreOptions(); - // Should initialize all static members first, then register. - instance.registerOptions(); - } - return instance; - } -} diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/query/Aggregate.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/Aggregate.java index 38f1365f67..51d2ee9db4 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/query/Aggregate.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/Aggregate.java @@ -20,19 +20,21 @@ package org.apache.hugegraph.query; import java.util.Iterator; +import java.util.function.BiFunction; + +import org.apache.tinkerpop.gremlin.util.NumberHelper; -@Deprecated public class Aggregate

{ private final AggregateFuncDefine

func; private final String column; - public Aggregate(AggregateFuncDefine func, String column) { + public Aggregate(AggregateFuncDefine

func, String column) { this.func = func; this.column = column; } - public AggregateFuncDefine func() { + public AggregateFuncDefine

func() { return this.func; } @@ -58,4 +60,58 @@ public String toString() { this.column == null ? "*" : this.column); } + public enum AggregateFunc implements AggregateFuncDefine { + + COUNT("count", 0L, NumberHelper::add), + MAX("max", -Double.MAX_VALUE, NumberHelper::max), + MIN("min", Double.MAX_VALUE, NumberHelper::min), + AVG("avg", 0D, NumberHelper::add), + SUM("sum", 0L, NumberHelper::add); + + private final String name; + private final Number defaultValue; + private final BiFunction merger; + + AggregateFunc(String name, Number defaultValue, + BiFunction merger) { + this.name = name; + this.defaultValue = defaultValue; + this.merger = merger; + } + + @Override + public String string() { + return this.name; + } + + @Override + public boolean countAll() { + return this == COUNT; + } + + @Override + public Number defaultValue() { + return this.defaultValue; + } + + @Override + public Number reduce(Iterator results) { + Number number; + long count = 0L; + if (results.hasNext()) { + number = results.next(); + count++; + } else { + return this.defaultValue; + } + while (results.hasNext()) { + number = this.merger.apply(number, results.next()); + count++; + } + if (this == AVG) { + number = NumberHelper.div(number, count); + } + return number; + } + } } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/query/AggregateFuncDefine.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/AggregateFuncDefine.java index d883aab49c..7cd74118c6 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/query/AggregateFuncDefine.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/AggregateFuncDefine.java @@ -26,7 +26,8 @@ * * @param

*/ -public interface AggregateFuncDefine

{ +public interface AggregateFuncDefine

{ + String string(); P defaultValue(); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/BatchConditionQuery.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/BatchConditionQuery.java similarity index 96% rename from hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/BatchConditionQuery.java rename to hugegraph-struct/src/main/java/org/apache/hugegraph/query/BatchConditionQuery.java index 181ee48648..32f09e03e3 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/BatchConditionQuery.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/BatchConditionQuery.java @@ -15,13 +15,13 @@ * limitations under the License. */ -package org.apache.hugegraph.backend.query; +package org.apache.hugegraph.query; import java.util.ArrayList; import java.util.List; import java.util.Objects; -import org.apache.hugegraph.backend.query.Condition.RelationType; +import org.apache.hugegraph.query.Condition.RelationType; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.HugeKeys; import org.apache.hugegraph.util.E; diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/query/Condition.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/Condition.java index d1ec7e52fa..c2d63e4f35 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/query/Condition.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/Condition.java @@ -17,10 +17,16 @@ package org.apache.hugegraph.query; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import org.apache.commons.lang.ArrayUtils; -import org.apache.commons.text.similarity.LevenshteinDistance; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.BiFunction; +import java.util.regex.Pattern; + import org.apache.hugegraph.backend.Shard; import org.apache.hugegraph.id.Id; import org.apache.hugegraph.structure.BaseElement; @@ -32,9 +38,10 @@ import org.apache.hugegraph.util.NumericUtil; import org.apache.tinkerpop.gremlin.process.traversal.PBiPredicate; -import java.util.*; -import java.util.function.BiFunction; -import java.util.regex.Pattern; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.text.similarity.LevenshteinDistance; public abstract class Condition { diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/query/ConditionQuery.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/ConditionQuery.java index 553fec9b8c..44bc00e824 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/query/ConditionQuery.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/ConditionQuery.java @@ -17,17 +17,26 @@ package org.apache.hugegraph.query; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; +import java.math.BigDecimal; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.id.Id; import org.apache.hugegraph.id.SplicingIdGenerator; import org.apache.hugegraph.perf.PerfUtil.Watched; import org.apache.hugegraph.query.Condition.Relation; import org.apache.hugegraph.query.Condition.RelationType; +import org.apache.hugegraph.query.serializer.AggregateAdapter; import org.apache.hugegraph.query.serializer.QueryAdapter; import org.apache.hugegraph.query.serializer.QueryIdAdapter; import org.apache.hugegraph.structure.BaseElement; @@ -35,12 +44,18 @@ import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.CollectionType; import org.apache.hugegraph.type.define.HugeKeys; -import org.apache.hugegraph.util.*; +import org.apache.hugegraph.util.CollectionUtil; +import org.apache.hugegraph.util.E; +import org.apache.hugegraph.util.InsertionOrderUtil; +import org.apache.hugegraph.util.LongEncoding; +import org.apache.hugegraph.util.NumericUtil; import org.apache.hugegraph.util.collection.CollectionFactory; -import java.math.BigDecimal; -import java.nio.charset.StandardCharsets; -import java.util.*; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; public class ConditionQuery extends IdQuery { @@ -57,9 +72,9 @@ public class ConditionQuery extends IdQuery { private static final Gson gson = new GsonBuilder() .registerTypeAdapter(Condition.class, new QueryAdapter()) .registerTypeAdapter(Id.class, new QueryIdAdapter()) + .registerTypeAdapter(Aggregate.class, new AggregateAdapter()) .setDateFormat("yyyy-MM-dd HH:mm:ss.SSS") .create(); - private static final int indexStringValueLength = 20; static { List list = new ArrayList<>(INDEX_SYM_MAX - INDEX_SYM_MIN); @@ -91,91 +106,6 @@ public ConditionQuery(HugeType resultType, Query originQuery) { super(resultType, originQuery); } - /** - * Index and composite index interception - * - * @param values - * @return - */ - public static String concatValuesLimitLength(List values) { - List newValues = new ArrayList<>(values.size()); - for (Object v : values) { - v = convertLargeValue(v); - newValues.add(convertNumberIfNeeded(v)); - } - return SplicingIdGenerator.concatValues(newValues); - } - - /** - * Index and composite index interception - * - * @param value - * @return - */ - public static String concatValuesLimitLength(Object value) { - if (value instanceof List) { - return concatValuesLimitLength((List) value); - } - - if (needConvertNumber(value)) { - return LongEncoding.encodeNumber(value); - } - value = convertLargeValue(value); - return value.toString(); - } - - public static int getIndexStringValueLength() { - return indexStringValueLength; - } - - /** - * Extract the String value - * - * @param v - * @return - */ - private static Object convertLargeValue(Object v) { - - if (Objects.nonNull(v) && v instanceof String && - ((String) v).length() > getIndexStringValueLength()) { - - v = ((String) v).substring(0, getIndexStringValueLength()); - - } - - return v; - } - - private static Object convertNumberIfNeeded(Object value) { - if (needConvertNumber(value)) { - return LongEncoding.encodeNumber(value); - } - return value; - } - - private static boolean removeValue(Set values, Object value) { - for (Object compareValue : values) { - if (numberEquals(compareValue, value)) { - values.remove(compareValue); - return true; - } - } - return false; - } - - private static boolean numberEquals(Object number1, Object number2) { - // Same class compare directly - if (number1.getClass().equals(number2.getClass())) { - return number1.equals(number2); - } - // Otherwise convert to BigDecimal to make two numbers comparable - Number n1 = NumericUtil.convertToNumber(number1); - Number n2 = NumericUtil.convertToNumber(number2); - BigDecimal b1 = BigDecimal.valueOf(n1.doubleValue()); - BigDecimal b2 = BigDecimal.valueOf(n2.doubleValue()); - return b1.compareTo(b2) == 0; - } - public static String concatValues(List values) { assert !values.isEmpty(); List newValues = new ArrayList<>(values.size()); @@ -199,15 +129,8 @@ public static String concatValues(Object value) { } public static ConditionQuery fromBytes(byte[] bytes) { - Gson gson = new GsonBuilder() - .registerTypeAdapter(Condition.class, new QueryAdapter()) - .registerTypeAdapter(Id.class, new QueryIdAdapter()) - .setDateFormat("yyyy-MM-dd HH:mm:ss.SSS") - .create(); - String cqs = new String(bytes, StandardCharsets.UTF_8); - ConditionQuery conditionQuery = gson.fromJson(cqs, ConditionQuery.class); - - return conditionQuery; + return gson.fromJson(new String(bytes, StandardCharsets.UTF_8), + ConditionQuery.class); } private static boolean needConvertNumber(Object value) { @@ -256,11 +179,7 @@ public boolean shard() { return this.shard; } - private void ensureElement2IndexValueMap() { - if (this.element2IndexValueMap == null) { - this.element2IndexValueMap = new Element2IndexValueMap(); - } - } + public ConditionQuery query(Condition condition) { // Query by id (HugeGraph-259) @@ -345,12 +264,10 @@ public void resetConditions() { } public void recordIndexValue(Id propertyId, Id id, Object indexValue) { - this.ensureElement2IndexValueMap(); this.element2IndexValueMap().addIndexValue(propertyId, id, indexValue); } public void selectedIndexField(Id indexField) { - this.ensureElement2IndexValueMap(); this.element2IndexValueMap().selectedIndexField(indexField); } @@ -491,24 +408,27 @@ public T condition(Object key) { return value; } + boolean initialized = false; Set intersectValues = InsertionOrderUtil.newSet(); for (Object value : valuesEQ) { List valueAsList = ImmutableList.of(value); - if (intersectValues.isEmpty()) { + if (!initialized) { intersectValues.addAll(valueAsList); + initialized = true; } else { CollectionUtil.intersectWithModify(intersectValues, - valueAsList); + valueAsList); } } for (Object value : valuesIN) { @SuppressWarnings("unchecked") List valueAsList = (List) value; - if (intersectValues.isEmpty()) { + if (!initialized) { intersectValues.addAll(valueAsList); + initialized = true; } else { CollectionUtil.intersectWithModify(intersectValues, - valueAsList); + valueAsList); } } @@ -516,8 +436,8 @@ public T condition(Object key) { return null; } E.checkState(intersectValues.size() == 1, - "Illegal key '%s' with more than one value: %s", - key, intersectValues); + "Illegal key '%s' with more than one value: %s", + key, intersectValues); @SuppressWarnings("unchecked") T value = (T) intersectValues.iterator().next(); return value; @@ -705,30 +625,7 @@ public String userpropValuesString(List fields) { return concatValues(values); } - public String userpropValuesStringForIndex(List fields) { - List values = new ArrayList<>(fields.size()); - for (Id field : fields) { - boolean got = false; - for (Relation r : this.userpropRelations()) { - if (r.key().equals(field) && !r.isSysprop()) { - E.checkState(r.relation() == RelationType.EQ || - r.relation() == RelationType.CONTAINS, - "Method userpropValues(List) only " + - "used for secondary index, " + - "relation must be EQ or CONTAINS, but got %s", - r.relation()); - values.add(r.serialValue()); - got = true; - } - } - if (!got) { - throw new BackendException( - "No such userprop named '%s' in the query '%s'", - field, this); - } - } - return concatValuesLimitLength(values); - } + public Set userpropValues(Id field) { Set values = new HashSet<>(); @@ -856,6 +753,10 @@ public Condition.Relation copyRelationAndUpdateQuery(Object key) { @Override public boolean test(BaseElement element) { + return this.test(element, this.resultsFilter); + } + + public boolean test(BaseElement element, ResultsFilter filter) { if (!this.ids().isEmpty() && !super.test(element)) { return false; } @@ -867,19 +768,25 @@ public boolean test(BaseElement element) { * We can't use sub-query results-filter here for fresh element which is * not committed to backend store, because it's not from a sub-query. */ - if (this.resultsFilter != null && !element.fresh()) { - return this.resultsFilter.test(element); + if (filter != null && !element.fresh()) { + return filter.test(element); } /* * NOTE: seems need to keep call checkRangeIndex() for each condition, * so don't break early even if test() return false. - */ + */ boolean valid = true; + Map rangeIndexMatches = null; + if (this.element2IndexValueMap != null) { + rangeIndexMatches = new HashMap<>(); + } for (Condition cond : this.conditions) { valid &= cond.test(element); - valid &= this.element2IndexValueMap == null || - this.element2IndexValueMap.checkRangeIndex(element, cond); + if (this.element2IndexValueMap != null) { + valid &= this.element2IndexValueMap.checkRangeIndex( + element, cond, rangeIndexMatches); + } } return valid; } @@ -944,6 +851,10 @@ public void registerResultsFilter(ResultsFilter filter) { this.resultsFilter = filter; } + public ResultsFilter resultsFilter() { + return this.resultsFilter; + } + public void updateResultsFilter() { Query originQuery = this.originQuery(); if (originQuery instanceof ConditionQuery) { @@ -1017,15 +928,7 @@ private static boolean removeFieldValue(Set values, return false; } - private static boolean removeValue(Set values, Object value) { - for (Object compareValue : values) { - if (numberEquals(compareValue, value)) { - values.remove(compareValue); - return true; - } - } - return false; - } + private static boolean numberEquals(Object number1, Object number2) { // Same class compare directly @@ -1068,10 +971,7 @@ public Set toRemoveIndexValues(Id indexField, Id elementId) { } public Set removeIndexValues(Id indexField, Id elementId) { - if (!this.filed2IndexValues.containsKey(indexField)) { - return null; - } - return this.filed2IndexValues.get(indexField).get(elementId); + return this.toRemoveIndexValues(indexField, elementId); } public void addLeftIndex(Id elementId, Id indexField, @@ -1090,12 +990,7 @@ public Set getLeftIndex(Id elementId) { public void addLeftIndex(Id indexField, Set indexValues, Id elementId) { - LeftIndex leftIndex = new LeftIndex(indexValues, indexField); - if (this.leftIndexMap.containsKey(elementId)) { - this.leftIndexMap.get(elementId).add(leftIndex); - } else { - this.leftIndexMap.put(elementId, Sets.newHashSet(leftIndex)); - } + this.addLeftIndex(elementId, indexField, indexValues); } public void removeElementLeftIndex(Id elementId) { @@ -1103,25 +998,36 @@ public void removeElementLeftIndex(Id elementId) { } public boolean checkRangeIndex(BaseElement element, Condition cond) { + return this.checkRangeIndex(element, cond, new HashMap<>()); + } + + public boolean checkRangeIndex(BaseElement element, Condition cond, + Map rangeIndexMatches) { // Not UserpropRelation if (!(cond instanceof Condition.UserpropRelation)) { return true; } - Condition.UserpropRelation propRelation = (Condition.UserpropRelation) cond; + Condition.UserpropRelation propRelation = + (Condition.UserpropRelation) cond; Id propId = propRelation.key(); Set fieldValues = this.toRemoveIndexValues(propId, - element.id()); + element.id()); if (fieldValues == null) { // Not range index return true; } + if (rangeIndexMatches.containsKey(propId)) { + return rangeIndexMatches.get(propId); + } + BaseProperty property = element.getProperty(propId); if (property == null) { // Property value has been deleted, so it's not matched this.addLeftIndex(element.id(), propId, fieldValues); - return false; + return this.cacheRangeIndexMatch(rangeIndexMatches, propId, + false); } /* @@ -1130,7 +1036,7 @@ public boolean checkRangeIndex(BaseElement element, Condition cond) { * wait the left-index to be removed. */ boolean hasRightValue = removeFieldValue(fieldValues, - property.value()); + property.value()); if (!fieldValues.isEmpty()) { this.addLeftIndex(element.id(), propId, fieldValues); } @@ -1142,55 +1048,23 @@ public boolean checkRangeIndex(BaseElement element, Condition cond) { * the element is valid or not. */ if (this.selectedIndexField != null) { - return !propId.equals(this.selectedIndexField) || hasRightValue; + hasRightValue = !propId.equals(this.selectedIndexField) || + hasRightValue; } - return hasRightValue; + return this.cacheRangeIndexMatch(rangeIndexMatches, propId, + hasRightValue); } - public boolean validRangeIndex(BaseElement element, Condition cond) { - // Not UserpropRelation - if (!(cond instanceof Condition.UserpropRelation)) { - return true; - } - - Condition.UserpropRelation propRelation = (Condition.UserpropRelation) cond; - Id propId = propRelation.key(); - Set fieldValues = this.removeIndexValues(propId, - element.id()); - if (fieldValues == null) { - // Not range index - return true; - } - - BaseProperty hugeProperty = element.getProperty(propId); - if (hugeProperty == null) { - // Property value has been deleted - this.addLeftIndex(propId, fieldValues, element.id()); - return false; - } - - /* - * NOTE: If success remove means has correct index, - * we should add left index values to left index map - * waiting to be removed - */ - boolean hasRightValue = removeValue(fieldValues, hugeProperty.value()); - if (fieldValues.size() > 0) { - this.addLeftIndex(propId, fieldValues, element.id()); - } - - /* - * NOTE: When query by more than one range index field, - * if current field is not the selected one, it can only be used to - * determine whether the index values matched, can't determine - * the element is valid or not - */ - if (this.selectedIndexField != null) { - return !propId.equals(this.selectedIndexField) || hasRightValue; - } + private boolean cacheRangeIndexMatch(Map rangeIndexMatches, + Id propertyId, + boolean matched) { + rangeIndexMatches.put(propertyId, matched); + return matched; + } - return hasRightValue; + public boolean validRangeIndex(BaseElement element, Condition cond) { + return this.checkRangeIndex(element, cond, new HashMap<>()); } } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/IdPrefixQuery.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/IdPrefixQuery.java similarity index 94% rename from hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/IdPrefixQuery.java rename to hugegraph-struct/src/main/java/org/apache/hugegraph/query/IdPrefixQuery.java index c14a07070d..933d1ea9f2 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/IdPrefixQuery.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/IdPrefixQuery.java @@ -15,10 +15,10 @@ * limitations under the License. */ -package org.apache.hugegraph.backend.query; +package org.apache.hugegraph.query; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.structure.HugeElement; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.structure.BaseElement; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.util.Bytes; import org.apache.hugegraph.util.E; @@ -76,7 +76,7 @@ public boolean empty() { } @Override - public boolean test(HugeElement element) { + public boolean test(BaseElement element) { byte[] elem = element.id().asBytes(); int cmp = Bytes.compare(elem, this.start.asBytes()); boolean matchedStart = this.inclusiveStart ? cmp >= 0 : cmp > 0; diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/query/IdQuery.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/IdQuery.java index 1235dfebc0..b07359af4e 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/query/IdQuery.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/IdQuery.java @@ -29,6 +29,7 @@ import org.apache.hugegraph.util.InsertionOrderUtil; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; public class IdQuery extends Query { @@ -124,4 +125,67 @@ public IdQuery copy() { InsertionOrderUtil.newList(this.ids); return query; } + + public static final class OneIdQuery extends IdQuery { + + private Id id; + + public OneIdQuery(HugeType resultType, Id id) { + super(resultType); + super.mustSortByInput = false; + this.id = id; + } + + public OneIdQuery(Query originQuery, Id id) { + super(originQuery.resultType(), originQuery); + super.mustSortByInput = false; + this.id = id; + } + + public Id id() { + return this.id; + } + + public void resetId(Id id) { + this.id = id; + } + + @Override + public int idsSize() { + return this.id == null ? 0 : 1; + } + + @Override + public Set ids() { + return this.id == null ? ImmutableSet.of() : + ImmutableSet.of(this.id); + } + + @Override + public void resetIds() { + this.id = null; + } + + @Override + public IdQuery query(Id id) { + E.checkArgumentNotNull(id, "Query id can't be null"); + this.id = id; + return this; + } + + @Override + public boolean test(BaseElement element) { + if (this.id == null) { + return true; + } + return this.id.equals(element.id()); + } + + @Override + public IdQuery copy() { + OneIdQuery query = (OneIdQuery) super.copy(); + assert this.id.equals(query.id); + return query; + } + } } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/IdRangeQuery.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/IdRangeQuery.java similarity index 94% rename from hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/IdRangeQuery.java rename to hugegraph-struct/src/main/java/org/apache/hugegraph/query/IdRangeQuery.java index 781dc72d08..d276d8bc54 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/IdRangeQuery.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/IdRangeQuery.java @@ -15,10 +15,10 @@ * limitations under the License. */ -package org.apache.hugegraph.backend.query; +package org.apache.hugegraph.query; -import org.apache.hugegraph.backend.id.Id; -import org.apache.hugegraph.structure.HugeElement; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.structure.BaseElement; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.util.Bytes; import org.apache.hugegraph.util.E; @@ -82,7 +82,7 @@ public boolean empty() { } @Override - public boolean test(HugeElement element) { + public boolean test(BaseElement element) { int cmp1 = Bytes.compare(element.id().asBytes(), this.start.asBytes()); int cmp2 = Bytes.compare(element.id().asBytes(), this.end.asBytes()); return (this.inclusiveStart ? cmp1 >= 0 : cmp1 > 0) && diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/query/Query.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/Query.java index 2151cd6d0b..3cf97d4a14 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/query/Query.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/Query.java @@ -81,8 +81,7 @@ public class Query implements Cloneable { private List selects = InsertionOrderUtil.newList(); - @Deprecated - private transient Aggregate aggregate; + private Aggregate aggregate; private Query originQuery; @@ -97,10 +96,6 @@ public Query() { } - private static final ThreadLocal capacityContext = new ThreadLocal<>(); - - private static int indexStringValueLength = 20; - public Query(HugeType resultType) { this(resultType, null); } @@ -271,12 +266,12 @@ public Set skipOffsetIfNeeded(Set elems) { if (fromIndex < 0L) { // Skipping offset is overhead, no need to skip fromIndex = 0L; - } else if (fromIndex > 0L) { + } + // An index holder yields ids in batches, only count this batch's ids + fromIndex = Math.min(fromIndex, elems.size()); + if (fromIndex > 0L) { this.goOffset(fromIndex); } - E.checkArgument(fromIndex <= Integer.MAX_VALUE, - "Offset must be <= 0x7fffffff, but got '%s'", - fromIndex); if (fromIndex >= elems.size()) { return ImmutableSet.of(); @@ -447,21 +442,21 @@ public void checkCapacity(long count) throws LimitExceedException { } } - public Aggregate aggregate() { + public Aggregate aggregate() { return this.aggregate; } - public Aggregate aggregateNotNull() { + public Aggregate aggregateNotNull() { E.checkArgument(this.aggregate != null, "The aggregate must be set for number query"); return this.aggregate; } - public void aggregate(AggregateFuncDefine func, String property) { - this.aggregate = new Aggregate(func, property); + public void aggregate(AggregateFuncDefine func, String property) { + this.aggregate = new Aggregate<>(func, property); } - public void aggregate(Aggregate aggregate) { + public void aggregate(Aggregate aggregate) { this.aggregate = aggregate; } @@ -569,7 +564,6 @@ public int hashCode() { Objects.hashCode(this.page) ^ this.ids().hashCode() ^ this.conditions().hashCode() ^ - this.selects().hashCode() ^ Boolean.hashCode(this.withProperties); if (this.resultType == null) { return hash; @@ -665,16 +659,9 @@ public boolean isTaskQuery() { return false; } - public static int getIndexStringValueLength() { - return indexStringValueLength; - } - public static void setIndexStringValueLength(int indexStringValueLengthTmp) { - if (indexStringValueLengthTmp <= 1) { - indexStringValueLengthTmp = 20; - } - indexStringValueLength = indexStringValueLengthTmp; - } + + public void select(Id id) { if (!this.selects.contains(id)) { diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/query/serializer/AggregateAdapter.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/serializer/AggregateAdapter.java new file mode 100644 index 0000000000..c2fd2196a0 --- /dev/null +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/serializer/AggregateAdapter.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package org.apache.hugegraph.query.serializer; + +import java.lang.reflect.Type; +import java.util.Locale; + +import org.apache.hugegraph.query.Aggregate; +import org.apache.hugegraph.query.Aggregate.AggregateFunc; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; + +/** Preserves the original query aggregate descriptor without Java class names. */ +public final class AggregateAdapter implements JsonSerializer>, + JsonDeserializer> { + + @Override + public JsonElement serialize(Aggregate aggregate, Type type, + JsonSerializationContext context) { + JsonObject result = new JsonObject(); + // Both the shared enum and external strategies expose their function name. + // Only names supported by the original query protocol may cross the wire. + AggregateFunc func = function(aggregate.func().string().toUpperCase(Locale.ROOT)); + result.addProperty("func", func.name()); + if (aggregate.column() != null) { + result.addProperty("column", aggregate.column()); + } + return result; + } + + @Override + public Aggregate deserialize(JsonElement json, Type type, + JsonDeserializationContext context) { + JsonObject aggregate = json.getAsJsonObject(); + AggregateFunc func = function(aggregate.get("func").getAsString()); + JsonElement column = aggregate.get("column"); + return new Aggregate<>(func, column == null || column.isJsonNull() ? null : + column.getAsString()); + } + + private static AggregateFunc function(String name) { + try { + return AggregateFunc.valueOf(name); + } catch (IllegalArgumentException e) { + throw new JsonParseException("Unsupported aggregate function: " + name, e); + } + } +} diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/query/serializer/QueryAdapter.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/serializer/QueryAdapter.java index e9975f57cd..888549effd 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/query/serializer/QueryAdapter.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/serializer/QueryAdapter.java @@ -25,6 +25,7 @@ import org.apache.hugegraph.query.Condition; import org.apache.hugegraph.type.define.Directions; +import org.apache.hugegraph.util.LegacyClassNames; import com.google.common.collect.ImmutableMap; import com.google.gson.JsonDeserializationContext; @@ -35,6 +36,7 @@ import com.google.gson.JsonSerializationContext; import com.google.gson.reflect.TypeToken; +// Historical query values use Java class names; readers retain their legacy mappings. public class QueryAdapter extends AbstractSerializerAdapter { static ImmutableMap cls = @@ -55,6 +57,13 @@ static boolean isPrimitive(Class clz) { } } + // Old server queries include Java class names in relation values. + // Resolve only the migrated names here; no legacy implementation is needed. + private static Class valueClass(String name) throws ClassNotFoundException { + Class mapped = LegacyClassNames.lookup(name); + return mapped != null ? mapped : Class.forName(name); + } + @Override public Map validType() { return cls; @@ -72,7 +81,7 @@ public Condition deserialize(JsonElement json, Type typeOfT, JsonDeserialization if (valueElement.isJsonObject()) { String cls = valueElement.getAsJsonObject().get("cls").getAsString(); try { - Class actualClass = Class.forName(cls); + Class actualClass = valueClass(cls); Object obj = context.deserialize(valueElement, actualClass); ((Condition.Relation) condition).value(obj); } catch (ClassNotFoundException e) { @@ -82,7 +91,7 @@ public Condition deserialize(JsonElement json, Type typeOfT, JsonDeserialization if (valueElement.isJsonArray()) { String cls = elElement.getAsJsonObject().get("valuecls").getAsString(); try { - Class actualClass = Class.forName(cls); + Class actualClass = valueClass(cls); Type type = TypeToken.getParameterized(ArrayList.class, actualClass) .getType(); Object value = context.deserialize(valueElement, type); @@ -93,7 +102,7 @@ public Condition deserialize(JsonElement json, Type typeOfT, JsonDeserialization } else { String cls = elElement.getAsJsonObject().get("valuecls").getAsString(); try { - Class actualClass = Class.forName(cls); + Class actualClass = valueClass(cls); Object obj = context.deserialize(valueElement, actualClass); ((Condition.Relation) condition).value(obj); } catch (ClassNotFoundException e) { diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/serializer/BinaryElementSerializer.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/serializer/BinaryElementSerializer.java index 03229b42f7..82f2f8952e 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/serializer/BinaryElementSerializer.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/serializer/BinaryElementSerializer.java @@ -24,18 +24,19 @@ import java.util.Arrays; import java.util.Base64; import java.util.Collection; -import java.util.Map; +import java.util.function.BiConsumer; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.NotImplementedException; import org.apache.hugegraph.HugeGraphSupplier; import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.backend.BinaryId; -import org.apache.hugegraph.exception.HugeException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.id.EdgeId; import org.apache.hugegraph.id.Id; import org.apache.hugegraph.id.IdGenerator; import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.struct.schema.SchemaElement; import org.apache.hugegraph.struct.schema.VertexLabel; @@ -43,10 +44,14 @@ import org.apache.hugegraph.structure.BaseElement; import org.apache.hugegraph.structure.BaseProperty; import org.apache.hugegraph.structure.BaseVertex; +import org.apache.hugegraph.structure.BaseVertex.TypeContext; import org.apache.hugegraph.structure.Index; +import org.apache.hugegraph.serializer.BytesBuffer.IndexColumnName; +import org.apache.hugegraph.serializer.BytesBuffer.IndexExpiryLayout; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Cardinality; import org.apache.hugegraph.type.define.EdgeLabelType; +import org.apache.hugegraph.type.define.Directions; import org.apache.hugegraph.util.Bytes; import org.apache.hugegraph.util.E; import org.apache.hugegraph.util.Log; @@ -107,32 +112,46 @@ public static Id ownerId(Index index) { protected void parseProperty(HugeGraphSupplier graph, Id pkeyId, - BytesBuffer buffer, - BaseElement owner) { - PropertyKey pkey = graph != null ? - graph.propertyKey(pkeyId) : - new PropertyKey(graph, pkeyId, ""); - // Parse value - Object value = buffer.readProperty(pkey); - // Set properties of vertex/edge - if (pkey.cardinality() == Cardinality.SINGLE) { - owner.addProperty(pkey, value); - } else { - if (!(value instanceof Collection)) { - throw new HugeException( - "Invalid value of non-single property: %s", value); - } - owner.addProperty(pkey, value); + BytesBuffer buffer, BaseElement owner) { + this.parseProperty(graph, pkeyId, buffer, true, owner::addProperty); + } + + public void parseSchemaProperty(HugeGraphSupplier graph, Id pkeyId, + BytesBuffer buffer, + BiConsumer propertySink) { + E.checkArgumentNotNull(graph, "Schema property decoding requires a schema supplier"); + this.parseProperty(graph, pkeyId, buffer, false, propertySink); + } + + private void parseProperty(HugeGraphSupplier graph, Id pkeyId, + BytesBuffer buffer, boolean tagged, + BiConsumer propertySink) { + PropertyKey pkey = graph != null ? graph.propertyKey(pkeyId) : + new PropertyKey(null, pkeyId, ""); + Object value = tagged ? buffer.readProperty(pkey) : buffer.readSchemaProperty(pkey); + if (pkey.cardinality() != Cardinality.SINGLE && !(value instanceof Collection)) { + throw new BackendException("Invalid value of non-single property: %s", value); } + propertySink.accept(pkey, value); } public void parseProperties(HugeGraphSupplier graph, BytesBuffer buffer, BaseElement owner) { + this.parseProperties(graph, buffer, true, owner::addProperty); + } + + public void parseSchemaProperties(HugeGraphSupplier graph, BytesBuffer buffer, + BiConsumer propertySink) { + E.checkArgumentNotNull(graph, "Schema property decoding requires a schema supplier"); + this.parseProperties(graph, buffer, false, propertySink); + } + + private void parseProperties(HugeGraphSupplier graph, BytesBuffer buffer, + boolean tagged, BiConsumer propertySink) { int size = buffer.readVInt(); assert size >= 0; for (int i = 0; i < size; i++) { - Id pkeyId = IdGenerator.of(buffer.readVInt()); - this.parseProperty(graph, pkeyId, buffer, owner); + this.parsePropertyRecord(graph, buffer, tagged, propertySink); } } @@ -145,74 +164,131 @@ public void parseProperties(HugeGraphSupplier graph, BytesBuffer buffer, */ public BaseVertex parseVertex(HugeGraphSupplier graph, BackendColumn vertexCol, BaseVertex vertex) { + return this.parseVertex(graph, vertexCol, vertex, true, TypeContext.STORAGE); + } + + /** Decode a persisted Server row using schema-supplied property metadata. */ + public BaseVertex parseSchemaVertex(HugeGraphSupplier graph, BackendColumn vertexCol, + BaseVertex vertex) { + return this.parseSchemaVertex(graph, vertexCol, vertex, TypeContext.STORAGE); + } + + public BaseVertex parseSchemaVertex(HugeGraphSupplier graph, BackendColumn vertexCol, + BaseVertex vertex, TypeContext typeContext) { + E.checkArgumentNotNull(graph, "Schema vertex decoding requires a schema supplier"); + return this.parseVertex(graph, vertexCol, vertex, false, typeContext); + } + + private BaseVertex parseVertex(HugeGraphSupplier graph, BackendColumn vertexCol, + BaseVertex vertex, boolean tagged, TypeContext typeContext) { if (vertex == null) { BinaryId binaryId = BytesBuffer.wrap(vertexCol.name).parseId(HugeType.VERTEX); - vertex = new BaseVertex(binaryId.origin(), VertexLabel.NONE); + vertex = new BaseVertex(binaryId.origin(), VertexLabel.NONE, typeContext); } if (ArrayUtils.isEmpty(vertexCol.value)) { // No need to parse vertex properties return vertex; } - BytesBuffer buffer = BytesBuffer.wrap(vertexCol.value); - Id labelId = buffer.readId(); - // Parse vertex label - if (graph != null) { - VertexLabel label = graph.vertexLabelOrNone(labelId); - vertex.correctVertexLabel(label); - } else { - VertexLabel label = new VertexLabel(null, labelId, UNDEF); - vertex.correctVertexLabel(label); - } - // Parse properties - this.parseProperties(graph, buffer, vertex); - - // Parse vertex expired time if needed - if (buffer.remaining() > 0 /*edge.hasTtl()*/) { - this.parseExpiredTime(buffer, vertex); - } + this.parseVertexValue(graph, vertexCol.value, vertex, tagged, vertex::addProperty); return vertex; } + public void parseSchemaVertexValue(HugeGraphSupplier graph, byte[] value, + BaseVertex vertex, + BiConsumer propertySink) { + E.checkArgumentNotNull(graph, "Schema vertex decoding requires a schema supplier"); + this.parseVertexValue(graph, value, vertex, false, propertySink); + } + + private void parseVertexValue(HugeGraphSupplier graph, byte[] value, BaseVertex vertex, + boolean tagged, BiConsumer propertySink) { + BytesBuffer buffer = BytesBuffer.wrap(value); + Id labelId = buffer.readId(); + VertexLabel label = graph != null ? graph.vertexLabelOrNone(labelId) : + new VertexLabel(null, labelId, UNDEF); + vertex.correctVertexLabel(label); + this.parseElementValue(graph, buffer, vertex, tagged, propertySink); + } + /** * Reverse sequence the vertex kv data into vertices of type BaseVertex * * @param olapVertexCol It must be a column of vertex data - * @param vertex When vertex==null, it is used for operator sinking to reverse sequence the col data into olapBaseVertex. - * vertex! When =null, add the col information to olapBaseVertex + * @param vertex The destination vertex; null creates one from the OLAP key. */ public BaseVertex parseVertexOlap(HugeGraphSupplier graph, BackendColumn olapVertexCol, BaseVertex vertex) { + return this.parseVertexOlap(graph, olapVertexCol, vertex, true, TypeContext.STORAGE); + } + + public BaseVertex parseSchemaVertexOlap(HugeGraphSupplier graph, + BackendColumn olapVertexCol, BaseVertex vertex) { + return this.parseSchemaVertexOlap(graph, olapVertexCol, vertex, TypeContext.STORAGE); + } + + public BaseVertex parseSchemaVertexOlap(HugeGraphSupplier graph, + BackendColumn olapVertexCol, BaseVertex vertex, + TypeContext typeContext) { + E.checkArgumentNotNull(graph, "Schema OLAP decoding requires a schema supplier"); + return this.parseVertexOlap(graph, olapVertexCol, vertex, false, typeContext); + } + + private BaseVertex parseVertexOlap(HugeGraphSupplier graph, BackendColumn olapVertexCol, + BaseVertex vertex, boolean tagged, TypeContext typeContext) { if (vertex == null) { BytesBuffer idBuffer = BytesBuffer.wrap(olapVertexCol.name); - // read olap property id - idBuffer.readId(); - // read vertex id which olap property belongs to + // Transient Store OLAP keys include the property ID; Server's + // persisted OLAP column name contains only the vertex ID. + if (tagged) { + idBuffer.readId(); + } Id vertexId = idBuffer.readId(); - vertex = new BaseVertex(vertexId, VertexLabel.NONE); + vertex = new BaseVertex(vertexId, VertexLabel.NONE, typeContext); } - BytesBuffer buffer = BytesBuffer.wrap(olapVertexCol.value); - Id pkeyId = IdGenerator.of(buffer.readVInt()); - this.parseProperty(graph, pkeyId, buffer, vertex); + this.parsePropertyRecord(graph, BytesBuffer.wrap(olapVertexCol.value), + tagged, vertex::addProperty); return vertex; } + public void parseSchemaPropertyRecord(HugeGraphSupplier graph, BytesBuffer buffer, + BiConsumer propertySink) { + E.checkArgumentNotNull(graph, "Schema property decoding requires a schema supplier"); + this.parsePropertyRecord(graph, buffer, false, propertySink); + } + + private void parsePropertyRecord(HugeGraphSupplier graph, BytesBuffer buffer, + boolean tagged, BiConsumer propertySink) { + Id pkeyId = IdGenerator.of(buffer.readVInt()); + this.parseProperty(graph, pkeyId, buffer, tagged, propertySink); + } + /** - * @param cols Deserializing a complete vertex may require multiple cols - * The first col represents the common vertex information in the g+v table, and each subsequent col represents the olap vertices stored in the olap table + * @param cols The first column contains vertex data; subsequent columns contain OLAP properties. */ public BaseVertex parseVertexFromCols(HugeGraphSupplier graph, BackendColumn... cols) { + return this.parseVertexFromCols(graph, true, cols); + } + + public BaseVertex parseSchemaVertexFromCols(HugeGraphSupplier graph, + BackendColumn... cols) { + E.checkArgumentNotNull(graph, "Schema vertex decoding requires a schema supplier"); + return this.parseVertexFromCols(graph, false, cols); + } + + private BaseVertex parseVertexFromCols(HugeGraphSupplier graph, boolean tagged, + BackendColumn... cols) { assert cols.length > 0; BaseVertex vertex = null; for (int index = 0; index < cols.length; index++) { BackendColumn col = cols[index]; if (index == 0) { - vertex = this.parseVertex(graph, col, vertex); + vertex = this.parseVertex(graph, col, vertex, tagged, TypeContext.STORAGE); } else { - this.parseVertexOlap(graph, col, vertex); + this.parseVertexOlap(graph, col, vertex, tagged, TypeContext.STORAGE); } } return vertex; @@ -235,48 +311,38 @@ public Id parseLabelFromCol(BackendColumn col, boolean isVertex) { } public BaseEdge parseEdge(HugeGraphSupplier graph, BackendColumn edgeCol, - BaseVertex ownerVertex, - boolean withEdgeProperties) { - // owner-vertex + dir + edge-label.id() + subLabel.id() + - // + sort-values + other-vertex - - BytesBuffer buffer = BytesBuffer.wrap(edgeCol.name); - // Consume owner-vertex id - Id id = buffer.readId(); - if (ownerVertex == null) { - ownerVertex = new BaseVertex(id, VertexLabel.NONE); - } - - E.checkState(buffer.remaining() > 0, "Missing column type"); + BaseVertex ownerVertex, boolean withEdgeProperties) { + return this.parseEdge(graph, edgeCol, ownerVertex, withEdgeProperties, + true, TypeContext.STORAGE); + } - byte type = buffer.read(); - if (type == HugeType.EDGE_IN.code() || - type == HugeType.EDGE_OUT.code()) { - E.checkState(true, - "Invalid column(%s) with unknown type(%s): 0x%s", - id, type & 0xff, Bytes.toHex(edgeCol.name)); - } + public BaseEdge parseSchemaEdge(HugeGraphSupplier graph, BackendColumn edgeCol, + BaseVertex ownerVertex, boolean withEdgeProperties) { + return this.parseSchemaEdge(graph, edgeCol, ownerVertex, withEdgeProperties, + TypeContext.STORAGE); + } - Id labelId = buffer.readId(); - Id subLabelId = buffer.readId(); - String sortValues = buffer.readStringWithEnding(); - Id otherVertexId = buffer.readId(); - boolean direction = EdgeId.isOutDirectionFromCode(type); - BaseEdge edge; - EdgeLabel edgeLabel; - if (graph == null) { /* when calculation sinking */ - edgeLabel = new EdgeLabel(null, subLabelId, UNDEF); - // If not equal here, need to add fatherId for correct operator sinking - if (subLabelId != labelId) { - edgeLabel.edgeLabelType(EdgeLabelType.SUB); - edgeLabel.fatherId(labelId); - } + public BaseEdge parseSchemaEdge(HugeGraphSupplier graph, BackendColumn edgeCol, + BaseVertex ownerVertex, boolean withEdgeProperties, + TypeContext typeContext) { + E.checkArgumentNotNull(graph, "Schema edge decoding requires a schema supplier"); + return this.parseEdge(graph, edgeCol, ownerVertex, withEdgeProperties, + false, typeContext); + } - } else { - edgeLabel = graph.edgeLabelOrNone(subLabelId); + private BaseEdge parseEdge(HugeGraphSupplier graph, BackendColumn edgeCol, + BaseVertex ownerVertex, boolean withEdgeProperties, + boolean tagged, TypeContext typeContext) { + EdgeId id = BytesBuffer.wrap(edgeCol.name).readEdgeId(true, null); + if (ownerVertex == null) { + ownerVertex = new BaseVertex(id.ownerVertexId(), VertexLabel.NONE, typeContext); } + boolean direction = id.direction() == Directions.OUT; + EdgeLabel edgeLabel = this.edgeLabel(graph, id); + BaseEdge edge; edge = BaseEdge.constructEdge(graph, ownerVertex, direction, - edgeLabel, sortValues, otherVertexId); + edgeLabel, id.sortValues(), id.otherVertexId()); + edge.otherVertex().typeContext(typeContext); if (!withEdgeProperties /*&& !edge.hasTtl()*/) { // only skip properties for edge without ttl @@ -289,19 +355,42 @@ public BaseEdge parseEdge(HugeGraphSupplier graph, BackendColumn edgeCol, return edge; } - // Parse edge-id + edge-properties - buffer = BytesBuffer.wrap(edgeCol.value); + this.parseElementValue(graph, BytesBuffer.wrap(edgeCol.value), edge, + tagged, edge::addProperty); + return edge; + } - // Parse edge properties - this.parseProperties(graph, buffer, edge); + public EdgeLabel edgeLabel(HugeGraphSupplier graph, EdgeId id) { + return this.edgeLabel(graph, id, graph); + } - /* Skip TTL parsing process first - * Can't determine if edge has TTL through edge, need to judge by bytebuffer length */ -// // Parse edge expired time if needed - if (buffer.remaining() > 0 /*edge.hasTtl()*/) { - this.parseExpiredTime(buffer, edge); + public EdgeLabel edgeLabel(HugeGraphSupplier lookupGraph, EdgeId id, + HugeGraphSupplier schemaGraph) { + if (lookupGraph != null) { + return lookupGraph.edgeLabelOrNone(id.subLabelId()); + } + EdgeLabel label = new EdgeLabel(schemaGraph, id.subLabelId(), UNDEF); + if (id.subLabelId() != id.edgeLabelId()) { + label.edgeLabelType(EdgeLabelType.SUB); + label.fatherId(id.edgeLabelId()); + } + return label; + } + + public void parseSchemaEdgeValue(HugeGraphSupplier graph, byte[] value, + BaseEdge edge, + BiConsumer propertySink) { + E.checkArgumentNotNull(graph, "Schema edge decoding requires a schema supplier"); + this.parseElementValue(graph, BytesBuffer.wrap(value), edge, false, propertySink); + } + + private void parseElementValue(HugeGraphSupplier graph, BytesBuffer buffer, + BaseElement element, boolean tagged, + BiConsumer propertySink) { + this.parseProperties(graph, buffer, tagged, propertySink); + if (tagged ? buffer.remaining() > 0 : element.hasTtl()) { + this.parseExpiredTime(buffer, element); } - return edge; } /** @@ -310,19 +399,45 @@ public BaseEdge parseEdge(HugeGraphSupplier graph, BackendColumn edgeCol, */ public Index parseIndex(HugeGraphSupplier graph, BackendColumn indexCol, Index index) { - HugeType indexType = parseIndexType(indexCol); + return this.parseIndex(graph, indexCol, index, false); + } + + /** Decode Server index rows, whose optional expiry is in the column name. */ + public Index parseSchemaIndex(HugeGraphSupplier graph, BackendColumn indexCol) { + E.checkArgumentNotNull(graph, "Schema index decoding requires a schema supplier"); + return this.parseIndex(graph, indexCol, null, true); + } - BytesBuffer buffer = BytesBuffer.wrap(indexCol.name); - BinaryId indexId = buffer.readIndexId(indexType); - Id elemId = buffer.readId(); + private Index parseIndex(HugeGraphSupplier graph, BackendColumn indexCol, + Index index, boolean schema) { + HugeType indexType = parseIndexType(indexCol); + IndexColumnName name = BytesBuffer.wrap(indexCol.name).readIndexColumnName( + indexType, true, schema ? IndexExpiryLayout.OPTIONAL : IndexExpiryLayout.NONE); if (index == null) { - index = Index.parseIndexId(graph, indexType, indexId.asBytes()); + index = Index.parseIndexId(graph, indexType, name.indexId().asBytes()); } - long expiredTime = 0L; - - if (indexCol.value.length > 0) { + long expiredTime = name.expiredTime(); + + if (schema) { + boolean hasTtl = !index.indexLabel().system() && + index.indexLabel().baseLabel().ttl() > 0; + Long legacyExpiredTime = null; + if (!name.hasExpiredTime()) { + // Legacy Store writers kept TTL in an exact value envelope. + // Only use it after the index/element name fields end, never + // search arbitrary field-value bytes for a delimiter. + legacyExpiredTime = this.legacyStoreIndexExpiredTime(indexCol.value); + E.checkState(!hasTtl || legacyExpiredTime != null, + "Missing TTL in schema index column"); + expiredTime = legacyExpiredTime == null ? 0L : legacyExpiredTime; + } + if (legacyExpiredTime == null && indexType.isStringIndex() && + !ArrayUtils.isEmpty(indexCol.value)) { + index.fieldValues(StringEncoding.decode(indexCol.value)); + } + } else if (indexCol.value.length > 0) { // Get delimiter address int delimiterIndex = @@ -355,10 +470,33 @@ public Index parseIndex(HugeGraphSupplier graph, BackendColumn indexCol, } } - index.elementIds(elemId, expiredTime); + index.elementIds(name.elementId(), expiredTime); return index; } + /** Decode the existing Store label envelope only at a complete label-index key boundary. */ + public Long storedLabelIndexExpiredTime(HugeType type, boolean atNameEnd, byte[] value) { + return type.isLabelIndex() && atNameEnd ? this.legacyStoreIndexExpiredTime(value) : null; + } + + private Long legacyStoreIndexExpiredTime(byte[] value) { + // A Store TTL writer emits exactly 0x00 + Base64(long), with no fields. + if (value == null || value.length != 13 || value[0] != BytesBuffer.STRING_ENDING_BYTE) { + return null; + } + try { + byte[] expiry = Base64.getDecoder().decode(Arrays.copyOfRange(value, 1, value.length)); + if (expiry.length != Longs.BYTES || + !Arrays.equals(Base64.getEncoder().encode(expiry), + Arrays.copyOfRange(value, 1, value.length))) { + return null; + } + return Longs.fromByteArray(expiry); + } catch (IllegalArgumentException ignored) { + return null; + } + } + public BackendColumn parseIndex(BackendColumn indexCol) { // Self-parsing index throw new NotImplementedException( @@ -373,21 +511,19 @@ public BackendColumn writeVertex(BaseVertex vertex) { BytesBuffer bufferName = BytesBuffer.allocate(vertex.id().length()); bufferName.writeId(vertex.id()); - int propsCount = vertex.getProperties().size(); - BytesBuffer buffer = BytesBuffer.allocate(8 + 16 * propsCount); - - // Write vertex label - buffer.writeId(vertex.schemaLabel().id()); - - // Write all properties of the vertex - this.formatProperties(vertex.getProperties().values(), buffer); + return BackendColumn.of(bufferName.bytes(), this.formatVertexValue(vertex, true)); + } - // Write vertex expired time if needed - if (vertex.hasTtl()) { - this.formatExpiredTime(vertex.expiredTime(), buffer); - } + public byte[] formatSchemaVertexValue(BaseVertex vertex) { + return this.formatVertexValue(vertex, false); + } - return BackendColumn.of(bufferName.bytes(), buffer.bytes()); + private byte[] formatVertexValue(BaseVertex vertex, boolean tagged) { + BytesBuffer buffer = BytesBuffer.allocate(8 + 16 * vertex.sizeOfProperties()); + buffer.writeId(vertex.schemaLabel().id()); + this.formatElementProperties(vertex, buffer, tagged); + this.formatElementExpiredTime(vertex, buffer); + return buffer.bytes(); } public BackendColumn writeOlapVertex(BaseVertex vertex) { @@ -396,18 +532,9 @@ public BackendColumn writeOlapVertex(BaseVertex vertex) { BaseProperty baseProperty = vertex.getProperties().values() .iterator().next(); PropertyKey propertyKey = baseProperty.propertyKey(); - buffer.writeVInt(SchemaElement.schemaId(propertyKey.id())); - buffer.writeProperty(propertyKey.cardinality(), propertyKey.dataType(), - baseProperty.value()); - - // OLAP table merge, key is {property_key_id}{vertex_id} - BytesBuffer bufferName = - BytesBuffer.allocate(1 + propertyKey.id().length() + 1 + - vertex.id().length()); - bufferName.writeId(propertyKey.id()); - bufferName.writeId(vertex.id()).bytes(); + this.formatProperty(baseProperty, buffer, true); - return BackendColumn.of(bufferName.bytes(), buffer.bytes()); + return BackendColumn.of(OlapKey.format(propertyKey.id(), vertex.id()), buffer.bytes()); } public BackendColumn writeEdge(BaseEdge edge) { @@ -424,6 +551,49 @@ public BackendColumn writeIndex(Index index) { formatIndexValue(index)); } + /** Write Store-owned rows with stable keys and the existing storage label-expiry envelope. */ + public BackendColumn writeSchemaIndex(Index index) { + BackendColumn column = this.formatSchemaIndex( + index.type(), index.indexLabelId(), index.fieldValues(), index.elementId(), + true, index.hasTtl(), index.expiredTime()); + if (this.storageLabelHasTtl(index)) { + // Preserve label-index keys so Core append/remove addresses the same row. + column.value = this.formatIndexValue(index); + } + return column; + } + + public BackendColumn formatSchemaIndex(HugeType type, Id indexLabelId, Object fieldValues, + Id elementId, boolean withIdPrefix, + boolean hasTtl, long expiredTime) { + Id rawId = Index.formatIndexId(type, indexLabelId, fieldValues); + boolean hashed = !type.isNumericIndex() && indexIdLengthExceedLimit(rawId); + Id indexId = schemaIndexId(type, indexLabelId, fieldValues); + int capacity = 1 + elementId.length() + (withIdPrefix ? 1 + indexId.length() : 0); + BytesBuffer name = BytesBuffer.allocate(capacity); + if (withIdPrefix) { + name.writeIndexId(indexId, type); + } + name.writeId(elementId); + if (hasTtl) { + name.writeVLong(expiredTime); + } + byte[] value = hashed ? StringEncoding.encode(fieldValues.toString()) : BytesBuffer.BYTES_EMPTY; + return BackendColumn.of(name.bytes(), value); + } + + public static Id schemaIndexId(HugeType type, Id indexLabelId, Object fieldValues) { + Id id = Index.formatIndexId(type, indexLabelId, fieldValues); + if (!type.isNumericIndex() && indexIdLengthExceedLimit(id)) { + id = Index.formatIndexHashId(type, indexLabelId, fieldValues); + } + return id; + } + + public static boolean indexIdLengthExceedLimit(Id id) { + return id.asBytes().length > BytesBuffer.INDEX_HASH_ID_THRESHOLD; + } + private byte[] formatIndexName(Index index) { BytesBuffer buffer; Id elemId = index.elementId(); @@ -444,8 +614,13 @@ private byte[] formatIndexName(Index index) { * @return format * | empty(field-value) | 0x00 | base64(expiredtime) | */ + private boolean storageLabelHasTtl(Index index) { + return (index.indexLabel() == IndexLabel.label(HugeType.VERTEX) || + index.indexLabel() == IndexLabel.label(HugeType.EDGE)) && index.expiredTime() > 0; + } + private byte[] formatIndexValue(Index index) { - if (index.hasTtl()) { + if (this.storageLabelHasTtl(index) || index.hasTtl()) { BytesBuffer valueBuffer = BytesBuffer.allocate(14); valueBuffer.write(BytesBuffer.STRING_ENDING_BYTE); @@ -494,32 +669,64 @@ public byte[] formatEdgeName(BaseEdge edge) { } protected byte[] formatEdgeValue(BaseEdge edge) { - Map> properties = edge.getProperties(); - int propsCount = properties.size(); - BytesBuffer buffer = BytesBuffer.allocate(4 + 16 * propsCount); + return this.formatEdgeValue(edge, true); + } - // Write edge properties - this.formatProperties(properties.values(), buffer); + public byte[] formatSchemaEdgeValue(BaseEdge edge) { + return this.formatEdgeValue(edge, false); + } - // Write edge expired time if needed - if (edge.hasTtl()) { - this.formatExpiredTime(edge.expiredTime(), buffer); + private byte[] formatEdgeValue(BaseEdge edge, boolean tagged) { + BytesBuffer buffer = BytesBuffer.allocate(4 + 16 * edge.sizeOfProperties()); + this.formatElementProperties(edge, buffer, tagged); + this.formatElementExpiredTime(edge, buffer); + return buffer.bytes(); + } + + private void formatElementProperties(BaseElement element, BytesBuffer buffer, + boolean tagged) { + if (tagged) { + this.formatProperties(element.getProperties().values(), buffer); + } else { + this.formatSchemaProperties(element, buffer); } + } - return buffer.bytes(); + private void formatElementExpiredTime(BaseElement element, BytesBuffer buffer) { + if (element.hasTtl()) { + this.formatExpiredTime(element.expiredTime(), buffer); + } } public void formatProperties(Collection> props, BytesBuffer buffer) { - // Write properties size - buffer.writeVInt(props.size()); + this.formatProperties(props, props.size(), buffer, true); + } - // Write properties data + public void formatSchemaProperties(BaseElement owner, BytesBuffer buffer) { + this.formatProperties(owner.properties().values(), owner.sizeOfProperties(), buffer, false); + } + + private void formatProperties(Iterable> props, int size, + BytesBuffer buffer, boolean tagged) { + buffer.writeVInt(size); for (BaseProperty property : props) { - PropertyKey pkey = property.propertyKey(); - buffer.writeVInt(SchemaElement.schemaId(pkey.id())); - buffer.writeProperty(pkey.cardinality(), pkey.dataType(), - property.value()); + this.formatProperty(property, buffer, tagged); + } + } + + public void formatSchemaProperty(BaseProperty property, BytesBuffer buffer) { + this.formatProperty(property, buffer, false); + } + + private void formatProperty(BaseProperty property, BytesBuffer buffer, + boolean tagged) { + PropertyKey pkey = property.propertyKey(); + buffer.writeVInt(SchemaElement.schemaId(pkey.id())); + if (tagged) { + buffer.writeProperty(pkey, property.value()); + } else { + buffer.writeSchemaProperty(pkey, property.value()); } } @@ -527,7 +734,7 @@ public void formatExpiredTime(long expiredTime, BytesBuffer buffer) { buffer.writeVLong(expiredTime); } - protected void parseExpiredTime(BytesBuffer buffer, BaseElement element) { + public void parseExpiredTime(BytesBuffer buffer, BaseElement element) { element.expiredTime(buffer.readVLong()); } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/serializer/BytesBuffer.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/serializer/BytesBuffer.java index 4ec6aad194..050ad75031 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/serializer/BytesBuffer.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/serializer/BytesBuffer.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.serializer; @@ -28,11 +26,11 @@ import java.util.LinkedHashSet; import java.util.UUID; -import org.apache.hugegraph.backend.BinaryId; import org.apache.hugegraph.id.EdgeId; import org.apache.hugegraph.id.Id; import org.apache.hugegraph.id.Id.IdType; import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.backend.BinaryId; import org.apache.hugegraph.struct.schema.PropertyKey; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Cardinality; @@ -41,6 +39,7 @@ import org.apache.hugegraph.util.Blob; import org.apache.hugegraph.util.Bytes; import org.apache.hugegraph.util.E; +import org.apache.hugegraph.util.KryoUtil; import org.apache.hugegraph.util.StringEncoding; /** @@ -55,31 +54,44 @@ public class BytesBuffer extends OutputStream { public static final int CHAR_LEN = Character.BYTES; public static final int FLOAT_LEN = Float.BYTES; public static final int DOUBLE_LEN = Double.BYTES; - public static final int BLOB_LEN = 4; + public static final int BYTES_LEN = 4; + public static final int BLOB_LEN = 5; public static final int UINT8_MAX = ((byte) -1) & 0xff; public static final int UINT16_MAX = ((short) -1) & 0xffff; public static final long UINT32_MAX = (-1) & 0xffffffffL; - public static final long WRITE_BYTES_MAX_LENGTH = 10 * Bytes.MB; + // TODO: support user-defined configuration // NOTE: +1 to let code 0 represent length 1 - public static final int ID_LEN_MAX = 0x7fff + 1; + public static final int ID_LEN_MAX = 0x3fff + 1; // 16KB + public static final int EID_LEN_MAX = 64 * 1024; public static final int BIG_ID_LEN_MAX = 0xfffff + 1; public static final byte STRING_ENDING_BYTE = (byte) 0x00; public static final byte STRING_ENDING_BYTE_FF = (byte) 0xff; + + // TODO: support user-defined configuration + public static final long BYTES_LEN_MAX = 10 * Bytes.MB; + public static final long WRITE_BYTES_MAX_LENGTH = BYTES_LEN_MAX; public static final int STRING_LEN_MAX = UINT16_MAX; - public static final long BLOB_LEN_MAX = Bytes.GB; + public static final long BLOB_LEN_MAX = 1 * Bytes.GB; + + public static final int MAX_PROPERTIES = BytesBuffer.UINT16_MAX; // The value must be in range [8, ID_LEN_MAX] public static final int INDEX_HASH_ID_THRESHOLD = 32; public static final int DEFAULT_CAPACITY = 64; public static final int MAX_BUFFER_CAPACITY = 128 * 1024 * 1024; // 128M + public static final int MAX_BUFFER_CAPACITY_UPPER_BOUND = (int) Bytes.GB; public static final int BUF_EDGE_ID = 128; public static final int BUF_PROPERTY = 64; + public static final byte[] BYTES_EMPTY = new byte[0]; + + private static volatile Integer maxBufferCapacity; + private ByteBuffer buffer; private final boolean resize; @@ -88,9 +100,12 @@ public BytesBuffer() { } public BytesBuffer(int capacity) { - E.checkArgument(capacity <= MAX_BUFFER_CAPACITY, - "Capacity exceeds max buffer capacity: %s", - MAX_BUFFER_CAPACITY); + int maxCapacity = maxBufferCapacity(); + if (capacity > maxCapacity) { + E.checkArgument(false, + "Capacity %s exceeds max buffer capacity: %s", + capacity, maxCapacity); + } this.buffer = ByteBuffer.allocate(capacity); this.resize = true; } @@ -117,6 +132,43 @@ public static BytesBuffer wrap(byte[] array, int offset, int length) { return new BytesBuffer(ByteBuffer.wrap(array, offset, length)); } + public static int maxBufferCapacity() { + Integer capacity = maxBufferCapacity; + return capacity != null ? capacity : MAX_BUFFER_CAPACITY; + } + + public static synchronized void initMaxBufferCapacity(int capacity) { + initMaxBufferCapacity(capacity, true); + } + + public static synchronized void initMaxBufferCapacity(int capacity, + boolean explicit) { + E.checkArgument(capacity >= DEFAULT_CAPACITY && + capacity <= MAX_BUFFER_CAPACITY_UPPER_BOUND, + "Max buffer capacity must be in range [%s, %s], " + + "but got %s", + DEFAULT_CAPACITY, MAX_BUFFER_CAPACITY_UPPER_BOUND, + capacity); + + if (!explicit) { + return; + } + + if (maxBufferCapacity == null) { + maxBufferCapacity = capacity; + return; + } + + if (maxBufferCapacity == capacity) { + return; + } + + throw new IllegalArgumentException(String.format( + "The process-wide serializer buffer max capacity has been " + + "initialized to %s, but got conflicting value %s", + maxBufferCapacity, capacity)); + } + public ByteBuffer asByteBuffer() { return this.buffer; } @@ -160,18 +212,26 @@ public int remaining() { private void require(int size) { // Does need to resize? - if (this.buffer.limit() - this.buffer.position() >= size) { + if (this.buffer.remaining() >= size) { return; } // Can't resize for wrapped buffer since will change the origin ref - E.checkState(this.resize, "Can't resize for wrapped buffer"); + if (!this.resize) { + E.checkState(false, "Can't resize for wrapped buffer"); + } + + int maxCapacity = maxBufferCapacity(); + long requiredCapacity = (long) this.buffer.position() + size; + if (requiredCapacity > maxCapacity) { + E.checkArgument(false, + "Capacity %s exceeds max buffer capacity: %s", + requiredCapacity, maxCapacity); + } // Extra capacity as buffer - int newcapacity = size + this.buffer.limit() + DEFAULT_CAPACITY; - E.checkArgument(newcapacity <= MAX_BUFFER_CAPACITY, - "Capacity exceeds max buffer capacity: %s", - MAX_BUFFER_CAPACITY); - ByteBuffer newBuffer = ByteBuffer.allocate(newcapacity); + long newCapacity = Math.min(requiredCapacity + DEFAULT_CAPACITY, + maxCapacity); + ByteBuffer newBuffer = ByteBuffer.allocate((int) newCapacity); this.buffer.flip(); newBuffer.put(this.buffer); this.buffer = newBuffer; @@ -248,7 +308,7 @@ public byte peek() { } public byte peekLast() { - return this.buffer.get(this.buffer.capacity() - 1); + return this.buffer.get(this.buffer.limit() - 1); } public byte read() { @@ -261,12 +321,6 @@ public byte[] read(int length) { return bytes; } - public byte[] readToEnd() { - byte[] bytes = new byte[this.remaining()]; - this.buffer.get(bytes); - return bytes; - } - public boolean readBoolean() { return this.buffer.get() != 0; } @@ -296,12 +350,12 @@ public double readDouble() { } public BytesBuffer writeBytes(byte[] bytes) { - // Original limit as above, consider this limit may be due to performance considerations when multiple storage backends are used. - // The above limit will cause errors when writing value to property exceeds the limit. So adjust size to 5M - E.checkArgument(bytes.length <= WRITE_BYTES_MAX_LENGTH, - "The max length of bytes is %s, but got %s", - WRITE_BYTES_MAX_LENGTH, bytes.length); - require(SHORT_LEN + bytes.length); + if (bytes.length > BYTES_LEN_MAX) { + E.checkArgument(false, + "The max length of bytes is %s, but got %s", + BYTES_LEN_MAX, bytes.length); + } + require(BYTES_LEN + bytes.length); this.writeVInt(bytes.length); this.write(bytes); return this; @@ -310,14 +364,15 @@ public BytesBuffer writeBytes(byte[] bytes) { public byte[] readBytes() { int length = this.readVInt(); assert length >= 0; - byte[] bytes = this.read(length); - return bytes; + return this.read(length); } public BytesBuffer writeBigBytes(byte[] bytes) { - E.checkArgument(bytes.length <= BLOB_LEN_MAX, - "The max length of bytes is %s, but got %s", - BLOB_LEN_MAX, bytes.length); + if (bytes.length > BLOB_LEN_MAX) { + E.checkArgument(false, + "The max length of bytes is %s, but got %s", + BLOB_LEN_MAX, bytes.length); + } require(BLOB_LEN + bytes.length); this.writeVInt(bytes.length); this.write(bytes); @@ -327,8 +382,7 @@ public BytesBuffer writeBigBytes(byte[] bytes) { public byte[] readBigBytes() { int length = this.readVInt(); assert length >= 0; - byte[] bytes = this.read(length); - return bytes; + return this.read(length); } public BytesBuffer writeStringRaw(String val) { @@ -356,11 +410,9 @@ public BytesBuffer writeStringWithEnding(String value) { * 0xFF is not a valid byte in UTF8 bytes */ assert !Bytes.contains(bytes, STRING_ENDING_BYTE_FF) : - "Invalid UTF8 bytes: " + value; + "Invalid UTF8 bytes: " + value; if (Bytes.contains(bytes, STRING_ENDING_BYTE)) { - E.checkArgument(false, - "Can't contains byte '0x00' in string: '%s'", - value); + E.checkArgument(false, "Can't contains byte '0x00' in string: '%s'", value); } this.write(bytes); } @@ -378,17 +430,6 @@ public BytesBuffer writeStringWithEnding(String value) { public String readStringWithEnding() { return StringEncoding.decode(this.readBytesWithEnding()); } - public String skipBytesWithEnding(){ - boolean foundEnding = false; - while (this.remaining() > 0) { - byte current = this.read(); - if (current == STRING_ENDING_BYTE) { - foundEnding = true; - break; - } - } - return ""; - } public BytesBuffer writeStringToRemaining(String value) { byte[] bytes = StringEncoding.encode(value); @@ -444,7 +485,7 @@ public BytesBuffer writeVInt(int value) { this.write(0x80 | ((value >>> 14) & 0x7f)); } if (value > 0x7f || value < 0) { - this.write(0x80 | ((value >>> 7) & 0x7f)); + this.write(0x80 | ((value >>> 7) & 0x7f)); } this.write(value & 0x7f); @@ -453,6 +494,11 @@ public BytesBuffer writeVInt(int value) { public int readVInt() { byte leading = this.read(); + if (leading == 0x80) { + E.checkArgument(false, + "Unexpected varint with leading byte '0x%s'", + Bytes.toHex(leading)); + } int value = leading & 0x7f; if (leading >= 0) { assert (leading & 0x80) == 0; @@ -470,6 +516,16 @@ public int readVInt() { } } + if (i >= 5) { + E.checkArgument(false, + "Unexpected varint %s with too many bytes(%s)", + value, i + 1); + } + if (i >= 4 && (leading & 0x70) != 0) { + E.checkArgument(false, + "Unexpected varint %s with leading byte '0x%s'", + value, Bytes.toHex(leading)); + } return value; } @@ -499,7 +555,7 @@ public BytesBuffer writeVLong(long value) { this.write(0x80 | ((int) (value >>> 14) & 0x7f)); } if (value > 0x7fL || value < 0L) { - this.write(0x80 | ((int) (value >>> 7) & 0x7f)); + this.write(0x80 | ((int) (value >>> 7) & 0x7f)); } this.write((int) value & 0x7f); @@ -508,9 +564,11 @@ public BytesBuffer writeVLong(long value) { public long readVLong() { byte leading = this.read(); - E.checkArgument(leading != 0x80, - "Unexpected varlong with leading byte '0x%s'", - Bytes.toHex(leading)); + if (leading == 0x80) { + E.checkArgument(false, + "Unexpected varlong with leading byte '0x%s'", + Bytes.toHex(leading)); + } long value = leading & 0x7fL; if (leading >= 0) { assert (leading & 0x80) == 0; @@ -528,84 +586,99 @@ public long readVLong() { } } - E.checkArgument(i < 10, - "Unexpected varlong %s with too many bytes(%s)", - value, i + 1); - E.checkArgument(i < 9 || (leading & 0x7e) == 0, - "Unexpected varlong %s with leading byte '0x%s'", - value, Bytes.toHex(leading)); + if (i >= 10) { + E.checkArgument(false, + "Unexpected varlong %s with too many bytes(%s)", + value, i + 1); + } + if (i >= 9 && (leading & 0x7e) != 0) { + E.checkArgument(false, + "Unexpected varlong %s with leading byte '0x%s'", + value, Bytes.toHex(leading)); + } return value; } - public T newValue(Cardinality cardinality) { - switch (cardinality) { - case SET: - return (T) new LinkedHashSet<>(); - case LIST: - return (T) new ArrayList<>(); - default: - // pass - break; - } - return null; + /** + * Store properties carry their cardinality and type in a leading byte. + * Schema-driven backend properties use {@link #writeSchemaProperty}. + */ + public BytesBuffer writeProperty(PropertyKey pkey, Object value) { + return this.writeProperty(pkey.cardinality(), pkey.dataType(), value); } - private byte getCardinalityAndType(int cardinality, int type){ - return (byte) ((cardinality << 6) | type); + public BytesBuffer writeProperty(Cardinality cardinality, DataType dataType, + Object value) { + this.write((cardinality.code() << 6) | dataType.code()); + return this.writePropertyValue(cardinality, dataType, value); } - public static byte getCardinality(int value){ - return (byte) ((value & 0xc0) >> 6); + public Object readProperty(PropertyKey pkey) { + int metadata = this.readUInt8(); + Cardinality cardinality = SerialEnum.fromCode(Cardinality.class, + getCardinality(metadata)); + DataType dataType = SerialEnum.fromCode(DataType.class, getType(metadata)); + pkey.cardinality(cardinality); + pkey.dataType(dataType); + return this.readPropertyValue(cardinality, dataType); } - public static byte getType(int value){ - return (byte) (value & 0x3f); + /** + * Encode a backend property whose metadata is supplied by the schema. + * Unlike Store's tagged format, no metadata byte is persisted here. + */ + public BytesBuffer writeSchemaProperty(PropertyKey pkey, Object value) { + return this.writePropertyValue(pkey.cardinality(), pkey.dataType(), value); } - public BytesBuffer writeProperty(PropertyKey pkey, Object value) { - return writeProperty(pkey.cardinality(), pkey.dataType(), value); + public Object readSchemaProperty(PropertyKey pkey) { + return this.readPropertyValue(pkey.cardinality(), pkey.dataType()); } - public BytesBuffer writeProperty(Cardinality cardinality, DataType dataType, Object value) { - this.write(getCardinalityAndType(cardinality.code(),dataType.code())); + private BytesBuffer writePropertyValue(Cardinality cardinality, + DataType dataType, Object value) { if (cardinality == Cardinality.SINGLE) { this.writeProperty(dataType, value); return this; } - assert cardinality == Cardinality.LIST || - cardinality == Cardinality.SET; + assert cardinality == Cardinality.LIST || cardinality == Cardinality.SET; Collection values = (Collection) value; this.writeVInt(values.size()); - for (Object o : values) { - this.writeProperty(dataType, o); + for (Object item : values) { + this.writeProperty(dataType, item); } return this; } - public Object readProperty(PropertyKey propertyKey) { - byte cardinalityAndType = this.read(); - Cardinality cardinality; - DataType type; - cardinality = SerialEnum.fromCode(Cardinality.class, - getCardinality(cardinalityAndType)); - - type = SerialEnum.fromCode(DataType.class, getType(cardinalityAndType)); - propertyKey.cardinality(cardinality); - propertyKey.dataType(type); + private Object readPropertyValue(Cardinality cardinality, DataType dataType) { if (cardinality == Cardinality.SINGLE) { - Object value = this.readProperty(type); - return value; + return this.readProperty(dataType); } - Collection values = this.newValue(cardinality); - assert cardinality == Cardinality.LIST || - cardinality == Cardinality.SET; + assert cardinality == Cardinality.LIST || cardinality == Cardinality.SET; int size = this.readVInt(); + Collection values = this.newValue(cardinality); for (int i = 0; i < size; i++) { - values.add(this.readProperty(type)); + values.add(this.readProperty(dataType)); } return values; } + @SuppressWarnings("unchecked") + public T newValue(Cardinality cardinality) { + switch (cardinality) { + case SET: + return (T) new LinkedHashSet<>(); + case LIST: + return (T) new ArrayList<>(); + default: + return null; + } + } + + public static byte getCardinality(int value) { + return (byte) ((value & 0xc0) >> 6); + } + public void writeProperty(DataType dataType, Object value) { switch (dataType) { case BOOLEAN: @@ -633,8 +706,7 @@ public void writeProperty(DataType dataType, Object value) { this.writeString((String) value); break; case BLOB: - byte[] bytes = value instanceof byte[] ? - (byte[]) value : ((Blob) value).bytes(); + byte[] bytes = value instanceof byte[] ? (byte[]) value : ((Blob) value).bytes(); this.writeBigBytes(bytes); break; case UUID: @@ -644,10 +716,15 @@ public void writeProperty(DataType dataType, Object value) { this.writeLong(uuid.getLeastSignificantBits()); break; default: - throw new IllegalArgumentException("Unsupported data type " + dataType); + this.writeBytes(KryoUtil.toKryoWithType(value)); + break; } } + public static byte getType(int value) { + return (byte) (value & 0x3f); + } + public Object readProperty(DataType dataType) { switch (dataType) { case BOOLEAN: @@ -671,15 +748,69 @@ public Object readProperty(DataType dataType) { case UUID: return new UUID(this.readLong(), this.readLong()); default: - throw new IllegalArgumentException("Unsupported data type " + dataType); + return KryoUtil.fromKryoWithType(this.readBytes()); } } - public BytesBuffer writeId(Id id) { - return this.writeId(id, false); + /** Skip a tagged property without allocating its value or collection. */ + public void skipProperty() { + int metadata = this.readUInt8(); + Cardinality cardinality = SerialEnum.fromCode(Cardinality.class, + getCardinality(metadata)); + DataType dataType = SerialEnum.fromCode(DataType.class, getType(metadata)); + this.skipPropertyValue(cardinality, dataType); } - public BytesBuffer writeId(Id id, boolean big) { + public void skipSchemaProperty(PropertyKey pkey) { + this.skipPropertyValue(pkey.cardinality(), pkey.dataType()); + } + + private void skipPropertyValue(Cardinality cardinality, DataType dataType) { + if (cardinality == Cardinality.SINGLE) { + this.skipProperty(dataType); + return; + } + assert cardinality == Cardinality.LIST || cardinality == Cardinality.SET; + int size = this.readVInt(); + E.checkArgument(size >= 0, "Invalid property collection size: %s", size); + for (int i = 0; i < size; i++) { + this.skipProperty(dataType); + } + } + + private void skipProperty(DataType dataType) { + switch (dataType) { + case BOOLEAN: + case BYTE: + case INT: + this.readVInt(); + return; + case LONG: + case DATE: + this.readVLong(); + return; + case FLOAT: + this.skip(FLOAT_LEN); + return; + case DOUBLE: + this.skip(DOUBLE_LEN); + return; + case UUID: + this.skip(Id.UUID_LENGTH); + return; + default: + // Text, blob and Kryo fallback payloads all carry a byte length. + this.skip(this.readVInt()); + } + } + + private void skip(int length) { + E.checkArgument(length >= 0 && length <= this.remaining(), + "Invalid skipped byte length %s, remaining %s", length, this.remaining()); + this.buffer.position(this.buffer.position() + length); + } + + public BytesBuffer writeId(Id id) { switch (id.type()) { case LONG: // Number Id @@ -687,35 +818,39 @@ public BytesBuffer writeId(Id id, boolean big) { this.writeNumber(value); break; case UUID: - // UUID Id + // UUID ID byte[] bytes = id.asBytes(); assert bytes.length == Id.UUID_LENGTH; this.writeUInt8(0x7f); // 0b01111111 means UUID this.write(bytes); break; case EDGE: - // Edge Id + // Edge ID this.writeUInt8(0x7e); // 0b01111110 means EdgeId this.writeEdgeId(id); break; default: - // String Id + // String Id (VertexID) bytes = id.asBytes(); int len = bytes.length; - E.checkArgument(len > 0, "Can't write empty id"); - E.checkArgument(len <= 16384, - "Big id max length is %s, but got %s {%s}", - 16384, len, id); - len -= 1; - if (len <= 63) { + if (len <= 0) { + E.checkArgument(false, "Can't write empty id"); + } + if (len > ID_LEN_MAX) { + E.checkArgument(false, "Big id max length is %s, but got %s {%s}", + ID_LEN_MAX, len, id); + } + len -= 1; // mapping [1, 16384] to [0, 16383] + if (len <= 0x3f) { + // If length is <= 63, use a single byte with the highest bit set to 1 this.writeUInt8(len | 0x80); } else { int high = len >> 8; int low = len & 0xff; + // Write high 8 bits with highest two bits set to 11 this.writeUInt8(high | 0xc0); this.writeUInt8(low); } - this.write(bytes); break; } @@ -723,10 +858,6 @@ public BytesBuffer writeId(Id id, boolean big) { } public Id readId() { - return this.readId(false); - } - - public Id readId(boolean big) { byte b = this.read(); boolean number = (b & 0x80) == 0; if (number) { @@ -742,19 +873,32 @@ public Id readId(boolean big) { } } else { // String Id - int len = b & 0x3f; - if ((b & 0x40) != 0) { + int len = b & 0x3f; // Take the lowest 6 bits as part of the length + if ((b & 0x40) != 0) { // If the 7th bit is set, length information spans 2 bytes int high = len << 8; int low = this.readUInt8(); len = high + low; } - len += 1; + len += 1; // restore [0, 16383] to [1, 16384] byte[] id = this.read(len); return IdGenerator.of(id, IdType.STRING); } } + /** + * Preserve the existing Store API. Both modes use the same persisted ID + * header; the flag has never selected a different on-disk format. + */ + public BytesBuffer writeId(Id id, boolean big) { + return this.writeId(id); + } + + public Id readId(boolean big) { + return this.readId(); + } + public BytesBuffer writeEdgeId(Id id) { + // owner-vertex + dir + edge-label + sub-edge-label + sort-values + other-vertex EdgeId edge = (EdgeId) id; this.writeId(edge.ownerVertexId()); this.write(edge.directionCode()); @@ -766,18 +910,79 @@ public BytesBuffer writeEdgeId(Id id) { } public Id readEdgeId() { - return new EdgeId(this.readId(), EdgeId.directionFromCode(this.read()), - this.readId(), this.readId(), - this.readStringWithEnding(), this.readId()); + return this.readEdgeId(true, null); + } + + public EdgeId readEdgeId(boolean withOwnerPrefix, Id suppliedOwner) { + return this.readEdgeId(withOwnerPrefix, suppliedOwner, false); + } + + private EdgeId readEdgeId(boolean withOwnerPrefix, Id suppliedOwner, boolean skipSortValues) { + Id owner = withOwnerPrefix ? this.readId() : suppliedOwner; + E.checkArgumentNotNull(owner, "Edge decoding requires an owner ID"); + byte direction = this.read(); + E.checkState(direction == HugeType.EDGE_IN.code() || direction == HugeType.EDGE_OUT.code(), + "Invalid edge column type: %s", direction & 0xff); + Id label = this.readId(); + Id subLabel = this.readId(); + String sortValues = skipSortValues ? this.skipBytesWithEnding() : this.readStringWithEnding(); + return new EdgeId(owner, EdgeId.directionFromCode(direction), label, subLabel, + sortValues, this.readId()); + } + + public enum IndexExpiryLayout { + NONE, + REQUIRED, + OPTIONAL + } + + /** Decode the shared index/element/expiry field order; callers choose the layout. */ + public IndexColumnName readIndexColumnName(HugeType type, boolean withIndexPrefix, + IndexExpiryLayout expiryLayout) { + E.checkArgumentNotNull(expiryLayout, "Index expiry layout can't be null"); + BinaryId indexId = withIndexPrefix ? this.readIndexId(type) : null; + Id elementId = this.readId(); + boolean hasExpiredTime = expiryLayout == IndexExpiryLayout.REQUIRED || + expiryLayout == IndexExpiryLayout.OPTIONAL && this.remaining() > 0; + long expiredTime = hasExpiredTime ? this.readVLong() : 0L; + if (expiryLayout == IndexExpiryLayout.OPTIONAL) { + E.checkState(this.remaining() == 0, + "Unexpected trailing bytes in schema index column: %s", this.remaining()); + } + return new IndexColumnName(indexId, elementId, expiredTime, hasExpiredTime); } - public Id readEdgeIdSkipSortValues() { - return new EdgeId(this.readId(), EdgeId.directionFromCode(this.read()), - this.readId(), this.readId(), - this.skipBytesWithEnding(), - this.readId()); - } + public static final class IndexColumnName { + + private final BinaryId indexId; + private final Id elementId; + private final long expiredTime; + private final boolean hasExpiredTime; + + private IndexColumnName(BinaryId indexId, Id elementId, long expiredTime, + boolean hasExpiredTime) { + this.indexId = indexId; + this.elementId = elementId; + this.expiredTime = expiredTime; + this.hasExpiredTime = hasExpiredTime; + } + public BinaryId indexId() { + return this.indexId; + } + + public Id elementId() { + return this.elementId; + } + + public long expiredTime() { + return this.expiredTime; + } + + public boolean hasExpiredTime() { + return this.hasExpiredTime; + } + } public BytesBuffer writeIndexId(Id id, HugeType type) { return this.writeIndexId(id, type, true); @@ -786,17 +991,18 @@ public BytesBuffer writeIndexId(Id id, HugeType type) { public BytesBuffer writeIndexId(Id id, HugeType type, boolean withEnding) { byte[] bytes = id.asBytes(); int len = bytes.length; - E.checkArgument(len > 0, "Can't write empty id"); + if (len == 0) { + E.checkArgument(false, "Can't write empty id"); + } this.write(bytes); if (type.isStringIndex()) { if (Bytes.contains(bytes, STRING_ENDING_BYTE)) { - // Not allow STRING_ENDING_BYTE exist in string index id + // Not allow STRING_ENDING_BYTE to exist in string index id E.checkArgument(false, "The %s type index id can't contains " + - "byte '0x%s', but got: 0x%s", type, - Bytes.toHex(STRING_ENDING_BYTE), - Bytes.toHex(bytes)); + "byte '0x%s', but got: 0x%s", + type, Bytes.toHex(STRING_ENDING_BYTE), Bytes.toHex(bytes)); } if (withEnding) { this.writeStringWithEnding(""); @@ -808,10 +1014,10 @@ public BytesBuffer writeIndexId(Id id, HugeType type, boolean withEnding) { public BinaryId readIndexId(HugeType type) { byte[] id; if (type.isRange4Index()) { - // HugeCodeType 1 bytes + IndexLabel 4 bytes + fieldValue 4 bytes + // HugeTypeCode 1 byte + IndexLabel 4 bytes + fieldValue 4 bytes id = this.read(9); } else if (type.isRange8Index()) { - // HugeCodeType 1 bytes + IndexLabel 4 bytes + fieldValue 8 bytes + // HugeTypeCode 1 byte + IndexLabel 4 bytes + fieldValue 8 bytes id = this.read(13); } else { assert type.isStringIndex(); @@ -825,10 +1031,17 @@ public BinaryId asId() { } public BinaryId parseId(HugeType type) { + return this.parseId(type, false); + } + + public BinaryId parseId(HugeType type, boolean enablePartition) { if (type.isIndex()) { return this.readIndexId(type); } // Parse id from bytes + if ((type.isVertex() || type.isEdge()) && enablePartition) { + this.readShort(); + } int start = this.buffer.position(); /* * Since edge id in edges table doesn't prefix with leading 0x7e, @@ -844,7 +1057,7 @@ public BinaryId parseId(HugeType type) { } /** - * Parse OLAP id + * Analyze olap id * @param type * @param isOlap * @return @@ -855,12 +1068,9 @@ public BinaryId parseOlapId(HugeType type, boolean isOlap) { } // Parse id from bytes int start = this.buffer.position(); - /** - * OLAP - * {PropertyKey}{VertexId} - */ + // OLAP {PropertyKey}{VertexId} if (isOlap) { - // First read OLAP property id + // Read olap property id first Id pkId = this.readId(); } Id id = this.readId(); @@ -939,6 +1149,11 @@ private void writeNumber(long val) { } private long readNumber(byte b) { + if ((b & 0x80) != 0) { + E.checkArgument(false, + "Not a number type with prefix byte '0x%s'", + Bytes.toHex(b)); + } // Parse the kind from byte 0kkksxxx int kind = b >>> 4; boolean positive = (b & 0x08) > 0; @@ -986,27 +1201,48 @@ private long readNumber(byte b) { private byte[] readBytesWithEnding() { int start = this.buffer.position(); boolean foundEnding = false; - while (this.remaining() > 0) { + int remaining = this.remaining(); + for (int i = 0; i < remaining; i++) { byte current = this.read(); if (current == STRING_ENDING_BYTE) { foundEnding = true; break; } } - E.checkArgument(foundEnding, "Not found ending '0x%s'", - Bytes.toHex(STRING_ENDING_BYTE)); + if (!foundEnding) { + E.checkArgument(false, + "Not found ending '0x%s'", + Bytes.toHex(STRING_ENDING_BYTE)); + } int end = this.buffer.position() - 1; int len = end - start; + if (len <= 0) { + return BYTES_EMPTY; + } byte[] bytes = new byte[len]; System.arraycopy(this.array(), start, bytes, 0, len); return bytes; } - public byte[] remainingBytes(){ - int length = this.remaining(); + public byte[] readToEnd() { + return this.read(this.remaining()); + } + + public String skipBytesWithEnding() { + while (this.remaining() > 0) { + if (this.read() == STRING_ENDING_BYTE) { + break; + } + } + return ""; + } + + public Id readEdgeIdSkipSortValues() { + return this.readEdgeId(true, null, true); + } + + public byte[] remainingBytes() { int start = this.position(); - byte[] bytes = new byte[length]; - System.arraycopy(this.array(), start, bytes, 0, length); - return bytes; + return Arrays.copyOfRange(this.array(), start, start + this.remaining()); } } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/serializer/DirectBinarySerializer.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/serializer/DirectBinarySerializer.java index bad18ebf8a..8aa325eabe 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/serializer/DirectBinarySerializer.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/serializer/DirectBinarySerializer.java @@ -22,9 +22,13 @@ import java.util.Arrays; import java.util.Base64; +import org.apache.hugegraph.HugeGraphSupplier; +import org.apache.hugegraph.backend.BackendColumn; import org.apache.hugegraph.id.Id; import org.apache.hugegraph.id.IdGenerator; -import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.structure.Index; +import org.apache.hugegraph.type.HugeType; +import org.apache.hugegraph.util.E; import org.apache.hugegraph.util.Bytes; import org.apache.hugegraph.util.Log; import org.slf4j.Logger; @@ -111,18 +115,56 @@ public DirectHugeElement parseEdge(byte[] key, byte[] value) { return new DirectHugeElement(IdGenerator.of(key), expiredTime); } + public DirectHugeElement parseSchemaIndex(HugeGraphSupplier graph, byte[] key, byte[] value) { + Index index = BinaryElementSerializer.getInstance().parseSchemaIndex( + graph, BackendColumn.of(key, value)); + return new DirectHugeElement(IdGenerator.of(key), index.expiredTime()); + } + + /** Read TTL from an untagged persisted Server vertex row. */ + public DirectHugeElement parseSchemaVertex(HugeGraphSupplier graph, byte[] key, byte[] value) { + E.checkArgumentNotNull(graph, "Schema vertex decoding requires a schema supplier"); + BytesBuffer buffer = BytesBuffer.wrap(value); + Id labelId = buffer.readId(); + this.skipProperties(buffer, graph); + long expiredTime = graph.vertexLabelOrNone(labelId).ttl() > 0 ? buffer.readVLong() : 0L; + return new DirectHugeElement(IdGenerator.of(key), expiredTime); + } + + /** Read TTL from an untagged persisted Server edge row. */ + public DirectHugeElement parseSchemaEdge(HugeGraphSupplier graph, byte[] key, byte[] value) { + E.checkArgumentNotNull(graph, "Schema edge decoding requires a schema supplier"); + BytesBuffer name = BytesBuffer.wrap(key); + name.readId(); + byte type = name.read(); + E.checkState(type == HugeType.EDGE_IN.code() || type == HugeType.EDGE_OUT.code(), + "Invalid edge column type: %s", type & 0xff); + name.readId(); + Id subLabelId = name.readId(); + BytesBuffer buffer = BytesBuffer.wrap(value); + this.skipProperties(buffer, graph); + long expiredTime = graph.edgeLabelOrNone(subLabelId).ttl() > 0 ? buffer.readVLong() : 0L; + return new DirectHugeElement(IdGenerator.of(key), expiredTime); + } + private void skipProperties(BytesBuffer buffer) { + this.skipProperties(buffer, null); + } + + private void skipProperties(BytesBuffer buffer, HugeGraphSupplier graph) { int size = buffer.readVInt(); assert size >= 0; for (int i = 0; i < size; i++) { Id pkeyId = IdGenerator.of(buffer.readVInt()); - this.skipProperty(pkeyId, buffer); + if (graph == null) { + this.skipProperty(pkeyId, buffer); + } else { + buffer.skipSchemaProperty(graph.propertyKey(pkeyId)); + } } } protected void skipProperty(Id pkeyId, BytesBuffer buffer) { - // Parse value - PropertyKey pkey = new PropertyKey(null, pkeyId, ""); - buffer.readProperty(pkey); + buffer.skipProperty(); } } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/serializer/OlapKey.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/serializer/OlapKey.java new file mode 100644 index 0000000000..814aea66e9 --- /dev/null +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/serializer/OlapKey.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.serializer; + +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.struct.schema.SchemaElement; + +/** Physical keys for the merged HStore OLAP table, independent of the value codec. */ +public final class OlapKey { + + private OlapKey() { + } + + public static byte[] format(Id propertyId, Id vertexId) { + return BytesBuffer.allocate(propertyId.length() + vertexId.length() + 18) + .writeId(propertyId).writeId(vertexId).bytes(); + } + + public static boolean matchesProperty(byte[] value, Id propertyId) { + if (value == null || value.length == 0) { + return false; + } + try { + return BytesBuffer.wrap(value).readVInt() == SchemaElement.schemaId(propertyId); + } catch (IllegalArgumentException | java.nio.BufferUnderflowException e) { + return false; + } + } +} diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/EdgeLabel.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/EdgeLabel.java index 7148495a78..128f8f4f63 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/EdgeLabel.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/EdgeLabel.java @@ -332,6 +332,7 @@ public static EdgeLabel fromMap(Map map, HugeGraphSupplier graph Id id = IdGenerator.of((int) map.get(EdgeLabel.P.ID)); String name = (String) map.get(EdgeLabel.P.NAME); EdgeLabel edgeLabel = new EdgeLabel(graph, id, name); + restoreLinks(map, edgeLabel); for (Map.Entry entry : map.entrySet()) { switch (entry.getKey()) { case P.ID: @@ -373,25 +374,9 @@ public static EdgeLabel fromMap(Map map, HugeGraphSupplier graph edgeLabel.ttlStartTime(IdGenerator.of(ttlStartTime)); break; case P.LINKS: - // TODO: serialize and deserialize - List list = (List) entry.getValue(); - for (Map m : list) { - for (Object key : m.keySet()) { - Id sid = IdGenerator.of(Long.parseLong((String) key)); - Id tid = IdGenerator.of(Long.parseLong(String.valueOf(m.get(key)))); - edgeLabel.links(Pair.of(sid, tid)); - } - } - break; case P.SOURCE_LABEL: - long sourceLabel = - Long.parseLong((String) entry.getValue()); - edgeLabel.sourceLabel(IdGenerator.of(sourceLabel)); - break; case P.TARGET_LABEL: - long targetLabel = - Long.parseLong((String) entry.getValue()); - edgeLabel.targetLabel(IdGenerator.of(targetLabel)); + // These fields describe the same links and were restored together. break; case P.FATHER_ID: long fatherId = @@ -410,9 +395,9 @@ public static EdgeLabel fromMap(Map map, HugeGraphSupplier graph edgeLabel.frequency(frequency); break; case P.SORT_KEYS: - ids = ((List) entry.getValue()).stream().map( - IdGenerator::of).collect(Collectors.toSet()); - edgeLabel.sortKeys(ids.toArray(new Id[0])); + List orderedIds = ((List) entry.getValue()).stream().map( + IdGenerator::of).collect(Collectors.toList()); + edgeLabel.sortKeys(orderedIds.toArray(new Id[0])); break; default: throw new AssertionError(String.format( @@ -423,6 +408,48 @@ public static EdgeLabel fromMap(Map map, HugeGraphSupplier graph return edgeLabel; } + private static void restoreLinks(Map map, EdgeLabel edgeLabel) { + Set> links = new HashSet<>(); + if (map.containsKey(P.LINKS)) { + Object value = map.get(P.LINKS); + E.checkArgument(value instanceof List, "Invalid edge label links: %s", value); + for (Object item : (List) value) { + E.checkArgument(item instanceof Map && !((Map) item).isEmpty(), + "Invalid edge label link: %s", item); + for (Map.Entry link : ((Map) item).entrySet()) { + links.add(Pair.of(linkId(link.getKey(), P.SOURCE_LABEL), + linkId(link.getValue(), P.TARGET_LABEL))); + } + } + } + + boolean hasSource = map.containsKey(P.SOURCE_LABEL); + boolean hasTarget = map.containsKey(P.TARGET_LABEL); + E.checkArgument(hasSource == hasTarget, + "Edge label sourceLabel and targetLabel must be provided together"); + if (hasSource) { + Pair endpoints = Pair.of(linkId(map.get(P.SOURCE_LABEL), P.SOURCE_LABEL), + linkId(map.get(P.TARGET_LABEL), P.TARGET_LABEL)); + E.checkArgument(links.isEmpty() || links.contains(endpoints), + "Edge label endpoints %s conflict with links %s", endpoints, links); + links.add(endpoints); + } + for (Pair link : links) { + edgeLabel.links(link); + } + } + + private static Id linkId(Object value, String field) { + E.checkArgument(value instanceof String || value instanceof Number, + "Invalid edge label %s: %s", field, value); + try { + return IdGenerator.of(Long.parseLong(value.toString())); + } catch (NumberFormatException e) { + throw new IllegalArgumentException(String.format( + "Invalid edge label %s: %s", field, value), e); + } + } + public static final class P { public static final String ID = "id"; diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/IndexLabel.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/IndexLabel.java index 2ef5eb9962..282d9ea79f 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/IndexLabel.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/IndexLabel.java @@ -126,7 +126,7 @@ public SchemaLabel baseLabel() { } public SchemaLabel baseElement() { - return getElement(this.graph, this.baseType, this.baseValue); + return getBaseLabel(this.graph, this.baseType, this.baseValue); } public boolean hasSameContent(IndexLabel other) { @@ -258,44 +258,6 @@ public static SchemaLabel getBaseLabel(HugeGraphSupplier graph, return label; } - public static SchemaLabel getElement(HugeGraphSupplier graph, - HugeType baseType, Object baseValue) { - E.checkNotNull(baseType, "base type", "index label"); - E.checkNotNull(baseValue, "base value", "index label"); - E.checkArgument(baseValue instanceof String || baseValue instanceof Id, - "The base value must be instance of String or Id, " + - "but got %s(%s)", baseValue, - baseValue.getClass().getSimpleName()); - - SchemaLabel label; - switch (baseType) { - case VERTEX_LABEL: - if (baseValue instanceof String) { - label = graph.vertexLabel((String) baseValue); - } else { - assert baseValue instanceof Id; - label = graph.vertexLabel((Id) baseValue); - } - break; - case EDGE_LABEL: - if (baseValue instanceof String) { - label = graph.edgeLabel((String) baseValue); - } else { - assert baseValue instanceof Id; - label = graph.edgeLabel((Id) baseValue); - } - break; - default: - throw new AssertionError(String.format( - "Unsupported base type '%s' of index label", - baseType)); - } - - E.checkArgumentNotNull(label, "Can't find the %s with name '%s'", - baseType.readableName(), baseValue); - return label; - } - public String convert2Groovy(boolean attachIdFlag) { StringBuilder builder = new StringBuilder(SCHEMA_PREFIX); diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/SchemaElement.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/SchemaElement.java index a62532ff79..d2563e34e9 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/SchemaElement.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/SchemaElement.java @@ -76,6 +76,8 @@ public SchemaElement(final HugeGraphSupplier graph, Id id, String name) { } public HugeGraphSupplier graph() { + E.checkState(this.graph != null, + "Graph is null of schema '%s'", this.name); return this.graph; } @@ -103,10 +105,12 @@ public void userdata(String key, Object value) { } public void userdata(Userdata userdata) { + E.checkArgumentNotNull(userdata, "userdata"); this.userdata.putAll(userdata); } public void userdata(Map userdata) { + E.checkArgumentNotNull(userdata, "userdata"); this.userdata.putAll(userdata); } @@ -116,6 +120,7 @@ public void removeUserdata(String key) { } public void removeUserdata(Userdata userdata) { + E.checkArgumentNotNull(userdata, "userdata"); for (String key : userdata.keySet()) { this.userdata.remove(key); } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/Userdata.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/Userdata.java index 1cd0db0e0f..8aef1e5610 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/Userdata.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/Userdata.java @@ -22,6 +22,7 @@ import org.apache.hugegraph.exception.NotAllowException; import org.apache.hugegraph.type.define.Action; +import org.apache.hugegraph.util.DateUtil; public class Userdata extends HashMap { @@ -37,6 +38,51 @@ public Userdata(Map map) { this.putAll(map); } + /** + * Normalizes the value before storing so the {@link #CREATE_TIME}-is-Date + * invariant holds regardless of how entries are added. + */ + @Override + public Object put(String key, Object value) { + return super.put(key, normalizeValue(key, value)); + } + + @Override + public void putAll(Map map) { + for (Map.Entry e : map.entrySet()) { + this.put(e.getKey(), e.getValue()); + } + } + + /** + * Normalize internal userdata values whose runtime type can diverge from + * their serialized form. The only such key today is {@link #CREATE_TIME}: + * it is written as a {@link java.util.Date} but persisted as a formatted + * JSON string by the backend serializers, and Jackson cannot re-type a + * value to {@code Date} when the target is a raw {@code Map}. This method + * restores the original type after deserialization. Idempotent for values + * already of the expected type. + *

+ * An empty string is passed through unchanged: it is the key-only + * placeholder used by the {@code eliminate()}/{@code DELETE} builder flow + * (e.g. {@code .userdata(CREATE_TIME, "").eliminate()}), where the value is + * ignored and only the key drives {@code removeUserdata}. Parsing it would + * fail before the eliminate path can apply its key-only semantics. + */ + public static Object normalizeValue(String key, Object value) { + if (CREATE_TIME.equals(key) && value instanceof String && + !((String) value).isEmpty()) { + try { + return DateUtil.parse((String) value); + } catch (RuntimeException e) { + throw new IllegalArgumentException(String.format( + "Invalid userdata '%s' value: '%s'", + CREATE_TIME, value), e); + } + } + return value; + } + public static void check(Userdata userdata, Action action) { if (userdata == null) { return; diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/VertexLabel.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/VertexLabel.java index 2a0002e69d..6b0b3cfe77 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/VertexLabel.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/VertexLabel.java @@ -380,9 +380,9 @@ public static VertexLabel fromMap(Map map, HugeGraphSupplier gra vertexLabel.idStrategy(idStrategy); break; case P.PRIMARY_KEYS: - ids = ((List) entry.getValue()).stream().map( - IdGenerator::of).collect(Collectors.toSet()); - vertexLabel.primaryKeys(ids.toArray(new Id[0])); + List orderedIds = ((List) entry.getValue()).stream().map( + IdGenerator::of).collect(Collectors.toList()); + vertexLabel.primaryKeys(orderedIds.toArray(new Id[0])); break; default: throw new AssertionError(String.format( diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/BaseEdge.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/BaseEdge.java index bafc2b727a..8032be1aff 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/BaseEdge.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/BaseEdge.java @@ -26,7 +26,7 @@ import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.id.EdgeId; import org.apache.hugegraph.id.Id; -import org.apache.hugegraph.id.SplicingIdGenerator; +import org.apache.hugegraph.query.ConditionQuery; import org.apache.hugegraph.serializer.BytesBuffer; import org.apache.hugegraph.struct.schema.EdgeLabel; import org.apache.hugegraph.struct.schema.SchemaLabel; @@ -73,7 +73,8 @@ public EdgeId idWithDirection() { @Override public String name() { if (this.name == null) { - this.name = SplicingIdGenerator.concatValues(sortValues()); + List values = this.sortValues(); + this.name = values.isEmpty() ? "" : ConditionQuery.concatValues(values); } return this.name; } @@ -98,7 +99,11 @@ public List sortValues() { BaseProperty property = this.getProperty(sk); E.checkState(property != null, "The value of sort key '%s' can't be null", sk); - propValues.add(property.propertyKey().serialValue(property.value(), true)); + Object value = property.serialValue(true); + if ("".equals(value)) { + value = ConditionQuery.INDEX_VALUE_EMPTY; + } + propValues.add(value); } return propValues; } @@ -182,9 +187,9 @@ public void assignId() { if (this.fresh()) { int len = this.id().length(); - E.checkArgument(len <= BytesBuffer.BIG_ID_LEN_MAX, + E.checkArgument(len <= BytesBuffer.EID_LEN_MAX, "The max length of edge id is %s, but got %s {%s}", - BytesBuffer.BIG_ID_LEN_MAX, len, this.id()); + BytesBuffer.EID_LEN_MAX, len, this.id()); } } @Override @@ -238,29 +243,78 @@ public BaseEdge switchOwner() { return edge; } + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (!(object instanceof BaseEdge) || this.id() == null) { + return false; + } + return this.id().equals(((BaseEdge) object).id()); + } + + @Override + public int hashCode() { + return this.id() == null ? System.identityHashCode(this) : this.id().hashCode(); + } + public static BaseEdge constructEdge(HugeGraphSupplier graph, BaseVertex ownerVertex, boolean isOutEdge, EdgeLabel edgeLabel, String sortValues, Id otherVertexId) { + BaseEdge edge = createEdge(graph, ownerVertex, isOutEdge, edgeLabel, + sortValues, otherVertexId); + ownerVertex.addEdge(edge); + edge.otherVertex().addEdge(edge.switchOwner()); + return edge; + } + + /** Create endpoint/schema state; adapters own adjacency attachment. */ + public static BaseEdge createEdge(HugeGraphSupplier graph, + BaseVertex ownerVertex, + boolean isOutEdge, + EdgeLabel edgeLabel, + String sortValues, + Id otherVertexId) { Id ownerLabelId = edgeLabel.sourceLabel(); Id otherLabelId = edgeLabel.targetLabel(); VertexLabel srcLabel; VertexLabel tgtLabel; if (graph == null) { - srcLabel = new VertexLabel(null, ownerLabelId, "UNDEF"); - tgtLabel = new VertexLabel(null, otherLabelId, "UNDEF"); + return createEdgeWithoutSchema(null, ownerVertex, isOutEdge, edgeLabel, + sortValues, otherVertexId); + } + if (edgeLabel.general() && + ownerVertex.typeContext() == BaseVertex.TypeContext.STORAGE) { + srcLabel = VertexLabel.GENERAL; + tgtLabel = VertexLabel.GENERAL; } else { - if (edgeLabel.general()) { - srcLabel = VertexLabel.GENERAL; - tgtLabel = VertexLabel.GENERAL; - } else { - srcLabel = graph.vertexLabelOrNone(ownerLabelId); - tgtLabel = graph.vertexLabelOrNone(otherLabelId); - } + srcLabel = graph.vertexLabelOrNone(ownerLabelId); + tgtLabel = graph.vertexLabelOrNone(otherLabelId); } + return createEdge(ownerVertex, isOutEdge, edgeLabel, sortValues, + otherVertexId, srcLabel, tgtLabel); + } + /** Resolve no metadata, while retaining an optional supplier for later engine access. */ + public static BaseEdge createEdgeWithoutSchema(HugeGraphSupplier supplier, + BaseVertex ownerVertex, + boolean isOutEdge, + EdgeLabel edgeLabel, + String sortValues, + Id otherVertexId) { + VertexLabel source = VertexLabel.undefined(supplier, edgeLabel.sourceLabel()); + VertexLabel target = VertexLabel.undefined(supplier, edgeLabel.targetLabel()); + return createEdge(ownerVertex, isOutEdge, edgeLabel, sortValues, + otherVertexId, source, target); + } + + private static BaseEdge createEdge(BaseVertex ownerVertex, boolean isOutEdge, + EdgeLabel edgeLabel, String sortValues, Id otherVertexId, + VertexLabel srcLabel, VertexLabel tgtLabel) { VertexLabel otherVertexLabel; if (isOutEdge) { ownerVertex.correctVertexLabel(srcLabel); @@ -269,6 +323,14 @@ public static BaseEdge constructEdge(HugeGraphSupplier graph, ownerVertex.correctVertexLabel(tgtLabel); otherVertexLabel = srcLabel; } + return createEdge(ownerVertex, isOutEdge, edgeLabel, sortValues, + otherVertexId, otherVertexLabel); + } + + /** Create an edge after the caller has resolved its endpoint labels. */ + public static BaseEdge createEdge(BaseVertex ownerVertex, boolean isOutEdge, + EdgeLabel edgeLabel, String sortValues, + Id otherVertexId, VertexLabel otherVertexLabel) { BaseVertex otherVertex = new BaseVertex(otherVertexId, otherVertexLabel); ownerVertex.propLoaded(false); @@ -279,9 +341,6 @@ public static BaseEdge constructEdge(HugeGraphSupplier graph, edge.vertices(isOutEdge, ownerVertex, otherVertex); edge.assignId(); - ownerVertex.addEdge(edge); - otherVertex.addEdge(edge.switchOwner()); - return edge; } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/BaseElement.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/BaseElement.java index c7353d6b77..b250922d0d 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/BaseElement.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/BaseElement.java @@ -28,6 +28,9 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; import java.util.function.Supplier; import org.apache.hugegraph.id.Id; @@ -41,6 +44,7 @@ import org.apache.hugegraph.type.define.HugeKeys; import org.apache.hugegraph.util.CollectionUtil; import org.apache.hugegraph.util.E; +import org.apache.hugegraph.util.InsertionOrderUtil; import org.apache.hugegraph.util.Log; import org.apache.hugegraph.util.collection.CollectionFactory; import org.eclipse.collections.api.map.primitive.MutableIntObjectMap; @@ -49,16 +53,16 @@ import org.slf4j.Logger; -public abstract class BaseElement implements GraphType, Idfiable, Serializable { +public abstract class BaseElement implements GraphType, Idfiable, Serializable, Cloneable { private static final Logger LOG = Log.logger(BaseElement.class); - public static final MutableIntObjectMap> EMPTY_MAP = - new IntObjectHashMap<>(); + private static final MutableIntObjectMap> EMPTY_MAP = + new IntObjectHashMap>().asUnmodifiable(); - private static final int MAX_PROPERTIES = BytesBuffer.UINT16_MAX; + private static final int MAX_PROPERTIES = BytesBuffer.MAX_PROPERTIES; - MutableIntObjectMap> properties; + private MutableIntObjectMap> properties; Id id; private SchemaLabel schemaLabel; @@ -228,7 +232,15 @@ public V getPropertyValue(Id key) { } return (V) prop.value(); } + /** + * Mutable storage for codecs and owning adapters. The empty map is materialized + * per element before exposure; callers never receive the shared sentinel. + * Direct changes update this container only, without engine transaction callbacks. + */ public MutableIntObjectMap> properties() { + if (this.properties == EMPTY_MAP) { + this.properties = CollectionFactory.newIntObjectMap(); + } return this.properties; } @@ -240,13 +252,14 @@ public BaseProperty getProperty(Id key) { } private BaseProperty addProperty(PropertyKey pkey, V value, - Supplier> supplier) { + Supplier> supplier, + BiFunction> factory) { assert pkey.cardinality().multiple(); BaseProperty> property; if (this.hasProperty(pkey.id())) { property = this.getProperty(pkey.id()); } else { - property = this.newProperty(pkey, supplier.get()); + property = (BaseProperty>) factory.apply(pkey, supplier.get()); this.addProperty(property); } @@ -265,36 +278,47 @@ private BaseProperty addProperty(PropertyKey pkey, V value, values = CollectionUtil.toList(value); } } - property.value().addAll(values); + property.value().addAll(pkey.validValueOrThrow(values)); // Any better ways? return (BaseProperty) property; } public BaseProperty addProperty(PropertyKey pkey, V value) { - BaseProperty prop = null; + return this.addProperty(pkey, value, (key, val) -> this.newProperty(key, val), + prop -> {}, prop -> {}); + } + + /** Single updates notify before replacement; collection updates notify afterwards. */ + @SuppressWarnings("unchecked") + public BaseProperty addProperty( + PropertyKey pkey, V value, + BiFunction> factory, + Consumer> beforeSingle, + Consumer> afterMultiple) { + BaseProperty prop; switch (pkey.cardinality()) { case SINGLE: - prop = this.newProperty(pkey, value); + prop = (BaseProperty) factory.apply(pkey, value); + beforeSingle.accept(prop); this.addProperty(prop); break; case SET: - prop = this.addProperty(pkey, value, HashSet::new); + prop = this.addProperty(pkey, value, HashSet::new, factory); + afterMultiple.accept(prop); break; case LIST: - prop = this.addProperty(pkey, value, ArrayList::new); + prop = this.addProperty(pkey, value, ArrayList::new, factory); + afterMultiple.accept(prop); break; default: - assert false; - break; + throw new AssertionError("Unknown property cardinality: " + pkey.cardinality()); } return prop; } public BaseProperty addProperty(BaseProperty prop) { - if (this.properties == EMPTY_MAP) { - this.properties = new IntObjectHashMap<>(); // change to CollectionFactory.newIntObjectMap(); - } + this.properties(); PropertyKey pkey = prop.propertyKey(); E.checkArgument(this.properties.containsKey(intFromId(pkey.id())) || @@ -311,7 +335,11 @@ public Map> getProperties() { } public BaseProperty removeProperty(Id key) { - return this.properties.remove(intFromId(key)); + int propertyId = intFromId(key); + if (this.properties == EMPTY_MAP) { + return null; + } + return this.properties.remove(propertyId); } /* a util may be should be moved to other place */ @@ -324,7 +352,7 @@ public static int intFromId(Id id) { public abstract Object sysprop(HugeKeys key); public Map getPropertiesMap() { - Map props = new HashMap<>(); + Map props = InsertionOrderUtil.newMap(); for (IntObjectPair> e : this.properties.keyValuesView()) { props.put(IdGenerator.of(e.getOne()), e.getTwo().value()); } @@ -347,6 +375,28 @@ public int sizeOfSubProperties() { return size; } + public void copyProperties(BaseElement source) { + this.properties = source.properties == EMPTY_MAP ? EMPTY_MAP : + CollectionFactory.newIntObjectMap(source.properties); + this.propLoaded(true); + } + + public void updateDefaultValues(Function keys) { + if (this.fresh || this.defaultValueUpdated) { + return; + } + this.defaultValueUpdated = true; + for (Id id : this.schemaLabel().properties()) { + if (!this.hasProperty(id)) { + PropertyKey key = keys.apply(id); + Object value = key.defaultValue(); + if (value != null) { + this.addProperty(newProperty(key, value)); + } + } + } + } + @Override public BaseElement clone() throws CloneNotSupportedException{ return (BaseElement) super.clone(); diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/BaseProperty.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/BaseProperty.java index d70384b631..763812eeea 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/BaseProperty.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/BaseProperty.java @@ -62,7 +62,7 @@ public PropertyKey propertyKey() { } public Object serialValue(boolean encodeNumber) { - return this.propertyKey.serialValue(this.value, encodeNumber); + return this.propertyKey.serialValue(this.value(), encodeNumber); } } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/BaseVertex.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/BaseVertex.java index fe9ab832d7..6982d69a2d 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/BaseVertex.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/BaseVertex.java @@ -21,11 +21,13 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Iterator; import java.util.List; import org.apache.hugegraph.id.Id; import org.apache.hugegraph.id.SplicingIdGenerator; import org.apache.hugegraph.perf.PerfUtil; +import org.apache.hugegraph.query.ConditionQuery; import org.apache.hugegraph.struct.schema.SchemaLabel; import org.apache.hugegraph.struct.schema.VertexLabel; import org.apache.hugegraph.type.HugeType; @@ -42,6 +44,14 @@ public class BaseVertex extends BaseElement implements Cloneable { protected Collection edges; + private boolean encodeNumber = true; + private TypeContext typeContext = TypeContext.STORAGE; + + /** Classification differs for legacy storage-only and engine system labels. */ + public enum TypeContext { + STORAGE, + ENGINE + } public BaseVertex(Id id) { this.edges = EMPTY_LIST; @@ -50,11 +60,29 @@ public BaseVertex(Id id) { public BaseVertex(Id id, SchemaLabel label) { // Note: - // If vertex is OLAP Vertex, id is the id of the vertex that the olap property belongs to, not including the olap property id. + // An OLAP vertex uses the owning vertex ID without the OLAP property ID. this(id); this.schemaLabel(label); } + public BaseVertex(Id id, SchemaLabel label, TypeContext typeContext) { + this(id, label); + this.typeContext(typeContext); + } + + public TypeContext typeContext() { + return this.typeContext; + } + + public void typeContext(TypeContext typeContext) { + E.checkArgumentNotNull(typeContext, "Vertex type context can't be null"); + this.typeContext = typeContext; + } + + public void encodeNumber(boolean encodeNumber) { + this.encodeNumber = encodeNumber; + } + @Override public String name() { E.checkState(this.schemaLabel().idStrategy() == IdStrategy.PRIMARY_KEY, @@ -73,7 +101,7 @@ public String name() { E.checkState(!propValues.isEmpty(), "Primary values must not be empty " + "(has properties %s)", hasProperties()); - name = SplicingIdGenerator.concatValues(propValues); + name = ConditionQuery.concatValues(propValues); E.checkArgument(!name.isEmpty(), "The value of primary key can't be empty"); } @@ -94,18 +122,38 @@ public List primaryValues() { for (Id pk : primaryKeys) { BaseProperty property = this.getProperty(pk); E.checkState(property != null, - "The value of primary key '%s' can't be null" - /*this.graph().propertyKey(pk).name() complete log*/); - propValues.add(property.serialValue(true)); + "The value of primary key '%s' can't be null", pk); + Object value = property.serialValue(this.encodeNumber); + if ("".equals(value)) { + value = ConditionQuery.INDEX_VALUE_EMPTY; + } + propValues.add(value); } return propValues; } - public void addEdge(BaseEdge edge) { + public boolean addEdge(BaseEdge edge) { if (this.edges == EMPTY_LIST) { this.edges = CollectionFactory.newList(CollectionType.EC); } - this.edges.add(edge); + return this.edges.add(edge); + } + + public void resetEdges(boolean unique) { + this.edges = unique ? CollectionFactory.newSet(CollectionType.EC) : + CollectionFactory.newList(CollectionType.EC); + } + + public BaseEdge removeEdge(BaseEdge edge) { + Iterator iterator = this.edges.iterator(); + while (iterator.hasNext()) { + BaseEdge current = iterator.next(); + if (current.equals(edge)) { + iterator.remove(); + return current; + } + } + return null; } public void correctVertexLabel(VertexLabel correctLabel) { @@ -154,14 +202,18 @@ public boolean olap() { } public HugeType type() { - // For Vertex type, when label is task, return TASK type, convenient for getting storage table information based on type - /* Magic: ~task ~taskresult ~variables*/ - if (schemaLabel() != null && - (schemaLabel().name().equals("~task") || - schemaLabel().name().equals("~taskresult") || - schemaLabel().name().equals("~variables"))) { + if (this.schemaLabel() == null) { + return HugeType.VERTEX; + } + String label = this.schemaLabel().name(); + if ("~task".equals(label) || "~taskresult".equals(label) || + this.typeContext == TypeContext.STORAGE && "~variables".equals(label)) { return HugeType.TASK; } + if (this.typeContext == TypeContext.ENGINE && + ("~server".equals(label) || "~role_data".equals(label))) { + return HugeType.SERVER; + } return HugeType.VERTEX; } } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/Index.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/Index.java index deffcde1ec..0c7c9e401d 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/Index.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/Index.java @@ -37,6 +37,7 @@ import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.DataType; import org.apache.hugegraph.util.E; +import org.apache.hugegraph.util.HashUtil; import org.apache.hugegraph.util.InsertionOrderUtil; import org.apache.hugegraph.util.NumericUtil; @@ -44,6 +45,8 @@ public class Index implements GraphType, Cloneable { + private static final int HUGE_TYPE_CODE_LENGTH = 1; + private final HugeGraphSupplier graph; private Object fieldValues; private final IndexLabel indexLabel; @@ -55,13 +58,7 @@ public class Index implements GraphType, Cloneable { private IdWithExpiredTime elementId; public Index(HugeGraphSupplier graph, IndexLabel indexLabel) { - E.checkNotNull(graph, "graph"); - E.checkNotNull(indexLabel, "label"); - E.checkNotNull(indexLabel.id(), "label id"); - this.graph = graph; - this.indexLabel = indexLabel; - this.elementIds = new LinkedHashSet<>(); - this.fieldValues = null; + this(graph, indexLabel, false); } public Index(HugeGraphSupplier graph, IndexLabel indexLabel, boolean write) { @@ -100,6 +97,10 @@ public Id id() { return formatIndexId(type(), this.indexLabelId(), this.fieldValues()); } + public Id hashId() { + return formatIndexHashId(type(), this.indexLabelId(), this.fieldValues()); + } + public Object fieldValues() { return this.fieldValues; } @@ -118,6 +119,7 @@ public IndexLabel indexLabel() { public IdWithExpiredTime elementIdWithExpiredTime() { if (this.elementIds == null) { + E.checkState(this.elementId != null, "Expect one element id, actual 0"); return this.elementId; } E.checkState(this.elementIds.size() == 1, @@ -144,8 +146,15 @@ public Set elementIds() { public Set expiredElementIds() { long now = this.graph.now(); Set expired = InsertionOrderUtil.newSet(); + if (this.elementIds == null) { + if (this.elementId != null && expired(this.elementId, now)) { + expired.add(this.elementId); + this.elementId = null; + } + return expired; + } for (IdWithExpiredTime id : this.elementIds) { - if (0L < id.expiredTime && id.expiredTime < now) { + if (expired(id, now)) { expired.add(id); } } @@ -153,6 +162,10 @@ public Set expiredElementIds() { return expired; } + private static boolean expired(IdWithExpiredTime id, long now) { + return 0L < id.expiredTime && id.expiredTime < now; + } + public void elementIds(Id elementId) { this.elementIds(elementId, 0L); } @@ -166,7 +179,11 @@ public void elementIds(Id elementId, long expiredTime) { } public void resetElementIds() { - this.elementIds = null; + if (this.elementIds == null) { + this.elementId = null; + } else { + this.elementIds = new LinkedHashSet<>(); + } } public long expiredTime() { @@ -174,17 +191,10 @@ public long expiredTime() { } public boolean hasTtl() { - if ((this.indexLabel() == IndexLabel.label(HugeType.VERTEX) || - this.indexLabel() == IndexLabel.label(HugeType.EDGE)) && - this.expiredTime() > 0) { - // LabelIndex index, if element has expiration time, then index also has TTL - return true; - } - if (this.indexLabel.system()) { return false; } - return this.indexLabel.baseElement().ttl() > 0L; + return this.indexLabel.baseLabel().ttl() > 0L; } public long ttl() { @@ -224,6 +234,14 @@ public String toString() { } + public static Id formatIndexHashId(HugeType type, Id indexLabel, + Object fieldValues) { + E.checkState(!type.isRangeIndex(), + "RangeIndex can't return a hash id"); + String value = fieldValues == null ? "" : fieldValues.toString(); + return formatIndexId(type, indexLabel, HashUtil.hash(value)); + } + public static Id formatIndexId(HugeType type, Id indexLabelId, Object fieldValues) { if (type.isStringIndex()) { @@ -239,12 +257,11 @@ public static Id formatIndexId(HugeType type, Id indexLabelId, */ String strIndexLabelId = IdGenerator.asStoredString(indexLabelId); // Add id prefix according to type - return SplicingIdGenerator.splicing(type.string(), strIndexLabelId, value); + return SplicingIdGenerator.splicing(type.string(), strIndexLabelId, value); } else { assert type.isRangeIndex(); int length = type.isRange4Index() ? 4 : 8; - // 1 is table type, 4 is labelId, length is value - BytesBuffer buffer = BytesBuffer.allocate(1 + 4 + length); + BytesBuffer buffer = BytesBuffer.allocate(HUGE_TYPE_CODE_LENGTH + 4 + length); // Add table type id buffer.write(type.code()); @@ -276,9 +293,7 @@ public static Index parseIndexId(HugeGraphSupplier graph, HugeType type, final int labelLength = 4; E.checkState(id.length > labelLength, "Invalid range index id"); BytesBuffer buffer = BytesBuffer.wrap(id); - // Read the first byte representing the table type - final int hugeTypeCodeLength = 1; - byte[] read = buffer.read(hugeTypeCodeLength); + buffer.read(HUGE_TYPE_CODE_LENGTH); Id label = IdGenerator.of(buffer.readInt()); indexLabel = IndexLabel.label(graph, label); @@ -289,7 +304,8 @@ public static Index parseIndexId(HugeGraphSupplier graph, HugeType type, "Invalid range index field type"); Class clazz = dataType.isNumber() ? dataType.clazz() : DataType.LONG.clazz(); - values = bytes2number(buffer.read(id.length - labelLength - hugeTypeCodeLength), clazz); + values = bytes2number(buffer.read(id.length - labelLength - HUGE_TYPE_CODE_LENGTH), + clazz); } Index index = new Index(graph, indexLabel); index.fieldValues(values); diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/builder/IndexBuilder.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/builder/IndexBuilder.java index cc1483f39e..0929a3b2f0 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/builder/IndexBuilder.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/structure/builder/IndexBuilder.java @@ -22,7 +22,10 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Objects; import java.util.Set; +import java.util.function.Consumer; +import java.util.function.Function; import org.apache.commons.lang3.StringUtils; import org.apache.hugegraph.HugeGraphSupplier; @@ -41,19 +44,26 @@ import org.apache.hugegraph.structure.Index; import org.apache.hugegraph.util.E; import org.apache.hugegraph.util.Log; +import org.apache.hugegraph.util.InsertionOrderUtil; import org.apache.hugegraph.util.NumericUtil; import org.slf4j.Logger; +import com.google.common.collect.ImmutableSet; + public class IndexBuilder { private static final Logger LOG = Log.logger(IndexBuilder.class); private final HugeGraphSupplier graph; private final Analyzer textAnalyzer; + public static final String START_SYMBOL = "("; + public static final String END_SYMBOL = ")"; + public static final String WORD_DELIMITER = "|"; + - public static final String INDEX_SYM_NULL = "\u0001"; - public static final String INDEX_SYM_EMPTY = "\u0002"; - public static final char INDEX_SYM_MAX = '\u0003'; + public static final String INDEX_SYM_NULL = ConditionQuery.INDEX_SYM_NULL; + public static final String INDEX_SYM_EMPTY = ConditionQuery.INDEX_SYM_EMPTY; + public static final char INDEX_SYM_MAX = ConditionQuery.INDEX_SYM_MAX; private static final String TEXT_ANALYZER = "search.text_analyzer"; private static final String TEXT_ANALYZER_MODE = @@ -63,18 +73,21 @@ public class IndexBuilder { private static final String DEFAULT_TEXT_ANALYZER_MODE = "smart"; public IndexBuilder(HugeGraphSupplier graph) { - this.graph = graph; + this(graph, createAnalyzer(graph)); + } - String name = graph.configuration().get(String.class, TEXT_ANALYZER); - String mode = graph.configuration().get(String.class, - TEXT_ANALYZER_MODE); + public IndexBuilder(HugeGraphSupplier graph, Analyzer textAnalyzer) { + this.graph = Objects.requireNonNull(graph, "graph"); + this.textAnalyzer = Objects.requireNonNull(textAnalyzer, "textAnalyzer"); + } + private static Analyzer createAnalyzer(HugeGraphSupplier graph) { + String name = graph.configuration().get(String.class, TEXT_ANALYZER); + String mode = graph.configuration().get(String.class, TEXT_ANALYZER_MODE); name = name == null ? DEFAULT_TEXT_ANALYZER : name; mode = mode == null ? DEFAULT_TEXT_ANALYZER_MODE : mode; - - LOG.debug("Loading text analyzer '{}' with mode '{}' for graph '{}'", - name, mode, graph.name()); - this.textAnalyzer = AnalyzerFactory.analyzer(name, mode); + LOG.debug("Loading text analyzer '{}' with mode '{}' for graph '{}'", name, mode, graph.name()); + return AnalyzerFactory.analyzer(name, mode); } public List buildLabelIndex(BaseElement element) { @@ -107,19 +120,17 @@ public List buildLabelIndex(BaseElement element) { return indexList; } - public List buildVertexOlapIndex(BaseVertex vertex) { - - List indexs = new ArrayList<>(); - - Id pkId = vertex.getProperties().keySet().iterator().next(); - Collection indexLabels = graph.indexLabels(); - for (IndexLabel il : indexLabels) { - if (il.indexFields().contains(pkId)) { - indexs.addAll(this.buildIndex(vertex, il)); + public static void forEachOlapIndexLabelId(BaseVertex vertex, Iterable candidates, + Consumer sink) { + int properties = vertex.sizeOfProperties(); + E.checkArgument(properties == 1, + "Expect only 1 property for olap vertex, but got %s", properties); + Id propertyId = vertex.properties().values().iterator().next().propertyKey().id(); + for (IndexLabel label : candidates) { + if (label.indexFields().contains(propertyId)) { + sink.accept(label.id()); } } - - return indexs; } public List buildVertexIndex(BaseVertex vertex) { @@ -131,9 +142,8 @@ public List buildVertexIndex(BaseVertex vertex) { indexs.addAll(this.buildLabelIndex(vertex)); } - for (Id il : label.indexLabels()) { - indexs.addAll(this.buildIndex(vertex, graph.indexLabel(il))); - } + forEachIndexLabelId(vertex, this.graph::edgeLabel, + id -> this.forEachIndex(vertex, this.graph.indexLabel(id), indexs::add)); return indexs; } @@ -148,13 +158,28 @@ public List buildEdgeIndex(BaseEdge edge) { } - for (Id il : label.indexLabels()) { - indexs.addAll(this.buildIndex(edge, graph.indexLabel(il))); - } + forEachIndexLabelId(edge, this.graph::edgeLabel, + id -> this.forEachIndex(edge, this.graph.indexLabel(id), indexs::add)); return indexs; } + public static void forEachIndexLabelId(BaseElement element, Function edgeLabelLookup, + Consumer sink) { + for (Id id : element.schemaLabel().indexLabels()) { + sink.accept(id); + } + if (element instanceof BaseEdge) { + EdgeLabel label = (EdgeLabel) element.schemaLabel(); + if (label.hasFather()) { + // Preserve child-first order and repeated IDs from the engine's existing loops. + for (Id id : edgeLabelLookup.apply(label.fatherId()).indexLabels()) { + sink.accept(id); + } + } + } + } + /** * Build index(user properties) of vertex or edge * Notice: This method does not use unique index validation to check if the current element already exists @@ -163,10 +188,14 @@ public List buildEdgeIndex(BaseEdge edge) { * @param element the properties owner */ public List buildIndex(BaseElement element, IndexLabel indexLabel) { - E.checkArgument(indexLabel != null, - "Not exist index label with id '%s'", indexLabel.id()); + List indexes = new ArrayList<>(); + this.forEachIndex(element, indexLabel, indexes::add); + return indexes; + } - List indexs = new ArrayList<>(); + public void forEachIndex(BaseElement element, IndexLabel indexLabel, Consumer sink) { + E.checkArgumentNotNull(indexLabel, "Index label cannot be null"); + Objects.requireNonNull(sink, "sink"); // Collect property values of index fields List allPropValues = new ArrayList<>(); @@ -181,18 +210,15 @@ public List buildIndex(BaseElement element, IndexLabel indexLabel) { if (firstNullField == fieldsNum) { firstNullField = allPropValues.size(); } - allPropValues.add(INDEX_SYM_NULL); + allPropValues.add(ConditionQuery.INDEX_VALUE_NULL); } else { - E.checkArgument(!INDEX_SYM_NULL.equals(property.value()), - "Illegal value of index property: '%s'", - INDEX_SYM_NULL); allPropValues.add(property.value()); } } if (firstNullField == 0 && !indexLabel.indexType().isUnique()) { // The property value of first index field is null - return indexs; + return; } // Not build index for record with nullable field (except unique index) List propValues = allPropValues.subList(0, firstNullField); @@ -209,7 +235,7 @@ public List buildIndex(BaseElement element, IndexLabel indexLabel) { E.checkState(propValues.size() == 1, "Expect only one property in range index"); Object value = NumericUtil.convertToNumber(propValues.get(0)); - indexs.add(this.buildIndex(indexLabel, value, element.id(), + sink.accept(this.buildIndex(indexLabel, value, element.id(), expiredTime)); break; case SEARCH: @@ -219,7 +245,7 @@ public List buildIndex(BaseElement element, IndexLabel indexLabel) { Set words = this.segmentWords(propertyValueToString(value)); for (String word : words) { - indexs.add(this.buildIndex(indexLabel, word, element.id(), + sink.accept(this.buildIndex(indexLabel, word, element.id(), expiredTime)); } break; @@ -232,10 +258,9 @@ public List buildIndex(BaseElement element, IndexLabel indexLabel) { */ for (Object propValue : (Collection) propValues.get(0)) { - value = ConditionQuery.concatValuesLimitLength( + value = ConditionQuery.concatValues( propValue); - value = escapeIndexValueIfNeeded((String) value); - indexs.add(this.buildIndex(indexLabel, value, + sink.accept(this.buildIndex(indexLabel, value, element.id(), expiredTime)); } @@ -243,25 +268,23 @@ public List buildIndex(BaseElement element, IndexLabel indexLabel) { for (int i = 0, n = propValues.size(); i < n; i++) { List prefixValues = propValues.subList(0, i + 1); - value = ConditionQuery.concatValuesLimitLength( + value = ConditionQuery.concatValues( prefixValues); - value = escapeIndexValueIfNeeded((String) value); - indexs.add(this.buildIndex(indexLabel, value, + sink.accept(this.buildIndex(indexLabel, value, element.id(), expiredTime)); } } break; case SHARD: - value = ConditionQuery.concatValuesLimitLength(propValues); - value = escapeIndexValueIfNeeded((String) value); - indexs.add(this.buildIndex(indexLabel, value, element.id(), + value = ConditionQuery.concatValues(propValues); + sink.accept(this.buildIndex(indexLabel, value, element.id(), expiredTime)); break; case UNIQUE: - value = ConditionQuery.concatValuesLimitLength(allPropValues); + value = ConditionQuery.concatValues(allPropValues); assert !"".equals(value); - indexs.add(this.buildIndex(indexLabel, value, element.id(), + sink.accept(this.buildIndex(indexLabel, value, element.id(), expiredTime)); break; default: @@ -269,7 +292,6 @@ public List buildIndex(BaseElement element, IndexLabel indexLabel) { "Unknown index type '%s'", indexLabel.indexType())); } - return indexs; } private Index buildIndex(IndexLabel indexLabel, Object propValue, @@ -282,26 +304,6 @@ private Index buildIndex(IndexLabel indexLabel, Object propValue, } - private static String escapeIndexValueIfNeeded(String value) { - for (int i = 0; i < value.length(); i++) { - char ch = value.charAt(i); - if (ch <= INDEX_SYM_MAX) { - /* - * Escape symbols can't be used due to impossible to parse, - * and treat it as illegal value for the origin text property - */ - E.checkArgument(false, "Illegal char '\\u000%s' " + - "in index property: '%s'", (int) ch, - value); - } - } - if (value.isEmpty()) { - // Escape empty String to INDEX_SYM_EMPTY (char `\u0002`) - value = INDEX_SYM_EMPTY; - } - return value; - } - private static boolean hasNullableProp(BaseElement element, Id key) { return element.schemaLabel().nullableKeys().contains(key); } @@ -311,17 +313,20 @@ private static boolean isCollectionIndex(List propValues) { propValues.get(0) instanceof Collection; } - private Set segmentWords(String text) { - return this.textAnalyzer.segment(text); + public Set segmentWords(String text) { + if (text.startsWith(START_SYMBOL) && text.endsWith(END_SYMBOL)) { + String words = text.substring(1, text.length() - 1); + return words.contains(WORD_DELIMITER) ? + ImmutableSet.copyOf(StringUtils.split(words, WORD_DELIMITER)) : ImmutableSet.of(words); + } + Set segments = InsertionOrderUtil.newSet(); + segments.addAll(this.textAnalyzer.segment(text)); + segments.add(text); + segments.removeAll(ConditionQuery.IGNORE_SYM_SET); + return segments; } - private static String propertyValueToString(Object value) { - /* - * Join collection items with white space if the value is Collection, - * or else keep the origin value. - */ - return value instanceof Collection ? - StringUtils.join(((Collection) value).toArray(), " ") : - value.toString(); + public static String propertyValueToString(Object value) { + return value instanceof Collection ? StringUtils.join((Iterable) value, " ") : value.toString(); } } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/HugeType.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/HugeType.java index 2fac93100a..122036ae38 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/HugeType.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/HugeType.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.type; @@ -123,9 +121,8 @@ public boolean isGraph() { } public boolean isVertex() { - // Consider task vertex variable as the same, all used to store HugeVertex structure - return this == HugeType.VERTEX || this == HugeType.TASK || - this == HugeType.VARIABLE || this == HugeType.SERVER; + return this == HugeType.VERTEX || this == HugeType.TASK || this == HugeType.SERVER || + this == HugeType.VARIABLE; } public boolean isEdge() { diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/Idfiable.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/Idfiable.java index c5a58c0eb1..59b8f1e3a3 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/Idfiable.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/Idfiable.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.type; @@ -23,5 +21,5 @@ public interface Idfiable { - public Id id(); + Id id(); } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/Action.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/Action.java index 042594c224..9561d52181 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/Action.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/Action.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.type.define; diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/AggregateType.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/AggregateType.java index e949d4af14..31c0f6212d 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/AggregateType.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/AggregateType.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.type.define; diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/Cardinality.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/Cardinality.java index 9f34a96dee..cf10a5acf7 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/Cardinality.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/Cardinality.java @@ -14,8 +14,6 @@ package org.apache.hugegraph.type.define; -import org.apache.tinkerpop.gremlin.structure.VertexProperty; - /** * The cardinality of the values associated with given key for a particular element. * @@ -39,8 +37,8 @@ public enum Cardinality implements SerialEnum { */ SET(3, "set"); - private byte code = 0; - private String name = null; + private final byte code; + private final String name; static { SerialEnum.register(Cardinality.class); @@ -69,17 +67,4 @@ public boolean multiple() { return this == LIST || this == SET; } - public static Cardinality convert(VertexProperty.Cardinality cardinality) { - switch (cardinality) { - case single: - return SINGLE; - case list: - return LIST; - case set: - return SET; - default: - throw new AssertionError(String.format("Unrecognized cardinality: '%s'", - cardinality)); - } - } } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/CollectionType.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/CollectionType.java index e8ff98ec95..e8a4cd3547 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/CollectionType.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/CollectionType.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.type.define; @@ -62,7 +60,7 @@ public static CollectionType fromCode(byte code) { return FU; default: throw new AssertionError( - "Unsupported collection code: " + code); + "Unsupported collection code: " + code); } } } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/Frequency.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/Frequency.java index 4ebe24867a..3fd1c82332 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/Frequency.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/Frequency.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.type.define; diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/HugeKeys.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/HugeKeys.java index c396e429c5..0e3536b011 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/HugeKeys.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/HugeKeys.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.type.define; @@ -53,7 +51,6 @@ public enum HugeKeys { EDGELABEL_TYPE(87, "edgelabel_type"), PARENT_LABEL(89, "parent_label"), - /* Column names of schema type (PropertyKey) */ DATA_TYPE(120, "data_type"), CARDINALITY(121, "cardinality"), @@ -82,11 +79,10 @@ public enum HugeKeys { SORT_VALUES(206, "sort_values"), PRIMARY_VALUES(207, "primary_values"), EXPIRED_TIME(208, "expired_time"), - SUB_LABEL(211,"sub_label"), + SUB_LABEL(211, "sub_label"), PROPERTY_TYPE(249, "property_type"), - AGGREGATE_PROPERTIES(250, "aggregate_properties"), - ; + AGGREGATE_PROPERTIES(250, "aggregate_properties"); public static final long NORMAL_PROPERTY_ID = 0L; diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/IdStrategy.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/IdStrategy.java index 4149c8db91..da9f51313c 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/IdStrategy.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/IdStrategy.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.type.define; diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/IndexType.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/IndexType.java index 77e59932e7..019ac98df9 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/IndexType.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/IndexType.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.type.define; diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/SerialEnum.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/SerialEnum.java index 337c981a76..3cb59b0450 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/SerialEnum.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/SerialEnum.java @@ -1,65 +1,65 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.type.define; -import org.apache.hugegraph.exception.HugeException; +import org.apache.hugegraph.exception.BackendException; import org.apache.hugegraph.type.HugeType; - import org.apache.hugegraph.util.CollectionUtil; import org.apache.hugegraph.util.E; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Table; public interface SerialEnum { - public byte code(); - -// static Table, Byte, SerialEnum> table = HashBasedTable.create(); + byte code(); - static Map>table =new ConcurrentHashMap<>(); + Table, Byte, SerialEnum> TABLE = HashBasedTable.create(); - public static void register(Class clazz) { + static void register(Class clazz) { Object enums; try { enums = clazz.getMethod("values").invoke(null); } catch (Exception e) { - throw new HugeException("Exception in backend", e); + throw new BackendException(e); } - ConcurrentHashMap map=new ConcurrentHashMap(); - for (SerialEnum e : CollectionUtil.toList(enums)) { - map.put(e.code(), e); + // Resolve enum initialization before locking: class initializers register here too. + synchronized (TABLE) { + for (SerialEnum e : CollectionUtil.toList(enums)) { + TABLE.put(clazz, e.code(), e); + } } - table.put(clazz,map); } - - public static T fromCode(Class clazz, byte code) { - Map clazzMap=table.get(clazz); - if (clazzMap == null) { - SerialEnum.register(clazz); - clazzMap=table.get(clazz); + static T fromCode(Class clazz, byte code) { + boolean registered; + synchronized (TABLE) { + registered = TABLE.containsRow(clazz); + } + if (!registered) { + register(clazz); + } + T value; + synchronized (TABLE) { + @SuppressWarnings("unchecked") + T entry = (T) TABLE.get(clazz, code); + value = entry; } - E.checkArgument(clazzMap != null, "Can't get class registery for %s", - clazz.getSimpleName()); - T value = (T) clazzMap.get(code); if (value == null) { E.checkArgument(false, "Can't construct %s from code %s", clazz.getSimpleName(), code); @@ -67,7 +67,7 @@ public static T fromCode(Class clazz, byte code) { return value; } - public static void registerInternalEnums() { + static void registerInternalEnums() { SerialEnum.register(Action.class); SerialEnum.register(AggregateType.class); SerialEnum.register(Cardinality.class); @@ -78,6 +78,5 @@ public static void registerInternalEnums() { SerialEnum.register(IdStrategy.class); SerialEnum.register(IndexType.class); SerialEnum.register(SchemaStatus.class); -// SerialEnum.register(HugePermission.class); } } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/WriteType.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/WriteType.java index 538b5bc40b..ea1018eabd 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/WriteType.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/WriteType.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.type.define; @@ -33,8 +31,8 @@ public enum WriteType implements SerialEnum { // OLAP property key with range index OLAP_RANGE(4, "olap_range"); - private final byte code; - private final String name; + private byte code = 0; + private String name = null; static { SerialEnum.register(WriteType.class); diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/util/Blob.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/util/Blob.java index 03d82e916e..5b5d8ec6ad 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/util/Blob.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/util/Blob.java @@ -1,29 +1,24 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.util; import java.util.Arrays; -import org.apache.hugegraph.util.Bytes; -import org.apache.hugegraph.util.E; - public class Blob implements Comparable { public static final Blob EMPTY = new Blob(new byte[0]); diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/util/KryoUtil.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/util/KryoUtil.java new file mode 100644 index 0000000000..0be4c6641b --- /dev/null +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/util/KryoUtil.java @@ -0,0 +1,238 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.lang.reflect.Array; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.hugegraph.exception.BackendException; +import org.apache.hugegraph.query.Condition.RelationType; +import org.apache.tinkerpop.shaded.kryo.Kryo; +import org.apache.tinkerpop.shaded.kryo.KryoException; +import org.apache.tinkerpop.shaded.kryo.Registration; +import org.apache.tinkerpop.shaded.kryo.Serializer; +import org.apache.tinkerpop.shaded.kryo.io.Input; +import org.apache.tinkerpop.shaded.kryo.io.Output; +import org.apache.tinkerpop.shaded.kryo.util.DefaultClassResolver; +import org.apache.tinkerpop.shaded.kryo.util.IntMap; +import org.apache.tinkerpop.shaded.kryo.util.MapReferenceResolver; +import org.apache.tinkerpop.shaded.kryo.util.ObjectMap; + +public final class KryoUtil { + + private static final ThreadLocal KRYOS = new ThreadLocal<>(); + + public static Kryo kryo() { + Kryo kryo = KRYOS.get(); + if (kryo != null) { + return kryo; + } + + kryo = new Kryo(new LegacyClassResolver(), new MapReferenceResolver()); + registerSerializers(kryo); + KRYOS.set(kryo); + return kryo; + } + + public static byte[] toKryo(Object value) { + try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); + Output output = new Output(bos, 256)) { + kryo().writeObject(output, value); + output.flush(); + return bos.toByteArray(); + } catch (IOException e) { + throw new BackendException("Failed to serialize: %s", e, value); + } + } + + public static T fromKryo(byte[] value, Class clazz) { + E.checkState(value != null, + "Kryo value can't be null for '%s'", + clazz.getSimpleName()); + return kryo().readObject(new Input(value), clazz); + } + + public static byte[] toKryoWithType(Object value) { + try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); + Output output = new Output(bos, 256)) { + kryo().writeClassAndObject(output, value); + output.flush(); + return bos.toByteArray(); + } catch (IOException e) { + throw new BackendException("Failed to serialize: %s", e, value); + } + } + + @SuppressWarnings("unchecked") + public static T fromKryoWithType(byte[] value) { + E.checkState(value != null, "Kryo value can't be null for object"); + return (T) kryo().readClassAndObject(new Input(value)); + } + + /** Resolve relocated names only when Kryo decodes a class descriptor. */ + private static class LegacyClassResolver extends DefaultClassResolver { + + private static final String LEGACY_RELATION = + "org.apache.hugegraph.backend.query.Condition$RelationType"; + private final Map legacyRelations = new HashMap<>(); + + @Override + protected Registration readName(Input input) { + // Kryo shaded by Gremlin 3.5.1 names contain a varint ID and, on first use, a string. + // Consume once: streamed Input may refill, making position rewind unsafe. + int nameId = input.readVarInt(true); + if (this.nameIdToClass == null) { + this.nameIdToClass = new IntMap<>(); + } + Class type = this.nameIdToClass.get(nameId); + String name = null; + if (type == null) { + name = input.readString(); + type = this.getTypeByName(name); + if (type == null) { + try { + type = Class.forName(name, false, this.kryo.getClassLoader()); + } catch (ClassNotFoundException e) { + throw new KryoException("Unable to find class: " + name, e); + } + if (this.nameToClass == null) { + this.nameToClass = new ObjectMap<>(); + } + this.nameToClass.put(name, type); + } + this.nameIdToClass.put(nameId, type); + } + Registration registration = this.kryo.getRegistration(type); + Registration legacy = this.legacyRelations.get(nameId); + if (legacy == null && name != null) { + Serializer serializer = null; + if (LEGACY_RELATION.equals(name)) { + serializer = new LegacyRelationSerializer(); + } else if (name.startsWith("[") && name.endsWith("L" + LEGACY_RELATION + ";")) { + serializer = new LegacyRelationArraySerializer(registration.getType()); + } + if (serializer != null) { + // Never register this globally: canonical descriptors use other ordinals. + legacy = new Registration(registration.getType(), serializer, NAME); + this.legacyRelations.put(nameId, legacy); + } + } + return legacy != null ? legacy : registration; + } + + @Override + public void reset() { + super.reset(); + this.legacyRelations.clear(); + } + + @Override + protected Class getTypeByName(String name) { + Class type = LegacyClassNames.lookup(name); + return type != null ? type : super.getTypeByName(name); + } + } + + /** The frozen core enum order differs from the existing shared enum order. */ + private static class LegacyRelationSerializer extends Serializer { + + private static final RelationType[] VALUES = { + RelationType.EQ, RelationType.GT, RelationType.GTE, RelationType.LT, + RelationType.LTE, RelationType.NEQ, RelationType.IN, RelationType.NOT_IN, + RelationType.PREFIX, RelationType.TEXT_CONTAINS, RelationType.TEXT_CONTAINS_ANY, + RelationType.CONTAINS, RelationType.CONTAINS_VALUE, RelationType.CONTAINS_KEY, + RelationType.SCAN + }; + + private LegacyRelationSerializer() { + this.setAcceptsNull(true); + this.setImmutable(true); + } + + @Override + public RelationType read(Kryo kryo, Input input, Class type) { + int ordinal = input.readVarInt(true); + if (ordinal == 0) { + return null; + } + if (ordinal < 0 || ordinal > VALUES.length) { + throw new KryoException("Invalid legacy relation ordinal: " + ordinal); + } + return VALUES[ordinal - 1]; + } + + @Override + public void write(Kryo kryo, Output output, RelationType value) { + kryo.getSerializer(RelationType.class).write(kryo, output, value); + } + } + + /** Typed enum arrays omit element descriptors, so retain the enclosing descriptor's codec. */ + private static class LegacyRelationArraySerializer extends Serializer { + + private final Serializer componentSerializer; + + private LegacyRelationArraySerializer(Class type) { + this.setAcceptsNull(true); + Class component = type.getComponentType(); + this.componentSerializer = component == RelationType.class ? new LegacyRelationSerializer() : + new LegacyRelationArraySerializer(component); + } + + @Override + @SuppressWarnings({"unchecked", "rawtypes"}) + public Object[] read(Kryo kryo, Input input, Class type) { + int length = input.readVarInt(true); + if (length == 0) { + return null; + } + Class component = type.getComponentType(); + Object[] values = (Object[]) Array.newInstance(component, length - 1); + kryo.reference(values); + for (int i = 0; i < values.length; i++) { + values[i] = kryo.readObjectOrNull(input, component, (Serializer) this.componentSerializer); + } + return values; + } + + @Override + public void write(Kryo kryo, Output output, Object[] values) { + kryo.getSerializer(values.getClass()).write(kryo, output, values); + } + } + + private static void registerSerializers(Kryo kryo) { + kryo.addDefaultSerializer(UUID.class, new Serializer() { + + @Override + public UUID read(Kryo kryo, Input input, Class c) { + return new UUID(input.readLong(), input.readLong()); + } + + @Override + public void write(Kryo kryo, Output output, UUID uuid) { + output.writeLong(uuid.getMostSignificantBits()); + output.writeLong(uuid.getLeastSignificantBits()); + } + }); + } +} diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/util/LZ4Util.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/util/LZ4Util.java index 98f23b9b29..253d813953 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/util/LZ4Util.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/util/LZ4Util.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.util; @@ -39,25 +37,20 @@ public static BytesBuffer compress(byte[] bytes, int blockSize) { return compress(bytes, blockSize, DEFAULT_BUFFER_RATIO); } - public static BytesBuffer compress(byte[] bytes, int blockSize, - float bufferRatio) { + public static BytesBuffer compress(byte[] bytes, int blockSize, float bufferRatio) { float ratio = bufferRatio <= 0.0F ? DEFAULT_BUFFER_RATIO : bufferRatio; LZ4Factory factory = LZ4Factory.fastestInstance(); LZ4Compressor compressor = factory.fastCompressor(); int initBufferSize = Math.round(bytes.length / ratio); BytesBuffer buf = new BytesBuffer(initBufferSize); - LZ4BlockOutputStream lz4Output = new LZ4BlockOutputStream( - buf, blockSize, compressor); + LZ4BlockOutputStream lz4Output = new LZ4BlockOutputStream(buf, blockSize, compressor); try { lz4Output.write(bytes); lz4Output.close(); } catch (IOException e) { throw new BackendException("Failed to compress", e); } - /* - * If need to perform reading outside the method, - * remember to call forReadWritten() - */ + // If we need to perform reading outside the method, remember to call forReadWritten() return buf; } @@ -65,17 +58,15 @@ public static BytesBuffer decompress(byte[] bytes, int blockSize) { return decompress(bytes, blockSize, DEFAULT_BUFFER_RATIO); } - public static BytesBuffer decompress(byte[] bytes, int blockSize, - float bufferRatio) { + public static BytesBuffer decompress(byte[] bytes, int blockSize, float bufferRatio) { float ratio = bufferRatio <= 0.0F ? DEFAULT_BUFFER_RATIO : bufferRatio; LZ4Factory factory = LZ4Factory.fastestInstance(); LZ4FastDecompressor decompressor = factory.fastDecompressor(); ByteArrayInputStream bais = new ByteArrayInputStream(bytes); int initBufferSize = Math.min(Math.round(bytes.length * ratio), - BytesBuffer.MAX_BUFFER_CAPACITY); + BytesBuffer.maxBufferCapacity()); BytesBuffer buf = new BytesBuffer(initBufferSize); - LZ4BlockInputStream lzInput = new LZ4BlockInputStream(bais, - decompressor); + LZ4BlockInputStream lzInput = new LZ4BlockInputStream(bais, decompressor); int count; byte[] buffer = new byte[blockSize]; try { @@ -86,10 +77,7 @@ public static BytesBuffer decompress(byte[] bytes, int blockSize, } catch (IOException e) { throw new BackendException("Failed to decompress", e); } - /* - * If need to perform reading outside the method, - * remember to call forReadWritten() - */ + // If we need to perform reading outside the method, remember to call forReadWritten() return buf; } } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/util/LegacyClassNames.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/util/LegacyClassNames.java new file mode 100644 index 0000000000..edb791e519 --- /dev/null +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/util/LegacyClassNames.java @@ -0,0 +1,184 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.util; + +import java.lang.reflect.Array; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.apache.hugegraph.backend.BackendColumn; +import org.apache.hugegraph.backend.BinaryId; +import org.apache.hugegraph.backend.Shard; +import org.apache.hugegraph.exception.BackendException; +import org.apache.hugegraph.exception.HugeException; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.id.IdUtil; +import org.apache.hugegraph.id.SplicingIdGenerator; +import org.apache.hugegraph.query.Aggregate; +import org.apache.hugegraph.query.BatchConditionQuery; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.IdPrefixQuery; +import org.apache.hugegraph.query.IdQuery; +import org.apache.hugegraph.query.IdRangeQuery; +import org.apache.hugegraph.query.Query; +import org.apache.hugegraph.query.serializer.AbstractSerializerAdapter; +import org.apache.hugegraph.query.serializer.QueryAdapter; +import org.apache.hugegraph.query.serializer.QueryIdAdapter; +import org.apache.hugegraph.serializer.BytesBuffer; +import org.apache.hugegraph.structure.Index; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.SchemaLabel; +import org.apache.hugegraph.struct.schema.Userdata; +import org.apache.hugegraph.struct.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.builder.SchemaBuilder; +import org.apache.hugegraph.type.GraphType; +import org.apache.hugegraph.type.Indexfiable; +import org.apache.hugegraph.type.Namifiable; +import org.apache.hugegraph.type.Propfiable; +import org.apache.hugegraph.type.Typifiable; + +/** Exact relocated class descriptors accepted by legacy JSON and Kryo decoders. */ +public final class LegacyClassNames { + + private static final Map> LEGACY_CLASSES = legacyClasses(); + + private LegacyClassNames() { + } + + /** Return an exact migrated type, or null so the caller retains its normal loader. */ + public static Class lookup(String name) { + Class type = LEGACY_CLASSES.get(name); + if (type != null) { + return type; + } + // Object arrays use JVM descriptors; keep dimensions and remap + // only an exact, known component name. Primitive arrays use the + // unchanged default resolver. + int dimensions = 0; + while (dimensions < name.length() && name.charAt(dimensions) == '[') { + dimensions++; + if (dimensions > 255) { + return null; + } + } + if (dimensions > 0 && dimensions < name.length() && + name.charAt(dimensions) == 'L' && name.endsWith(";")) { + type = LEGACY_CLASSES.get(name.substring(dimensions + 1, name.length() - 1)); + if (type != null) { + return Array.newInstance(type, new int[dimensions]).getClass(); + } + } + return null; + } + + private static Class declaredClass(Class owner, String name) { + for (Class type : owner.getDeclaredClasses()) { + if (type.getSimpleName().equals(name)) { + return type; + } + } + throw new IllegalStateException("Missing legacy target: " + owner.getName() + "$" + name); + } + + private static Map> legacyClasses() { + Map> classes = new HashMap<>(); + classes.put("org.apache.hugegraph.backend.id.Id", Id.class); + classes.put("org.apache.hugegraph.backend.id.IdGenerator", IdGenerator.class); + classes.put("org.apache.hugegraph.backend.id.IdUtil", IdUtil.class); + classes.put("org.apache.hugegraph.backend.id.SplicingIdGenerator", SplicingIdGenerator.class); + classes.put("org.apache.hugegraph.backend.serializer.BytesBuffer", BytesBuffer.class); + classes.put("org.apache.hugegraph.type.Typeable", Typifiable.class); + classes.put("org.apache.hugegraph.type.Nameable", Namifiable.class); + classes.put("org.apache.hugegraph.type.Propertiable", Propfiable.class); + classes.put("org.apache.hugegraph.type.Indexable", Indexfiable.class); + classes.put("org.apache.hugegraph.backend.id.Id$IdType", Id.IdType.class); + classes.put("org.apache.hugegraph.backend.id.IdGenerator$StringId", IdGenerator.StringId.class); + classes.put("org.apache.hugegraph.backend.id.IdGenerator$LongId", IdGenerator.LongId.class); + classes.put("org.apache.hugegraph.backend.id.IdGenerator$UuidId", IdGenerator.UuidId.class); + classes.put("org.apache.hugegraph.backend.id.IdGenerator$ObjectId", IdGenerator.ObjectId.class); + classes.put("org.apache.hugegraph.backend.id.EdgeId", EdgeId.class); + classes.put("org.apache.hugegraph.backend.serializer.BinaryBackendEntry$BinaryId", BinaryId.class); + classes.put("org.apache.hugegraph.backend.store.BackendEntry$BackendColumn", BackendColumn.class); + classes.put("org.apache.hugegraph.backend.store.Shard", Shard.class); + classes.put("org.apache.hugegraph.HugeException", HugeException.class); + classes.put("org.apache.hugegraph.backend.BackendException", BackendException.class); + classes.put("org.apache.hugegraph.structure.GraphType", GraphType.class); + classes.put("org.apache.hugegraph.schema.SchemaElement", SchemaElement.class); + classes.put("org.apache.hugegraph.schema.SchemaLabel", SchemaLabel.class); + classes.put("org.apache.hugegraph.schema.PropertyKey", PropertyKey.class); + classes.put("org.apache.hugegraph.schema.VertexLabel", VertexLabel.class); + classes.put("org.apache.hugegraph.schema.EdgeLabel", EdgeLabel.class); + classes.put("org.apache.hugegraph.schema.IndexLabel", IndexLabel.class); + classes.put("org.apache.hugegraph.schema.Userdata", Userdata.class); + classes.put("org.apache.hugegraph.schema.SchemaElement$TaskWithSchema", SchemaElement.TaskWithSchema.class); + classes.put("org.apache.hugegraph.schema.SchemaElement$P", SchemaElement.P.class); + classes.put("org.apache.hugegraph.schema.PropertyKey$P", declaredClass(PropertyKey.class, "P")); + classes.put("org.apache.hugegraph.schema.VertexLabel$P", declaredClass(VertexLabel.class, "P")); + classes.put("org.apache.hugegraph.schema.EdgeLabel$P", declaredClass(EdgeLabel.class, "P")); + classes.put("org.apache.hugegraph.schema.IndexLabel$P", declaredClass(IndexLabel.class, "P")); + classes.put("org.apache.hugegraph.schema.PropertyKey$Builder", PropertyKey.Builder.class); + classes.put("org.apache.hugegraph.schema.VertexLabel$Builder", VertexLabel.Builder.class); + classes.put("org.apache.hugegraph.schema.EdgeLabel$Builder", EdgeLabel.Builder.class); + classes.put("org.apache.hugegraph.schema.IndexLabel$Builder", IndexLabel.Builder.class); + classes.put("org.apache.hugegraph.structure.HugeIndex", Index.class); + classes.put("org.apache.hugegraph.structure.HugeIndex$IdWithExpiredTime", Index.IdWithExpiredTime.class); + classes.put("org.apache.hugegraph.schema.builder.SchemaBuilder", SchemaBuilder.class); + classes.put("org.apache.hugegraph.backend.query.serializer.AbstractSerializerAdapter", + AbstractSerializerAdapter.class); + classes.put("org.apache.hugegraph.backend.query.serializer.QueryAdapter", QueryAdapter.class); + classes.put("org.apache.hugegraph.backend.query.serializer.QueryIdAdapter", QueryIdAdapter.class); + classes.put("org.apache.hugegraph.backend.query.Query", Query.class); + classes.put("org.apache.hugegraph.backend.query.Query$Order", Query.Order.class); + classes.put("org.apache.hugegraph.backend.query.Query$OrderType", Query.OrderType.class); + classes.put("org.apache.hugegraph.backend.query.IdQuery", IdQuery.class); + classes.put("org.apache.hugegraph.backend.query.IdQuery$OneIdQuery", IdQuery.OneIdQuery.class); + classes.put("org.apache.hugegraph.backend.query.IdPrefixQuery", IdPrefixQuery.class); + classes.put("org.apache.hugegraph.backend.query.IdRangeQuery", IdRangeQuery.class); + classes.put("org.apache.hugegraph.backend.query.ConditionQuery", ConditionQuery.class); + classes.put("org.apache.hugegraph.backend.query.ConditionQuery$OptimizedType", + ConditionQuery.OptimizedType.class); + classes.put("org.apache.hugegraph.backend.query.ConditionQuery$Element2IndexValueMap", + ConditionQuery.Element2IndexValueMap.class); + classes.put("org.apache.hugegraph.backend.query.ConditionQuery$LeftIndex", ConditionQuery.LeftIndex.class); + classes.put("org.apache.hugegraph.backend.query.BatchConditionQuery", BatchConditionQuery.class); + classes.put("org.apache.hugegraph.backend.query.Aggregate", Aggregate.class); + classes.put("org.apache.hugegraph.backend.query.Aggregate$AggregateFunc", Aggregate.AggregateFunc.class); + classes.put("org.apache.hugegraph.backend.query.Condition", Condition.class); + classes.put("org.apache.hugegraph.backend.query.Condition$ConditionType", Condition.ConditionType.class); + classes.put("org.apache.hugegraph.backend.query.Condition$RelationType", Condition.RelationType.class); + classes.put("org.apache.hugegraph.backend.query.Condition$BinCondition", Condition.BinCondition.class); + classes.put("org.apache.hugegraph.backend.query.Condition$And", Condition.And.class); + classes.put("org.apache.hugegraph.backend.query.Condition$Or", Condition.Or.class); + classes.put("org.apache.hugegraph.backend.query.Condition$Not", Condition.Not.class); + classes.put("org.apache.hugegraph.backend.query.Condition$Relation", Condition.Relation.class); + classes.put("org.apache.hugegraph.backend.query.Condition$SyspropRelation", Condition.SyspropRelation.class); + classes.put("org.apache.hugegraph.backend.query.Condition$FlattenSyspropRelation", + Condition.FlattenSyspropRelation.class); + classes.put("org.apache.hugegraph.backend.query.Condition$UserpropRelation", Condition.UserpropRelation.class); + classes.put("org.apache.hugegraph.backend.query.Condition$RangeConditions", Condition.RangeConditions.class); + return Collections.unmodifiableMap(classes); + } + +} diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/util/StringEncoding.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/util/StringEncoding.java index f4690d430d..fd987a76df 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/util/StringEncoding.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/util/StringEncoding.java @@ -32,18 +32,16 @@ package org.apache.hugegraph.util; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Base64; import java.util.UUID; -import org.apache.hugegraph.util.Bytes; -import org.apache.hugegraph.util.E; -import org.mindrot.jbcrypt.BCrypt; - import org.apache.hugegraph.exception.HugeException; import org.apache.hugegraph.serializer.BytesBuffer; +import org.mindrot.jbcrypt.BCrypt; + import com.google.common.base.CharMatcher; /** @@ -54,8 +52,8 @@ public final class StringEncoding { private static final MessageDigest DIGEST; private static final byte[] BYTES_EMPTY = new byte[0]; + private static final String STRING_EMPTY = ""; private static final int BLOCK_SIZE = 4096; - private static final int BCRYPT_WORK_FACTOR = 10; static { @@ -70,7 +68,7 @@ public final class StringEncoding { private static final Base64.Encoder BASE64_ENCODER = Base64.getEncoder(); private static final Base64.Decoder BASE64_DECODER = Base64.getDecoder(); - // Similar to {@link StringSerializer} + /** Similar to {@link StringSerializer} */ public static int writeAsciiString(byte[] array, int offset, String value) { E.checkArgument(CharMatcher.ascii().matchesAllOf(value), "'%s' must be ASCII string", value); @@ -86,7 +84,8 @@ public static int writeAsciiString(byte[] array, int offset, String value) { assert c <= 127; byte b = (byte) c; if (++i == len) { - b |= 0x80; // End marker + // End marker + b |= 0x80; } array[offset++] = b; } while (i < len); @@ -96,7 +95,7 @@ public static int writeAsciiString(byte[] array, int offset, String value) { public static String readAsciiString(byte[] array, int offset) { StringBuilder sb = new StringBuilder(); - int c = 0; + int c; do { c = 0xFF & array[offset++]; if (c != 0x80) { @@ -113,27 +112,21 @@ public static int getAsciiByteLength(String value) { } public static byte[] encode(String value) { - try { - return value.getBytes("UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new HugeException("Failed to encode string", e); - } + return value.getBytes(StandardCharsets.UTF_8); } public static String decode(byte[] bytes) { - try { - return new String(bytes, "UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new HugeException("Failed to decode string", e); + if (bytes.length == 0) { + return STRING_EMPTY; } + return new String(bytes, StandardCharsets.UTF_8); } public static String decode(byte[] bytes, int offset, int length) { - try { - return new String(bytes, offset, length, "UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new HugeException("Failed to decode string", e); + if (length == 0) { + return STRING_EMPTY; } + return new String(bytes, offset, length, StandardCharsets.UTF_8); } public static String encodeBase64(byte[] bytes) { @@ -152,8 +145,7 @@ public static byte[] compress(String value) { } public static byte[] compress(String value, float bufferRatio) { - BytesBuffer buf = LZ4Util.compress(encode(value), BLOCK_SIZE, - bufferRatio); + BytesBuffer buf = LZ4Util.compress(encode(value), BLOCK_SIZE, bufferRatio); return buf.bytes(); } @@ -172,8 +164,7 @@ public static String hashPassword(String password) { return BCrypt.hashpw(password, BCrypt.gensalt(BCRYPT_WORK_FACTOR)); } - public static boolean checkPassword(String candidatePassword, - String dbPassword) { + public static boolean checkPassword(String candidatePassword, String dbPassword) { return BCrypt.checkpw(candidatePassword, dbPassword); } @@ -194,8 +185,7 @@ public static UUID uuid(String value) { return UUID.fromString(value); } // UUID represented by hex string - E.checkArgument(value.length() == 32, - "Invalid UUID string: %s", value); + E.checkArgument(value.length() == 32, "Invalid UUID string: %s", value); String high = value.substring(0, 16); String low = value.substring(16); return new UUID(Long.parseUnsignedLong(high, 16), diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/Frequency.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/util/UnsafeUtil.java similarity index 52% rename from hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/Frequency.java rename to hugegraph-struct/src/main/java/org/apache/hugegraph/util/UnsafeUtil.java index 3fd1c82332..bc6e492faa 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/Frequency.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/util/UnsafeUtil.java @@ -15,35 +15,33 @@ * limitations under the License. */ -package org.apache.hugegraph.type.define; +package org.apache.hugegraph.util; -public enum Frequency implements SerialEnum { +import java.lang.reflect.Field; - DEFAULT(0, "default"), +import sun.misc.Unsafe; - SINGLE(1, "single"), - - MULTIPLE(2, "multiple"); - - private byte code = 0; - private String name = null; +/** + * Shared access to the Unsafe instance used by native memory and concurrent collections. + */ +public final class UnsafeUtil { - static { - SerialEnum.register(Frequency.class); - } + private static final Unsafe UNSAFE = loadUnsafe(); - Frequency(int code, String name) { - assert code < 256; - this.code = (byte) code; - this.name = name; + private UnsafeUtil() { } - @Override - public byte code() { - return this.code; + public static Unsafe getUnsafe() { + return UNSAFE; } - public String string() { - return this.name; + private static Unsafe loadUnsafe() { + try { + Field field = Unsafe.class.getDeclaredField("theUnsafe"); + field.setAccessible(true); + return (Unsafe) field.get(null); + } catch (ReflectiveOperationException | RuntimeException cause) { + throw new UnsupportedOperationException("Unsafe is not supported on this platform", cause); + } } } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/util/collection/CollectionFactory.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/util/collection/CollectionFactory.java index fb42b8416e..d345e26565 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/util/collection/CollectionFactory.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/util/collection/CollectionFactory.java @@ -1,20 +1,18 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.util.collection; @@ -27,6 +25,8 @@ import java.util.Map; import java.util.Set; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.type.define.CollectionType; import org.apache.hugegraph.util.E; import org.eclipse.collections.api.map.primitive.IntObjectMap; import org.eclipse.collections.api.map.primitive.MutableIntObjectMap; @@ -35,9 +35,6 @@ import org.eclipse.collections.impl.map.mutable.primitive.IntObjectHashMap; import org.eclipse.collections.impl.set.mutable.UnifiedSet; -import org.apache.hugegraph.id.Id; -import org.apache.hugegraph.type.define.CollectionType; - import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; @@ -76,7 +73,7 @@ public static List newList(CollectionType type) { return new ObjectArrayList<>(); default: throw new AssertionError( - "Unsupported collection type: " + type); + "Unsupported collection type: " + type); } } @@ -91,7 +88,7 @@ public static List newList(CollectionType type, return new ObjectArrayList<>(initialCapacity); default: throw new AssertionError( - "Unsupported collection type: " + type); + "Unsupported collection type: " + type); } } @@ -106,7 +103,7 @@ public static List newList(CollectionType type, return new ObjectArrayList<>(collection); default: throw new AssertionError( - "Unsupported collection type: " + type); + "Unsupported collection type: " + type); } } @@ -132,7 +129,7 @@ public static Set newSet(CollectionType type) { return new ObjectOpenHashSet<>(); default: throw new AssertionError( - "Unsupported collection type: " + type); + "Unsupported collection type: " + type); } } @@ -147,7 +144,7 @@ public static Set newSet(CollectionType type, return new ObjectOpenHashSet<>(initialCapacity); default: throw new AssertionError( - "Unsupported collection type: " + type); + "Unsupported collection type: " + type); } } @@ -162,7 +159,7 @@ public static Set newSet(CollectionType type, return new ObjectOpenHashSet<>(collection); default: throw new AssertionError( - "Unsupported collection type: " + type); + "Unsupported collection type: " + type); } } @@ -192,7 +189,7 @@ public static Map newMap(CollectionType type) { return new Object2ObjectOpenHashMap<>(); default: throw new AssertionError( - "Unsupported collection type: " + type); + "Unsupported collection type: " + type); } } @@ -207,7 +204,7 @@ public static Map newMap(CollectionType type, return new Object2ObjectOpenHashMap<>(initialCapacity); default: throw new AssertionError( - "Unsupported collection type: " + type); + "Unsupported collection type: " + type); } } @@ -222,7 +219,7 @@ public static Map newMap(CollectionType type, return new Object2ObjectOpenHashMap<>(map); default: throw new AssertionError( - "Unsupported collection type: " + type); + "Unsupported collection type: " + type); } } @@ -230,18 +227,19 @@ public static MutableIntObjectMap newIntObjectMap() { return new IntObjectHashMap<>(); } - public static MutableIntObjectMap newIntObjectMap(int initialCapacity) { + public static MutableIntObjectMap newIntObjectMap( + int initialCapacity) { return new IntObjectHashMap<>(initialCapacity); } public static MutableIntObjectMap newIntObjectMap( - IntObjectMap map) { + IntObjectMap map) { return new IntObjectHashMap<>(map); } @SuppressWarnings("unchecked") public static MutableIntObjectMap newIntObjectMap( - Object... objects) { + Object... objects) { IntObjectHashMap map = IntObjectHashMap.newMap(); E.checkArgument(objects.length % 2 == 0, "Must provide even arguments for " + @@ -261,4 +259,22 @@ public IdSet newIdSet() { public static IdSet newIdSet(CollectionType type) { return new IdSet(type); } + + public static IntSet newIntSet() { + /* + * Resume to the old version like this: + * return concurrent ? new IntHashSet().asSynchronized() : + * new IntHashSet(); + */ + return new IntSet.IntSetBySegments(Integer.MAX_VALUE); + } + + public static IntMap newIntMap() { + /* + * Resume to the old version like this: + * return concurrent ? new IntIntHashMap().asSynchronized() : + * new IntIntHashMap(); + */ + return new IntMap.IntMapBySegments(Integer.MAX_VALUE); + } } diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/util/collection/IdSet.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/util/collection/IdSet.java index d77ddfb047..7f977b252b 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/util/collection/IdSet.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/util/collection/IdSet.java @@ -1,36 +1,33 @@ /* - * Copyright 2017 HugeGraph Authors - * * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.apache.hugegraph.util.collection; +import java.util.AbstractSet; +import java.util.Iterator; +import java.util.Set; + import org.apache.hugegraph.id.Id; import org.apache.hugegraph.id.IdGenerator; -import org.apache.hugegraph.type.define.CollectionType; - import org.apache.hugegraph.iterator.ExtendableIterator; +import org.apache.hugegraph.type.define.CollectionType; import org.eclipse.collections.api.iterator.MutableLongIterator; import org.eclipse.collections.impl.set.mutable.primitive.LongHashSet; -import java.util.AbstractSet; -import java.util.Iterator; -import java.util.Set; - public class IdSet extends AbstractSet { private final LongHashSet numberIds; @@ -67,8 +64,8 @@ public boolean contains(Object object) { @Override public Iterator iterator() { return new ExtendableIterator<>( - this.nonNumberIds.iterator(), - new EcIdIterator(this.numberIds.longIterator())); + this.nonNumberIds.iterator(), + new EcLongIdIterator(this.numberIds.longIterator())); } @Override @@ -94,11 +91,11 @@ public void clear() { this.nonNumberIds.clear(); } - private static class EcIdIterator implements Iterator { + private static class EcLongIdIterator implements Iterator { private final MutableLongIterator iterator; - public EcIdIterator(MutableLongIterator iter) { + public EcLongIdIterator(MutableLongIterator iter) { this.iterator = iter; } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/collection/IntIterator.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/util/collection/IntIterator.java similarity index 100% rename from hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/collection/IntIterator.java rename to hugegraph-struct/src/main/java/org/apache/hugegraph/util/collection/IntIterator.java diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/collection/IntMap.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/util/collection/IntMap.java similarity index 100% rename from hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/collection/IntMap.java rename to hugegraph-struct/src/main/java/org/apache/hugegraph/util/collection/IntMap.java diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/collection/IntSet.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/util/collection/IntSet.java similarity index 99% rename from hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/collection/IntSet.java rename to hugegraph-struct/src/main/java/org/apache/hugegraph/util/collection/IntSet.java index c40b731d8c..48cfe75f85 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/collection/IntSet.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/util/collection/IntSet.java @@ -22,11 +22,10 @@ import java.util.function.Function; import org.apache.hugegraph.util.E; +import org.apache.hugegraph.util.UnsafeUtil; import org.eclipse.collections.api.collection.primitive.MutableIntCollection; import org.eclipse.collections.impl.set.mutable.primitive.IntHashSet; -import io.netty.util.internal.shaded.org.jctools.util.UnsafeAccess; - public interface IntSet { boolean add(int key); @@ -549,7 +548,7 @@ public boolean concurrent() { } int CPUS = Runtime.getRuntime().availableProcessors(); - sun.misc.Unsafe UNSAFE = UnsafeAccess.UNSAFE; + sun.misc.Unsafe UNSAFE = UnsafeUtil.getUnsafe(); long MOD64 = 0x3fL; int DIV64 = 6; diff --git a/hugegraph-struct/src/test/java/org/apache/hugegraph/SchemaDriverTest.java b/hugegraph-struct/src/test/java/org/apache/hugegraph/SchemaDriverTest.java deleted file mode 100644 index e5398c2fb1..0000000000 --- a/hugegraph-struct/src/test/java/org/apache/hugegraph/SchemaDriverTest.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hugegraph; - -import java.lang.reflect.Field; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; - -import org.apache.hugegraph.exception.HugeException; -import org.apache.hugegraph.exception.NotAllowException; -import org.apache.hugegraph.pd.client.KvClient; -import org.apache.hugegraph.pd.client.PDConfig; -import org.apache.hugegraph.pd.common.PDException; -import org.apache.hugegraph.pd.grpc.kv.WatchResponse; -import org.junit.Assert; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -public class SchemaDriverTest { - - private AtomicReference instance; - private SchemaDriver previousInstance; - - @Before - public void setUp() throws Exception { - this.instance = instanceReference(); - this.previousInstance = this.instance.getAndSet(null); - } - - @After - public void tearDown() { - this.instance.set(this.previousInstance); - } - - @Test - public void testDestroyClosesOwnedKvClient() { - TrackingKvClient client = new TrackingKvClient(); - SchemaDriver driver = new SchemaDriver(client, 10, 60_000L); - this.instance.set(driver); - - try { - SchemaDriver.destroy(); - - Assert.assertTrue(client.closed); - Assert.assertNull(SchemaDriver.getInstance()); - } finally { - client.close(); - } - } - - @Test - public void testDestroyUnpublishesInstanceBeforeClosingResources() throws Exception { - BlockingCloseKvClient client = new BlockingCloseKvClient(); - SchemaDriver driver = new SchemaDriver(client, 10, 60_000L); - this.instance.set(driver); - Thread destroyThread = new Thread(SchemaDriver::destroy, "schema-driver-destroy"); - try { - destroyThread.start(); - client.awaitCloseStarted(); - - Assert.assertNull(SchemaDriver.getInstance()); - } finally { - client.allowClose.countDown(); - destroyThread.join(5000L); - client.close(); - } - - Assert.assertFalse(destroyThread.isAlive()); - Assert.assertTrue(client.closed); - } - - @Test - public void testInitDoesNotWaitForDestroyCleanup() throws Exception { - BlockingCloseKvClient client = new BlockingCloseKvClient(); - SchemaDriver driver = new SchemaDriver(client, 10, 60_000L); - this.instance.set(driver); - AtomicReference initFailure = new AtomicReference<>(); - CountDownLatch initFinished = new CountDownLatch(1); - Thread destroyThread = new Thread(SchemaDriver::destroy, "schema-driver-destroy"); - Thread initThread = new Thread(() -> { - try { - SchemaDriver.init(PDConfig.of("127.0.0.1:8686"), 10, 60_000L); - } catch (Throwable throwable) { - initFailure.set(throwable); - } finally { - initFinished.countDown(); - } - }, "schema-driver-init"); - boolean initCompletedDuringCleanup; - try { - destroyThread.start(); - client.awaitCloseStarted(); - initThread.start(); - initCompletedDuringCleanup = initFinished.await(1L, TimeUnit.SECONDS); - } finally { - client.allowClose.countDown(); - destroyThread.join(5000L); - initThread.join(5000L); - client.close(); - } - - Assert.assertTrue(initCompletedDuringCleanup); - Assert.assertTrue(initFailure.get() instanceof NotAllowException); - Assert.assertFalse(destroyThread.isAlive()); - Assert.assertFalse(initThread.isAlive()); - } - - @Test - public void testConcurrentDestroyWaitsForCleanup() throws Exception { - BlockingCloseKvClient client = new BlockingCloseKvClient(); - SchemaDriver driver = new SchemaDriver(client, 10, 60_000L); - this.instance.set(driver); - CountDownLatch secondDestroyStarted = new CountDownLatch(1); - CountDownLatch secondDestroyReturned = new CountDownLatch(1); - Thread firstDestroy = new Thread(SchemaDriver::destroy, "schema-driver-destroy-first"); - Thread secondDestroy = new Thread(() -> { - secondDestroyStarted.countDown(); - SchemaDriver.destroy(); - secondDestroyReturned.countDown(); - }, "schema-driver-destroy-second"); - boolean returnedBeforeCleanup; - try { - firstDestroy.start(); - client.awaitCloseStarted(); - secondDestroy.start(); - Assert.assertTrue(secondDestroyStarted.await(5L, TimeUnit.SECONDS)); - returnedBeforeCleanup = secondDestroyReturned.await(500L, TimeUnit.MILLISECONDS); - } finally { - client.allowClose.countDown(); - firstDestroy.join(5000L); - secondDestroy.join(5000L); - client.close(); - } - - Assert.assertFalse(returnedBeforeCleanup); - Assert.assertFalse(firstDestroy.isAlive()); - Assert.assertFalse(secondDestroy.isAlive()); - } - - @Test - public void testConstructorFailureClosesOwnedKvClient() { - FailingListenKvClient client = new FailingListenKvClient(); - - try { - new SchemaDriver(client, 10, 60_000L); - Assert.fail("SchemaDriver construction should fail"); - } catch (HugeException expected) { - Assert.assertEquals(2, client.listenCalls); - Assert.assertTrue(client.closed); - } finally { - client.close(); - } - } - - @SuppressWarnings("unchecked") - private static AtomicReference instanceReference() throws Exception { - Field field = SchemaDriver.class.getDeclaredField("INSTANCE"); - field.setAccessible(true); - return (AtomicReference) field.get(null); - } - - private static class TrackingKvClient extends KvClient { - - protected volatile boolean closed; - - TrackingKvClient() { - super(PDConfig.of("127.0.0.1:8686")); - } - - @Override - public void listen(String key, Consumer consumer) throws PDException { - // Avoid opening a real PD stream while constructing SchemaDriver. - } - - @Override - public void close() { - this.closed = true; - super.close(); - } - } - - private static class BlockingCloseKvClient extends TrackingKvClient { - - private final CountDownLatch closeStarted = new CountDownLatch(1); - private final CountDownLatch allowClose = new CountDownLatch(1); - - @Override - public void close() { - this.closeStarted.countDown(); - try { - this.allowClose.await(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new IllegalStateException("Client close was interrupted", e); - } - super.close(); - } - - private void awaitCloseStarted() throws InterruptedException { - Assert.assertTrue(this.closeStarted.await(5L, TimeUnit.SECONDS)); - } - } - - private static class FailingListenKvClient extends TrackingKvClient { - - private int listenCalls; - - @Override - public void listen(String key, Consumer consumer) throws PDException { - if (++this.listenCalls == 2) { - throw new PDException(-1, "listener startup failed"); - } - } - } -} diff --git a/hugegraph-struct/src/test/java/org/apache/hugegraph/backend/BackendColumnTest.java b/hugegraph-struct/src/test/java/org/apache/hugegraph/backend/BackendColumnTest.java new file mode 100644 index 0000000000..a9f1a8b379 --- /dev/null +++ b/hugegraph-struct/src/test/java/org/apache/hugegraph/backend/BackendColumnTest.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.backend; + +import java.util.HashSet; +import java.util.Set; + +import org.junit.Assert; +import org.junit.Test; + +public class BackendColumnTest { + + @Test + public void testColumnsWithEqualBytesHaveEqualHashes() { + BackendColumn first = BackendColumn.of(new byte[]{1, 2}, new byte[]{3, 4}); + BackendColumn same = BackendColumn.of(new byte[]{1, 2}, new byte[]{3, 4}); + Assert.assertEquals(first, same); + Assert.assertEquals(first.hashCode(), same.hashCode()); + Set columns = new HashSet<>(); + columns.add(first); + Assert.assertTrue(columns.contains(same)); + Assert.assertFalse(columns.add(same)); + Assert.assertNotEquals(first, BackendColumn.of(new byte[]{1, 2}, new byte[]{5})); + } + + @Test + public void testSharedColumnRetainsMutableByteArraysAndNameOrdering() { + byte[] name = new byte[]{1}; + byte[] value = new byte[]{2}; + BackendColumn column = BackendColumn.of(name, value); + Assert.assertSame(name, column.name); + Assert.assertSame(value, column.value); + Assert.assertTrue(column.compareTo(BackendColumn.of(new byte[]{2}, value)) < 0); + Assert.assertEquals(0, column.compareTo(BackendColumn.of(new byte[]{1}, new byte[]{3}))); + Assert.assertTrue(column.compareTo(null) > 0); + name[0] = 3; + Assert.assertEquals(3, column.name[0]); + } +} diff --git a/hugegraph-struct/src/test/java/org/apache/hugegraph/compatibility/LegacyCoreCodecTest.java b/hugegraph-struct/src/test/java/org/apache/hugegraph/compatibility/LegacyCoreCodecTest.java new file mode 100644 index 0000000000..0e1f4ad525 --- /dev/null +++ b/hugegraph-struct/src/test/java/org/apache/hugegraph/compatibility/LegacyCoreCodecTest.java @@ -0,0 +1,487 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.compatibility; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.BufferUnderflowException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.Properties; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Locale; +import java.util.UUID; + +import org.apache.hugegraph.backend.BinaryId; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.query.Aggregate.AggregateFunc; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.serializer.BytesBuffer; +import org.apache.hugegraph.serializer.BytesBuffer.IndexColumnName; +import org.apache.hugegraph.serializer.BytesBuffer.IndexExpiryLayout; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.type.HugeType; +import org.apache.hugegraph.type.define.Cardinality; +import org.apache.hugegraph.type.define.DataType; +import org.apache.hugegraph.type.define.Directions; +import org.apache.hugegraph.type.define.HugeKeys; +import org.apache.hugegraph.util.Blob; +import org.apache.hugegraph.util.Bytes; +import org.junit.Assert; +import org.junit.Test; + +import com.google.gson.JsonParser; + +/** + * Golden fixtures were written by the pre-consolidation core, not this module. + * See compatibility/2f827d6e8/README.md for provenance and coverage limits. + */ +public class LegacyCoreCodecTest { + + private static final String FIXTURES = "/compatibility/2f827d6e8/"; + + @Test + public void testLegacyLongIdsAndVarLongs() throws IOException { + long[] values = {Long.MIN_VALUE, -16385L, -16384L, -129L, -128L, -1L, + 0L, 1L, 127L, 128L, 16383L, 16384L, Long.MAX_VALUE}; + for (long value : values) { + byte[] idBytes = fixture("id.long." + value); + BytesBuffer reader = BytesBuffer.wrap(idBytes); + Id actual = reader.readId(); + Assert.assertEquals(IdGenerator.of(value), actual); + Assert.assertEquals(0, reader.remaining()); + Assert.assertArrayEquals(idBytes, + BytesBuffer.allocate(64).writeId(actual).bytes()); + + byte[] varLongBytes = fixture("vlong." + value); + reader = BytesBuffer.wrap(varLongBytes); + Assert.assertEquals(value, reader.readVLong()); + Assert.assertEquals(0, reader.remaining()); + Assert.assertArrayEquals(varLongBytes, + BytesBuffer.allocate(64).writeVLong(value).bytes()); + } + } + + @Test + public void testLegacyVarInts() throws IOException { + int[] values = {Integer.MIN_VALUE, -129, -1, 0, 127, 128, 16383, 16384, + Integer.MAX_VALUE}; + for (int value : values) { + byte[] expected = fixture("vint." + value); + BytesBuffer reader = BytesBuffer.wrap(expected); + Assert.assertEquals(value, reader.readVInt()); + Assert.assertEquals(0, reader.remaining()); + Assert.assertArrayEquals(expected, + BytesBuffer.allocate(64).writeVInt(value).bytes()); + } + } + + @Test + public void testLegacyTextAndUuidIds() throws IOException { + assertId("id.text", IdGenerator.of("alice")); + assertId("id.unicode", IdGenerator.of("顶点😀")); + assertId("id.uuid", IdGenerator.of( + UUID.fromString("01234567-89ab-cdef-0123-456789abcdef"))); + } + + @Test + public void testLegacyTextIdWidthBoundaries() throws IOException { + for (int length : new int[]{1, 64, 65, 256, 257, 16384}) { + String key = "id.text.length." + length; + Id expected = IdGenerator.of("x".repeat(length)); + assertId(key, expected); + // The historical struct boolean overload used the same layout. + byte[] legacy = fixture(key); + BytesBuffer reader = BytesBuffer.wrap(legacy); + Assert.assertEquals(expected, reader.readId(true)); + Assert.assertEquals(0, reader.remaining()); + Assert.assertArrayEquals(legacy, + BytesBuffer.allocate(64).writeId(expected, true).bytes()); + } + Assert.assertThrows(IllegalArgumentException.class, + () -> BytesBuffer.allocate(64).writeId(IdGenerator.of(""))); + Assert.assertThrows(IllegalArgumentException.class, + () -> BytesBuffer.allocate(64).writeId(IdGenerator.of("x".repeat(16385)))); + } + + @Test + public void testLegacyEdgeIds() throws IOException { + assertEdge("edge.out", new EdgeId(IdGenerator.of("alice"), Directions.OUT, + IdGenerator.of(3L), IdGenerator.of(4L), "2026!x", IdGenerator.of(99L))); + assertEdge("edge.in", new EdgeId(IdGenerator.of(99L), Directions.IN, + IdGenerator.of(3L), IdGenerator.of(4L), "2026!x", IdGenerator.of("alice"))); + } + + @Test + public void testLegacyEdgeKeyPrefixAndSortSkipping() throws IOException { + byte[] legacy = fixture("edge.out"); + Id owner = IdGenerator.of("alice"); + byte[] withoutOwner = Arrays.copyOfRange(legacy, fixture("id.text").length, legacy.length); + BytesBuffer prefixless = BytesBuffer.wrap(withoutOwner); + EdgeId edge = prefixless.readEdgeId(false, owner); + Assert.assertEquals(owner, edge.ownerVertexId()); + Assert.assertEquals(Directions.OUT, edge.direction()); + Assert.assertEquals(IdGenerator.of(3L), edge.edgeLabelId()); + Assert.assertEquals(IdGenerator.of(4L), edge.subLabelId()); + Assert.assertEquals("2026!x", edge.sortValues()); + Assert.assertEquals(IdGenerator.of(99L), edge.otherVertexId()); + Assert.assertEquals(0, prefixless.remaining()); + BytesBuffer skipped = BytesBuffer.wrap(legacy); + EdgeId withoutSort = (EdgeId) skipped.readEdgeIdSkipSortValues(); + Assert.assertEquals(owner, withoutSort.ownerVertexId()); + Assert.assertEquals("", withoutSort.sortValues()); + Assert.assertEquals(IdGenerator.of(99L), withoutSort.otherVertexId()); + Assert.assertEquals(0, skipped.remaining()); + } + + @Test + public void testLegacyIndexKeyLayoutBoundaries() throws IOException { + Properties rows = new Properties(); + try (InputStream input = this.getClass().getResourceAsStream(FIXTURES + "core-rows.properties")) { + Assert.assertNotNull(input); + rows.load(input); + } + byte[] timed = Bytes.fromHex(rows.getProperty("index.secondary.column.0.name")); + byte[] indexPrefix = Bytes.fromHex(rows.getProperty("index.secondary.id")); + byte[] prefixless = Arrays.copyOfRange(timed, indexPrefix.length, timed.length); + BytesBuffer withPrefix = BytesBuffer.wrap(timed); + IndexColumnName parsed = withPrefix.readIndexColumnName(HugeType.SECONDARY_INDEX, true, + IndexExpiryLayout.REQUIRED); + Assert.assertArrayEquals(Arrays.copyOf(indexPrefix, indexPrefix.length - 1), parsed.indexId().asBytes()); + Assert.assertEquals(IdGenerator.of(1L), parsed.elementId()); + Assert.assertEquals(1609459260000L, parsed.expiredTime()); + Assert.assertTrue(parsed.hasExpiredTime()); + Assert.assertEquals(0, withPrefix.remaining()); + BytesBuffer noPrefix = BytesBuffer.wrap(prefixless); + parsed = noPrefix.readIndexColumnName(HugeType.SECONDARY_INDEX, false, IndexExpiryLayout.REQUIRED); + Assert.assertNull(parsed.indexId()); + Assert.assertEquals(IdGenerator.of(1L), parsed.elementId()); + Assert.assertEquals(1609459260000L, parsed.expiredTime()); + Assert.assertEquals(0, noPrefix.remaining()); + byte[] bare = Bytes.fromHex(rows.getProperty("index.system.column.0.name")); + parsed = BytesBuffer.wrap(bare).readIndexColumnName(HugeType.VERTEX_LABEL_INDEX, true, + IndexExpiryLayout.OPTIONAL); + Assert.assertEquals(0L, parsed.expiredTime()); + Assert.assertFalse(parsed.hasExpiredTime()); + byte[] withZero = Arrays.copyOf(bare, bare.length + 1); + withZero[bare.length] = fixture("vlong.0")[0]; + parsed = BytesBuffer.wrap(withZero).readIndexColumnName(HugeType.VERTEX_LABEL_INDEX, true, + IndexExpiryLayout.OPTIONAL); + Assert.assertEquals(0L, parsed.expiredTime()); + Assert.assertTrue(parsed.hasExpiredTime()); + Assert.assertThrows(BufferUnderflowException.class, + () -> BytesBuffer.wrap(bare).readIndexColumnName( + HugeType.VERTEX_LABEL_INDEX, true, IndexExpiryLayout.REQUIRED)); + } + + @Test + public void testLegacyScalarProperties() throws IOException { + assertProperty(DataType.BOOLEAN, true); + assertProperty(DataType.BYTE, (byte) -7); + assertProperty(DataType.INT, -123456); + assertProperty(DataType.LONG, Long.MIN_VALUE); + assertProperty(DataType.FLOAT, 1.25f); + assertProperty(DataType.DOUBLE, -123.125d); + assertProperty(DataType.DATE, new Date(1609459200123L)); + assertProperty(DataType.TEXT, "属性😀\u0000"); + assertProperty(DataType.BLOB, Blob.wrap(new byte[]{0, -1, 1, 127, -128})); + assertProperty(DataType.UUID, UUID.fromString("01234567-89ab-cdef-0123-456789abcdef")); + } + + @Test + public void testLegacyKryoProperties() throws IOException { + assertProperty(DataType.OBJECT, new ArrayList<>(Arrays.asList("legacy", 7, true))); + assertProperty(DataType.UNKNOWN, "legacy-object"); + } + + @Test + public void testLegacySchemaDrivenProperties() throws IOException { + assertSchemaProperty("single", Cardinality.SINGLE, 7); + assertSchemaProperty("list", Cardinality.LIST, Arrays.asList(7, -1, 7)); + assertSchemaProperty("set", Cardinality.SET, + new LinkedHashSet<>(Arrays.asList(7, -1))); + } + + @Test + public void testLegacyIndexIds() throws IOException { + assertIndex("index.string", HugeType.SECONDARY_INDEX, + "label!alice".getBytes(StandardCharsets.UTF_8)); + assertIndex("index.int", HugeType.RANGE_INT_INDEX, + new byte[]{(byte) 160, 0, 0, 0, 3, (byte) 128, 0, 0, 7}); + assertIndex("index.long", HugeType.RANGE_LONG_INDEX, + new byte[]{(byte) 162, 0, 0, 0, 3, (byte) 128, 0, 0, 0, 0, 0, 0, 7}); + } + + @Test + public void testLegacyTaggedScalarProperties() throws IOException { + assertTaggedScalar(DataType.BOOLEAN, true); + assertTaggedScalar(DataType.BYTE, (byte) -7); + assertTaggedScalar(DataType.INT, -123456); + assertTaggedScalar(DataType.LONG, Long.MIN_VALUE); + assertTaggedScalar(DataType.FLOAT, 1.25f); + assertTaggedScalar(DataType.DOUBLE, -123.125d); + assertTaggedScalar(DataType.DATE, new Date(1609459200123L)); + assertTaggedScalar(DataType.TEXT, "属性😀\u0000"); + assertTaggedScalar(DataType.BLOB, Blob.wrap(new byte[]{0, -1, 1, 127, -128})); + assertTaggedScalar(DataType.UUID, + UUID.fromString("01234567-89ab-cdef-0123-456789abcdef")); + } + + @Test + public void testLegacyTaggedCollectionProperties() throws IOException { + assertTaggedProperty("list", DataType.INT, Cardinality.LIST, + Arrays.asList(7, -1, 7), "schema.list"); + assertTaggedProperty("set", DataType.INT, Cardinality.SET, + new LinkedHashSet<>(Arrays.asList(7, -1)), "schema.set"); + } + + @Test + public void testSkippingLegacyPropertiesPreservesTrailingTtl() throws IOException { + for (DataType type : DataType.values()) { + this.assertSkipProperty("property." + type.name(), type, Cardinality.SINGLE); + byte[] legacy = type == DataType.UNKNOWN || type == DataType.OBJECT ? null : + fixture("struct-tagged-properties.hex", type.name()); + if (legacy != null) { + BytesBuffer buffer = withTrailingMarker(legacy); + buffer.skipProperty(); + assertTrailingMarker(buffer); + } + } + this.assertSkipProperty("schema.list", DataType.INT, Cardinality.LIST); + this.assertSkipProperty("schema.set", DataType.INT, Cardinality.SET); + // An existing core Kryo limitation must not prevent skipping data: + // this collection's baseline writer can encode it, but its reader + // cannot instantiate Arrays$ArrayList. + this.assertSkipProperty("property.OBJECT_UNSUPPORTED_COLLECTION", + DataType.OBJECT, Cardinality.SINGLE); + } + + private void assertSkipProperty(String name, DataType type, Cardinality cardinality) + throws IOException { + PropertyKey key = new PropertyKey(null, IdGenerator.of(101L), "legacy"); + key.dataType(type); + key.cardinality(cardinality); + BytesBuffer buffer = withTrailingMarker(fixture(name)); + buffer.skipSchemaProperty(key); + assertTrailingMarker(buffer); + } + + private static BytesBuffer withTrailingMarker(byte[] bytes) { + BytesBuffer buffer = BytesBuffer.allocate(bytes.length + 16); + buffer.write(bytes); + buffer.writeUInt8(0x55); + buffer.writeVLong(1609459260000L); + return buffer.forReadWritten(); + } + + private static void assertTrailingMarker(BytesBuffer buffer) { + Assert.assertEquals(0x55, buffer.readUInt8()); + Assert.assertEquals(1609459260000L, buffer.readVLong()); + Assert.assertEquals(0, buffer.remaining()); + } + + @Test + public void testLegacyVertexQuery() throws IOException, ParseException { + // Legacy JSON date strings represent wall time in the process time + // zone. Do not mutate it after Gson's date adapter initialization. + ConditionQuery query = ConditionQuery.fromBytes(jsonFixture("core-query.json.txt")); + Assert.assertEquals(HugeType.VERTEX, query.resultType()); + Assert.assertEquals(7L, query.offset()); + Assert.assertEquals(19L, query.limit()); + Assert.assertEquals(IdGenerator.of(3L), query.condition(HugeKeys.LABEL)); + Condition.Relation range = query.relation(IdGenerator.of(11L)); + Assert.assertEquals(Condition.RelationType.GTE, range.relation()); + Assert.assertEquals(18, range.value()); + Assert.assertNull(query.condition(IdGenerator.of(11L))); + Assert.assertEquals(Arrays.asList(20L, 30L), query.condition(IdGenerator.of(12L))); + Date expectedDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.ROOT) + .parse("2021-01-01 00:00:00.123"); + Assert.assertEquals(expectedDate, query.condition(IdGenerator.of(13L))); + Assert.assertEquals(5, query.conditions().size()); + Condition disjunction = query.conditions().stream() + .filter(c -> c instanceof Condition.Or) + .findFirst().orElseThrow(AssertionError::new); + Assert.assertTrue(disjunction.test("alice")); + Assert.assertTrue(disjunction.test("bob")); + Assert.assertFalse(disjunction.test("charlie")); + } + + @Test + public void testLegacyEdgeQuery() throws IOException { + ConditionQuery query = ConditionQuery.fromBytes(jsonFixture("core-edge-query.json.txt")); + Assert.assertEquals(HugeType.EDGE, query.resultType()); + Assert.assertEquals(IdGenerator.of("alice"), query.condition(HugeKeys.OWNER_VERTEX)); + Assert.assertEquals(Directions.OUT, query.condition(HugeKeys.DIRECTION)); + Assert.assertEquals(IdGenerator.of(3L), query.condition(HugeKeys.LABEL)); + Assert.assertEquals("AQIDBA==", query.page()); + Assert.assertEquals(5L, query.limit()); + Assert.assertEquals(3, query.conditions().size()); + } + + @Test + public void testLegacyCountAggregateQuery() throws IOException { + byte[] payload = jsonFixture("core-count-query.json.txt"); + ConditionQuery query = ConditionQuery.fromBytes(payload); + Assert.assertEquals(AggregateFunc.COUNT, query.aggregateNotNull().func()); + Assert.assertTrue(query.aggregateNotNull().countAll()); + Assert.assertNull(query.aggregateNotNull().column()); + Assert.assertEquals(5L, query.aggregateNotNull() + .reduce(Arrays.asList(2L, 3L).iterator()).longValue()); + assertAggregateJson(payload, query.bytes()); + } + + @Test + public void testLegacyAvgAggregateQuery() throws IOException { + byte[] payload = jsonFixture("core-avg-query.json.txt"); + ConditionQuery query = ConditionQuery.fromBytes(payload); + Assert.assertEquals(AggregateFunc.AVG, query.aggregateNotNull().func()); + Assert.assertFalse(query.aggregateNotNull().countAll()); + Assert.assertEquals("age", query.aggregateNotNull().column()); + Assert.assertEquals(25d, query.aggregateNotNull() + .reduce(Arrays.asList(20, 30).iterator()).doubleValue(), + 0d); + Assert.assertEquals(IdGenerator.of(3L), query.condition(HugeKeys.LABEL)); + assertAggregateJson(payload, query.bytes()); + } + + private static void assertAggregateJson(byte[] legacy, byte[] current) { + Assert.assertEquals(JsonParser.parseString(new String(legacy, StandardCharsets.UTF_8)) + .getAsJsonObject().get("aggregate"), + JsonParser.parseString(new String(current, StandardCharsets.UTF_8)) + .getAsJsonObject().get("aggregate")); + } + + private static void assertId(String key, Id expected) throws IOException { + byte[] legacy = fixture(key); + BytesBuffer reader = BytesBuffer.wrap(legacy); + Assert.assertEquals(expected, reader.readId()); + Assert.assertEquals(0, reader.remaining()); + Assert.assertArrayEquals(legacy, BytesBuffer.allocate(64).writeId(expected).bytes()); + } + + private static void assertEdge(String key, EdgeId expected) throws IOException { + byte[] legacy = fixture(key); + BytesBuffer reader = BytesBuffer.wrap(legacy); + EdgeId actual = (EdgeId) reader.readEdgeId(); + Assert.assertEquals(expected.ownerVertexId(), actual.ownerVertexId()); + Assert.assertEquals(expected.direction(), actual.direction()); + Assert.assertEquals(expected.edgeLabelId(), actual.edgeLabelId()); + Assert.assertEquals(expected.subLabelId(), actual.subLabelId()); + Assert.assertEquals(expected.sortValues(), actual.sortValues()); + Assert.assertEquals(expected.otherVertexId(), actual.otherVertexId()); + Assert.assertEquals(0, reader.remaining()); + Assert.assertArrayEquals(legacy, BytesBuffer.allocate(128).writeEdgeId(expected).bytes()); + } + + private static void assertProperty(DataType type, Object expected) throws IOException { + byte[] legacy = fixture("property." + type.name()); + BytesBuffer reader = BytesBuffer.wrap(legacy); + Assert.assertEquals(expected, reader.readProperty(type)); + Assert.assertEquals(0, reader.remaining()); + BytesBuffer writer = BytesBuffer.allocate(128); + writer.writeProperty(type, expected); + Assert.assertArrayEquals(legacy, writer.bytes()); + } + + private static void assertSchemaProperty(String name, Cardinality cardinality, + Object expected) throws IOException { + PropertyKey key = new PropertyKey(null, IdGenerator.of(101L), "legacy"); + key.dataType(DataType.INT); + key.cardinality(cardinality); + byte[] legacy = fixture("schema." + name); + BytesBuffer reader = BytesBuffer.wrap(legacy); + Assert.assertEquals(expected, reader.readSchemaProperty(key)); + Assert.assertEquals(0, reader.remaining()); + Assert.assertEquals(cardinality, key.cardinality()); + Assert.assertEquals(DataType.INT, key.dataType()); + Assert.assertArrayEquals(legacy, + BytesBuffer.allocate(64).writeSchemaProperty(key, expected).bytes()); + } + + private static void assertIndex(String name, HugeType type, byte[] expected) + throws IOException { + byte[] legacy = fixture(name); + BytesBuffer reader = BytesBuffer.wrap(legacy); + Assert.assertArrayEquals(expected, reader.readIndexId(type).asBytes()); + Assert.assertEquals(0, reader.remaining()); + Assert.assertArrayEquals(legacy, BytesBuffer.allocate(64) + .writeIndexId(new BinaryId(expected, null), type) + .bytes()); + } + + private static void assertTaggedScalar(DataType type, Object expected) throws IOException { + assertTaggedProperty(type.name(), type, Cardinality.SINGLE, + expected, "property." + type.name()); + } + + private static void assertTaggedProperty(String name, DataType type, + Cardinality cardinality, Object expected, + String rawKey) throws IOException { + byte[] legacy = fixture("struct-tagged-properties.hex", name); + byte[] raw = fixture(rawKey); + Assert.assertEquals(raw.length + 1, legacy.length); + Assert.assertArrayEquals(raw, Arrays.copyOfRange(legacy, 1, legacy.length)); + PropertyKey key = new PropertyKey(null, IdGenerator.of(101L), "legacy"); + // Tagged readers must recover metadata, even when the caller starts + // with metadata different from the encoded property. + key.dataType(DataType.UNKNOWN); + key.cardinality(Cardinality.SET); + BytesBuffer reader = BytesBuffer.wrap(legacy); + Assert.assertEquals(expected, reader.readProperty(key)); + Assert.assertEquals(0, reader.remaining()); + Assert.assertEquals(type, key.dataType()); + Assert.assertEquals(cardinality, key.cardinality()); + Assert.assertArrayEquals(legacy, + BytesBuffer.allocate(128).writeProperty(key, expected).bytes()); + } + + private static byte[] fixture(String key) throws IOException { + return fixture("core-codecs.hex", key); + } + + private static byte[] fixture(String file, String key) throws IOException { + Properties properties = new Properties(); + try (InputStream input = LegacyCoreCodecTest.class.getResourceAsStream( + FIXTURES + file)) { + Assert.assertNotNull("Missing codec fixture resource", input); + properties.load(input); + } + String hex = properties.getProperty(key); + Assert.assertNotNull("Missing legacy fixture " + key, hex); + return Bytes.fromHex(hex); + } + + private static byte[] jsonFixture(String name) throws IOException { + try (InputStream input = LegacyCoreCodecTest.class.getResourceAsStream(FIXTURES + name)) { + Assert.assertNotNull("Missing legacy fixture " + name, input); + String text = new String(input.readAllBytes(), StandardCharsets.UTF_8); + Assert.assertTrue("Missing fixture license prolog", text.startsWith("/*")); + int payloadStart = text.indexOf("*/\n") + 3; + Assert.assertTrue("Missing fixture payload", payloadStart > 3); + Assert.assertTrue("Missing fixture file newline", text.endsWith("\n")); + return text.substring(payloadStart, text.length() - 1).getBytes(StandardCharsets.UTF_8); + } + } +} diff --git a/hugegraph-struct/src/test/java/org/apache/hugegraph/compatibility/LegacyCoreRowCodecTest.java b/hugegraph-struct/src/test/java/org/apache/hugegraph/compatibility/LegacyCoreRowCodecTest.java new file mode 100644 index 0000000000..0e48381070 --- /dev/null +++ b/hugegraph-struct/src/test/java/org/apache/hugegraph/compatibility/LegacyCoreRowCodecTest.java @@ -0,0 +1,323 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.compatibility; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Proxy; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Properties; + +import org.apache.commons.lang3.tuple.Pair; +import org.apache.hugegraph.HugeGraphSupplier; +import org.apache.hugegraph.backend.BackendColumn; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.type.define.Directions; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.serializer.BinaryElementSerializer; +import org.apache.hugegraph.serializer.DirectBinarySerializer; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; +import org.apache.hugegraph.structure.BaseEdge; +import org.apache.hugegraph.structure.BaseElement; +import org.apache.hugegraph.structure.BaseVertex; +import org.apache.hugegraph.structure.Index; +import org.apache.hugegraph.type.HugeType; +import org.apache.hugegraph.type.define.Cardinality; +import org.apache.hugegraph.type.define.DataType; +import org.apache.hugegraph.type.define.Frequency; +import org.apache.hugegraph.type.define.IndexType; +import org.apache.hugegraph.type.define.WriteType; +import org.apache.hugegraph.util.Bytes; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** Test complete rows written by the pinned pre-consolidation BinarySerializer. */ +public class LegacyCoreRowCodecTest { + + private final BinaryElementSerializer serializer = new BinaryElementSerializer(); + private final DirectBinarySerializer direct = new DirectBinarySerializer(); + private final Map properties = new HashMap<>(); + private final Map vertices = new HashMap<>(); + private final Map edges = new HashMap<>(); + private final Map indexes = new HashMap<>(); + private Properties rows; + private HugeGraphSupplier graph; + private long expiry; + + @Before + public void prepare() throws IOException { + this.rows = new Properties(); + try (InputStream input = this.getClass().getResourceAsStream( + "/compatibility/2f827d6e8/core-rows.properties")) { + Assert.assertNotNull(input); + this.rows.load(input); + } + this.expiry = Long.parseLong(this.rows.getProperty("expiry")); + this.graph = (HugeGraphSupplier) Proxy.newProxyInstance( + HugeGraphSupplier.class.getClassLoader(), new Class[]{HugeGraphSupplier.class}, + (proxy, method, args) -> { + switch (method.getName()) { + case "now": return Long.parseLong(this.rows.getProperty("now")); + case "name": + case "spaceGraphName": return "legacy-fixture"; + case "propertyKey": return this.properties.get(((Id) args[0]).asLong()); + case "vertexLabel": + case "vertexLabelOrNone": return this.vertices.get(((Id) args[0]).asLong()); + case "edgeLabel": + case "edgeLabelOrNone": return this.edges.get(((Id) args[0]).asLong()); + case "indexLabel": return this.indexes.get(((Id) args[0]).asLong()); + default: throw new AssertionError("Unexpected supplier call: " + method); + } + }); + this.property(1L, "age", DataType.INT, Cardinality.SINGLE); + this.property(2L, "scores", DataType.INT, Cardinality.LIST); + this.property(3L, "groups", DataType.INT, Cardinality.SET); + this.property(9L, "rank", DataType.INT, Cardinality.SINGLE) + .writeType(WriteType.OLAP_COMMON); + this.property(16L, "weight", DataType.LONG, Cardinality.SINGLE); + this.property(17L, "name", DataType.TEXT, Cardinality.SINGLE); + this.vertexLabel(4L, "person", 60000L); + this.vertexLabel(10L, "timeless", 0L); + this.edgeLabel(5L, "knows", 60000L); + this.edgeLabel(11L, "untimed", 0L); + this.indexLabel(6L, IndexType.SECONDARY, 4L); + this.indexLabel(7L, IndexType.RANGE_INT, 4L); + this.indexLabel(8L, IndexType.RANGE_LONG, 4L); + this.indexLabel(12L, IndexType.SECONDARY, 10L); + this.indexLabel(13L, IndexType.RANGE_INT, 10L); + this.indexLabel(14L, IndexType.RANGE_LONG, 10L); + this.indexLabel(15L, IndexType.SECONDARY, 4L); + } + + @Test + public void testLegacyVertexRowsAndDirectTtl() { + for (String name : new String[]{"vertex", "vertex.untimed"}) { + BackendColumn column = this.column(name); + BaseVertex vertex = this.serializer.parseSchemaVertex(this.graph, column, null); + this.assertProperties(vertex); + Assert.assertEquals(name.endsWith("untimed") ? 3L : 1L, vertex.id().asLong()); + long expectedExpiry = name.endsWith("untimed") ? 0L : this.expiry; + Assert.assertEquals(expectedExpiry, vertex.expiredTime()); + Assert.assertArrayEquals(column.value, this.serializer.formatSchemaVertexValue(vertex)); + Assert.assertEquals(expectedExpiry, this.direct.parseSchemaVertex( + this.graph, column.name, column.value).expiredTime()); + } + } + + @Test + public void testLegacyEdgeRowsAndDirectTtl() { + for (String name : new String[]{"edge.out", "edge.in", "edge.untimed"}) { + BackendColumn column = this.column(name); + BaseEdge edge = this.serializer.parseSchemaEdge(this.graph, column, null, true); + this.assertProperties(edge); + Assert.assertEquals(!name.equals("edge.in"), edge.isOutEdge()); + Assert.assertEquals(name.equals("edge.in") ? 2L : 1L, edge.ownerVertexId().asLong()); + long expectedExpiry = name.endsWith("untimed") ? 0L : this.expiry; + Assert.assertEquals(expectedExpiry, edge.expiredTime()); + Assert.assertArrayEquals(column.name, this.serializer.formatEdgeName(edge)); + Assert.assertArrayEquals(column.value, this.serializer.formatSchemaEdgeValue(edge)); + Assert.assertEquals(expectedExpiry, this.direct.parseSchemaEdge( + this.graph, column.name, column.value).expiredTime()); + } + } + + @Test + public void testLegacyVertexWithOlapMergedRow() { + BaseVertex vertex = this.serializer.parseSchemaVertexFromCols( + this.graph, this.column("vertex"), this.column("olap")); + Assert.assertEquals(1L, vertex.id().asLong()); + Assert.assertEquals(this.expiry, vertex.expiredTime()); + this.assertProperties(vertex); + Assert.assertEquals(42, (int) vertex.getPropertyValue(IdGenerator.of(9L))); + } + + @Test + public void testLegacyStandaloneOlapRow() { + BaseVertex vertex = this.serializer.parseSchemaVertexOlap( + this.graph, this.column("olap"), null); + Assert.assertEquals(1L, vertex.id().asLong()); + Assert.assertEquals(42, (int) vertex.getPropertyValue(IdGenerator.of(9L))); + Assert.assertEquals(0L, vertex.expiredTime()); + } + + @Test + public void testSharedIndexWriterRetainsLegacyCoreBytes() { + for (String name : new String[]{"index.secondary", "index.int", "index.long", + "index.secondary.untimed", "index.int.untimed", + "index.long.untimed", "index.hashed", "index.system", "index.system.edge"}) { + BackendColumn legacy = this.column(name); + Index decoded = this.serializer.parseSchemaIndex(this.graph, legacy); + BackendColumn current = this.serializer.writeSchemaIndex(decoded); + Assert.assertArrayEquals(name + " key", legacy.name, current.name); + Assert.assertNotNull(name + " persistent value", current.value); + Assert.assertArrayEquals(name + " value", legacy.value, current.value); + } + } + + @Test + public void testOriginalStoreIndexTtlRows() throws IOException { + Properties legacy = new Properties(); + try (InputStream input = this.getClass().getResourceAsStream( + "/compatibility/2f827d6e8/store-index-rows.properties")) { + Assert.assertNotNull(input); + legacy.load(input); + } + for (String name : new String[]{"secondary", "int", "long", "system", "system.edge"}) { + BackendColumn column = BackendColumn.of(Bytes.fromHex(legacy.getProperty(name + ".name")), + Bytes.fromHex(legacy.getProperty(name + ".value"))); + Index decoded = this.serializer.parseSchemaIndex(this.graph, column); + Id expectedElement = name.equals("system.edge") ? edgeElementId() : IdGenerator.of(1L); + Assert.assertEquals(expectedElement, decoded.elementId()); + Assert.assertEquals(this.expiry, decoded.expiredTime()); + Assert.assertEquals(this.expiry, this.direct.parseSchemaIndex( + this.graph, column.name, column.value).expiredTime()); + // The still-supported tagged writer must also retain old Store bytes. + BackendColumn tagged = this.serializer.writeIndex(decoded); + Assert.assertArrayEquals(column.name, tagged.name); + Assert.assertArrayEquals(column.value, tagged.value); + if (name.startsWith("system")) { + BackendColumn current = this.serializer.writeSchemaIndex(decoded); + Assert.assertArrayEquals(column.name, current.name); + Assert.assertArrayEquals(column.value, current.value); + Assert.assertFalse(decoded.hasTtl()); + } + } + } + + @Test + public void testPositiveLabelExpiryUsesStableStorageKeyAndCoreFlag() throws IOException { + Properties storage = new Properties(); + try (InputStream input = this.getClass().getResourceAsStream( + "/compatibility/2f827d6e8/store-index-rows.properties")) { + Assert.assertNotNull(input); + storage.load(input); + } + for (String name : new String[]{"system", "system.edge"}) { + HugeType base = name.endsWith("edge") ? HugeType.EDGE : HugeType.VERTEX; + Id elementId = name.endsWith("edge") ? edgeElementId() : IdGenerator.of(1L); + Index index = new Index(this.graph, IndexLabel.label(base), true); + index.fieldValues(name.endsWith("edge") ? 5L : 4L); + index.elementIds(elementId, this.expiry); + Assert.assertFalse(index.hasTtl()); + BackendColumn oldCore = this.column("index." + name); + BackendColumn core = this.serializer.formatSchemaIndex(index.type(), index.indexLabelId(), + index.fieldValues(), elementId, true, false, this.expiry); + Assert.assertArrayEquals(oldCore.name, core.name); + Assert.assertNotNull(core.value); + Assert.assertArrayEquals(oldCore.value, core.value); + BackendColumn stored = this.serializer.writeSchemaIndex(index); + Assert.assertArrayEquals(Bytes.fromHex(storage.getProperty(name + ".name")), stored.name); + Assert.assertArrayEquals(Bytes.fromHex(storage.getProperty(name + ".value")), stored.value); + Assert.assertArrayEquals("Storage append retains Core elimination key", core.name, stored.name); + Assert.assertEquals(this.expiry, this.direct.parseSchemaIndex( + this.graph, stored.name, stored.value).expiredTime()); + Assert.assertEquals(Long.valueOf(this.expiry), this.serializer.storedLabelIndexExpiredTime( + index.type(), true, stored.value)); + Assert.assertNull(this.serializer.storedLabelIndexExpiredTime(index.type(), false, stored.value)); + Assert.assertNull(this.serializer.storedLabelIndexExpiredTime( + HugeType.SECONDARY_INDEX, true, stored.value)); + Assert.assertNull(this.serializer.storedLabelIndexExpiredTime( + index.type(), true, Arrays.copyOf(stored.value, stored.value.length + 1))); + } + } + + private static Id edgeElementId() { + return new EdgeId(IdGenerator.of(1L), Directions.OUT, IdGenerator.of(5L), + IdGenerator.of(5L), "2026!x", IdGenerator.of(2L)); + } + + @Test + public void testLegacyIndexRowsAndDirectTtl() { + for (String name : new String[]{"index.secondary", "index.int", "index.long", + "index.secondary.untimed", "index.int.untimed", + "index.long.untimed", "index.hashed", "index.system", "index.system.edge"}) { + BackendColumn column = this.column(name); + Index index = this.serializer.parseSchemaIndex(this.graph, column); + Assert.assertEquals(name.equals("index.system.edge") ? edgeElementId() : IdGenerator.of(1L), + index.elementId()); + long expectedExpiry = name.endsWith("untimed") || name.startsWith("index.system") ? + 0L : this.expiry; + Assert.assertEquals(expectedExpiry, index.expiredTime()); + Assert.assertEquals(expectedExpiry, this.direct.parseSchemaIndex( + this.graph, column.name, column.value).expiredTime()); + if (name.equals("index.hashed")) { + Assert.assertEquals("long-field-".repeat(20), index.fieldValues()); + } else if (name.startsWith("index.secondary")) { + Assert.assertEquals("alice", index.fieldValues()); + } else if (name.startsWith("index.int")) { + Assert.assertEquals(7, index.fieldValues()); + } else if (name.startsWith("index.long")) { + Assert.assertEquals(7L, index.fieldValues()); + } + } + } + + private void assertProperties(BaseElement element) { + Assert.assertEquals(7, (int) element.getPropertyValue(IdGenerator.of(1L))); + Assert.assertEquals(Arrays.asList(7, -1, 7), element.getPropertyValue(IdGenerator.of(2L))); + Assert.assertEquals(new HashSet<>(Arrays.asList(7, -1)), + element.getPropertyValue(IdGenerator.of(3L))); + } + + private BackendColumn column(String name) { + return BackendColumn.of(Bytes.fromHex(this.rows.getProperty(name + ".column.0.name")), + Bytes.fromHex(this.rows.getProperty(name + ".column.0.value"))); + } + + private PropertyKey property(long id, String name, DataType type, Cardinality cardinality) { + PropertyKey key = new PropertyKey(this.graph, IdGenerator.of(id), name); + key.dataType(type); + key.cardinality(cardinality); + this.properties.put(id, key); + return key; + } + + private void vertexLabel(long id, String name, long ttl) { + VertexLabel label = new VertexLabel(this.graph, IdGenerator.of(id), name); + label.ttl(ttl); + label.properties(IdGenerator.of(1L), IdGenerator.of(2L), IdGenerator.of(3L)); + this.vertices.put(id, label); + } + + private void edgeLabel(long id, String name, long ttl) { + EdgeLabel label = new EdgeLabel(this.graph, IdGenerator.of(id), name); + label.ttl(ttl); + label.frequency(Frequency.MULTIPLE); + label.links(Pair.of(IdGenerator.of(4L), IdGenerator.of(4L))); + label.properties(IdGenerator.of(1L), IdGenerator.of(2L), IdGenerator.of(3L)); + this.edges.put(id, label); + } + + private void indexLabel(long id, IndexType type, long baseId) { + IndexLabel label = new IndexLabel(this.graph, IdGenerator.of(id), "index-" + id); + label.indexType(type); + label.baseType(HugeType.VERTEX_LABEL); + label.baseValue(IdGenerator.of(baseId)); + label.indexFields(IdGenerator.of(type == IndexType.RANGE_LONG ? 16L : + type == IndexType.SECONDARY ? 17L : 1L)); + this.indexes.put(id, label); + } +} diff --git a/hugegraph-struct/src/test/java/org/apache/hugegraph/compatibility/LegacyKryoCompatibilityTest.java b/hugegraph-struct/src/test/java/org/apache/hugegraph/compatibility/LegacyKryoCompatibilityTest.java new file mode 100644 index 0000000000..b9b56b44c8 --- /dev/null +++ b/hugegraph-struct/src/test/java/org/apache/hugegraph/compatibility/LegacyKryoCompatibilityTest.java @@ -0,0 +1,448 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.compatibility; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.apache.hugegraph.backend.BackendColumn; +import org.apache.hugegraph.backend.BinaryId; +import org.apache.hugegraph.backend.Shard; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.id.IdUtil; +import org.apache.hugegraph.id.SplicingIdGenerator; +import org.apache.hugegraph.query.Aggregate.AggregateFunc; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.ConditionQuery; +import org.apache.hugegraph.query.Query; +import org.apache.hugegraph.query.serializer.AbstractSerializerAdapter; +import org.apache.hugegraph.query.serializer.QueryAdapter; +import org.apache.hugegraph.query.serializer.QueryIdAdapter; +import org.apache.hugegraph.serializer.BytesBuffer; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.Userdata; +import org.apache.hugegraph.struct.schema.SchemaElement; +import org.apache.hugegraph.struct.schema.VertexLabel; +import org.apache.hugegraph.struct.schema.builder.SchemaBuilder; +import org.apache.hugegraph.structure.Index; +import org.apache.hugegraph.type.GraphType; +import org.apache.hugegraph.type.Indexfiable; +import org.apache.hugegraph.type.Namifiable; +import org.apache.hugegraph.type.Propfiable; +import org.apache.hugegraph.type.Typifiable; +import org.apache.hugegraph.type.define.DataType; +import org.apache.hugegraph.util.Bytes; +import org.apache.hugegraph.util.KryoUtil; +import org.apache.hugegraph.util.LegacyClassNames; +import org.apache.tinkerpop.shaded.kryo.Kryo; +import org.apache.tinkerpop.shaded.kryo.KryoException; +import org.apache.tinkerpop.shaded.kryo.io.Input; +import org.apache.tinkerpop.shaded.kryo.io.Output; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** Original core OBJECT payloads and original default-reader receipts. */ +public class LegacyKryoCompatibilityTest { + + private Properties fixtures; + + @Before + public void prepare() throws IOException { + this.fixtures = new Properties(); + try (InputStream input = this.getClass().getResourceAsStream( + "/compatibility/2f827d6e8/core-kryo-objects.properties")) { + Assert.assertNotNull(input); + this.fixtures.load(input); + } + } + + @Test + public void testReadableRelocatedEnumsAndClassLiteral() { + this.assertValue("aggregate_func", AggregateFunc.AVG); + this.assertValue("relation_type", Condition.RelationType.GTE); + this.assertValue("condition_type", Condition.ConditionType.OR); + this.assertValue("query_order", Query.Order.DESC); + this.assertValue("query_order_type", Query.OrderType.ORDER_STRICT); + this.assertValue("optimized_type", ConditionQuery.OptimizedType.INDEX_FILTER); + this.assertValue("id_type", Id.IdType.UUID); + this.assertValue("graph_type_class", GraphType.class); + } + + @Test + public void testReadableRelocatedUserdata() { + Object decoded = this.read("userdata"); + Assert.assertEquals(Userdata.class, decoded.getClass()); + Assert.assertEquals(expectedUserdata(), decoded); + Assert.assertEquals(decoded, roundTrip(decoded)); + } + + @Test + public void testReadableRelocatedArrayTypes() { + Object ids = this.read("id_array"); + Assert.assertEquals(Id[].class, ids.getClass()); + Assert.assertArrayEquals(new Id[]{null}, (Id[]) ids); + Assert.assertArrayEquals((Id[]) ids, (Id[]) roundTrip(ids)); + Object matrix = this.read("id_matrix"); + Assert.assertEquals(Id[][].class, matrix.getClass()); + Assert.assertArrayEquals(new Id[][]{new Id[]{null}, new Id[0]}, (Id[][]) matrix); + Assert.assertArrayEquals((Id[][]) matrix, (Id[][]) roundTrip(matrix)); + Object shards = this.read("shard_array"); + Assert.assertEquals(Shard[].class, shards.getClass()); + Assert.assertArrayEquals(new Shard[]{null}, (Shard[]) shards); + Assert.assertArrayEquals((Shard[]) shards, (Shard[]) roundTrip(shards)); + Object schemas = this.read("schema_array"); + Assert.assertEquals(PropertyKey[].class, schemas.getClass()); + Assert.assertArrayEquals(new PropertyKey[]{null}, (PropertyKey[]) schemas); + Assert.assertArrayEquals((PropertyKey[]) schemas, (PropertyKey[]) roundTrip(schemas)); + } + + @Test + public void testReadableNestedClassAndArrayGraphs() { + Object classes = this.read("class_list"); + Assert.assertEquals(expectedClasses(), classes); + Assert.assertEquals(classes, roundTrip(classes)); + Object nested = this.read("nested"); + assertNested(nested); + assertNested(roundTrip(nested)); + } + + @Test + public void testReadableRenamedContractAndUtilityClassLiterals() { + List> expected = Arrays.asList(Namifiable.class, Typifiable.class, + Indexfiable.class, Propfiable.class, IdUtil.class, + SplicingIdGenerator.class, SchemaBuilder.class, + AbstractSerializerAdapter.class, QueryAdapter.class, + QueryIdAdapter.class); + Object decoded = this.read("contract_classes"); + Assert.assertEquals(expected, decoded); + Assert.assertEquals(expected, roundTrip(decoded)); + } + + @Test + public void testReadableLegacyBackendColumn() { + this.assertValue("backend_column_class", BackendColumn.class); + Object decoded = this.read("backend_column"); + assertColumn(decoded); + assertColumn(roundTrip(decoded)); + Object array = this.read("backend_column_array"); + Assert.assertEquals(BackendColumn[].class, array.getClass()); + Assert.assertEquals(2, ((BackendColumn[]) array).length); + assertColumn(((BackendColumn[]) array)[0]); + Assert.assertNull(((BackendColumn[]) array)[1]); + assertColumn(((BackendColumn[]) roundTrip(array))[0]); + } + + @Test + public void testReadableNestedSchemaClassLiteralsAndArrays() { + List> expected = Arrays.asList(SchemaElement.TaskWithSchema.class, + nestedClass(PropertyKey.class, "P"), nestedClass(VertexLabel.class, "P"), + nestedClass(EdgeLabel.class, "P"), nestedClass(IndexLabel.class, "P"), + SchemaElement.P.class, PropertyKey.Builder.class, VertexLabel.Builder.class, + EdgeLabel.Builder.class, IndexLabel.Builder.class); + Object classes = this.read("schema_nested_classes"); + Assert.assertEquals(expected, classes); + Assert.assertEquals(expected, roundTrip(classes)); + List arrays = (List) this.read("schema_nested_arrays"); + List written = (List) roundTrip(arrays); + for (int i = 0; i < expected.size(); i++) { + Class arrayClass = Array.newInstance(expected.get(i), 1).getClass(); + Assert.assertEquals(arrayClass, arrays.get(i).getClass()); + Assert.assertEquals(arrayClass, written.get(i).getClass()); + Assert.assertEquals(1, Array.getLength(arrays.get(i))); + Assert.assertNull(Array.get(arrays.get(i), 0)); + } + } + + @Test + public void testReadableRelocatedIndexClassLiteralsAndArrays() { + List> expected = Arrays.asList(Index.class, Index.IdWithExpiredTime.class); + Object classes = this.read("index_classes"); + Assert.assertEquals(expected, classes); + Assert.assertEquals(expected, roundTrip(classes)); + Object indexes = this.read("index_array"); + Assert.assertEquals(Index[].class, indexes.getClass()); + Assert.assertArrayEquals(new Index[]{null}, (Index[]) indexes); + Assert.assertArrayEquals((Index[]) indexes, (Index[]) roundTrip(indexes)); + Object expires = this.read("expiry_id_array"); + Assert.assertEquals(Index.IdWithExpiredTime[].class, expires.getClass()); + Assert.assertArrayEquals(new Index.IdWithExpiredTime[]{null}, (Index.IdWithExpiredTime[]) expires); + Assert.assertArrayEquals((Index.IdWithExpiredTime[]) expires, + (Index.IdWithExpiredTime[]) roundTrip(expires)); + } + + @Test + public void testLegacyArrayDescriptorDimensionBoundary() { + String legacy = "org.apache.hugegraph.backend.id.Id"; + Assert.assertEquals(Id.class, LegacyClassNames.lookup(legacy)); + Assert.assertEquals(Id[].class, LegacyClassNames.lookup("[L" + legacy + ";")); + Class limit = LegacyClassNames.lookup("[".repeat(255) + "L" + legacy + ";"); + int dimensions = 0; + while (limit.isArray()) { + dimensions++; + limit = limit.getComponentType(); + } + Assert.assertEquals(255, dimensions); + Assert.assertEquals(Id.class, limit); + Assert.assertNull(LegacyClassNames.lookup("[".repeat(256) + "L" + legacy + ";")); + Assert.assertNull(LegacyClassNames.lookup("[".repeat(5000) + "L" + legacy + ";")); + Assert.assertNull(LegacyClassNames.lookup("[Lexample.UserClass;")); + Assert.assertNull(LegacyClassNames.lookup("[I")); + } + + @Test + public void testOriginalUnsupportedInstancesKeepConstructorPolicy() { + for (String name : new String[]{"long_id", "string_id", "uuid_id", "edge_id", "binary_id", + "shard", "property_key", "vertex_label", "edge_label", + "index_label", "expiry_id", "unsupported_arrays_list"}) { + Assert.assertEquals(name, "false", this.fixtures.getProperty(name + ".baseline_readable")); + Assert.assertTrue(this.fixtures.getProperty(name + ".baseline_error") + .contains("missing no-arg constructor")); + // Reset failure state before and after a read, keeping independent + // fixtures independent without changing the instantiation strategy. + KryoUtil.kryo().reset(); + try { + KryoException error = Assert.assertThrows(KryoException.class, + () -> this.decode(name)); + Assert.assertTrue(name + ": " + error.getMessage(), + error.getMessage().contains("missing no-arg constructor")); + } finally { + KryoUtil.kryo().reset(); + } + } + } + + @Test + public void testEveryLegacyRelationOrdinal() throws IOException { + Properties relations = this.relationFixtures(); + String[] names = relations.getProperty("legacy.names").split(","); + Assert.assertEquals(15, names.length); + for (String name : names) { + Condition.RelationType expected = Condition.RelationType.valueOf(name); + Assert.assertEquals(name, expected, readRelationFixture(relations, "enum." + name)); + } + } + + @Test + public void testLegacyRelationDescriptorsInContainersAndArrays() throws IOException { + Properties relations = this.relationFixtures(); + Condition.RelationType[] expected = Arrays.stream(relations.getProperty("legacy.names").split(",")) + .map(Condition.RelationType::valueOf) + .toArray(Condition.RelationType[]::new); + Assert.assertArrayEquals(expected, (Object[]) readRelationFixture(relations, "array")); + Object matrix = readRelationFixture(relations, "matrix"); + Assert.assertEquals(Condition.RelationType[][].class, matrix.getClass()); + Assert.assertArrayEquals(new Object[]{expected, null, new Condition.RelationType[0]}, (Object[]) matrix); + Map nested = (Map) readRelationFixture(relations, "nested"); + Assert.assertEquals(Arrays.asList(expected), nested.get("values")); + Assert.assertArrayEquals(expected, (Object[]) nested.get("array")); + Assert.assertEquals(Condition.RelationType.SCAN, nested.get("last")); + } + + @Test + public void testInterleavedLegacyAndCanonicalRelationDescriptors() throws IOException { + List values = (List) readRelationFixture(this.relationFixtures(), "interleaved"); + assertInterleavedRelations(values); + List written = (List) roundTrip(values); + Assert.assertEquals(values.subList(0, 4), written.subList(0, 4)); + Assert.assertArrayEquals((Object[]) values.get(4), (Object[]) written.get(4)); + Assert.assertArrayEquals((Object[]) values.get(5), (Object[]) written.get(5)); + Assert.assertSame(written.get(4), written.get(6)); + Assert.assertSame(written.get(5), written.get(7)); + } + + @Test + public void testCanonicalRelationWriterRetainsDefaultOrdinals() { + for (Condition.RelationType relation : Condition.RelationType.values()) { + Assert.assertEquals(relation, roundTrip(relation)); + Output output = new Output(128); + new Kryo().writeClassAndObject(output, relation); + Assert.assertArrayEquals(output.toBytes(), KryoUtil.toKryoWithType(relation)); + } + Condition.RelationType[] values = Condition.RelationType.values(); + Assert.assertArrayEquals(values, (Object[]) roundTrip(values)); + } + + @Test + public void testCanonicalRelationsWithStreamedInput() { + for (int bufferSize : new int[]{2, 7, 16}) { + for (Condition.RelationType relation : Condition.RelationType.values()) { + for (Object value : readStreamedTwice(KryoUtil.toKryoWithType(relation), bufferSize)) { + Assert.assertEquals(relation, value); + } + } + Condition.RelationType[] relations = {Condition.RelationType.TEXT_PREFIX, null, + Condition.RelationType.TEXT_REGEX}; + for (Object value : readStreamedTwice(KryoUtil.toKryoWithType(relations), bufferSize)) { + Assert.assertArrayEquals(relations, (Object[]) value); + } + } + } + + @Test + public void testLegacyRelationsWithStreamedInput() throws IOException { + Properties relations = this.relationFixtures(); + Condition.RelationType[] expected = Arrays.stream(relations.getProperty("legacy.names").split(",")) + .map(Condition.RelationType::valueOf) + .toArray(Condition.RelationType[]::new); + for (int bufferSize : new int[]{2, 7, 16}) { + for (Condition.RelationType relation : expected) { + byte[] bytes = Bytes.fromHex(relations.getProperty("enum." + relation + ".hex")); + for (Object value : readStreamedTwice(bytes, bufferSize)) { + Assert.assertEquals(relation, value); + } + } + for (Object value : readStreamedTwice(Bytes.fromHex(relations.getProperty("array.hex")), bufferSize)) { + Assert.assertArrayEquals(expected, (Object[]) value); + } + for (Object value : readStreamedTwice(Bytes.fromHex(relations.getProperty("matrix.hex")), bufferSize)) { + Assert.assertArrayEquals(new Object[]{expected, null, new Condition.RelationType[0]}, (Object[]) value); + } + byte[] interleaved = Bytes.fromHex(relations.getProperty("interleaved.hex")); + for (Object value : readStreamedTwice(interleaved, bufferSize)) { + assertInterleavedRelations((List) value); + } + } + } + + private static Object[] readStreamedTwice(byte[] payload, int bufferSize) { + // Start a descriptor at the last buffered byte and cross refills; the second + // top-level object also verifies reset of descriptor and reference caches. + int prefix = bufferSize - 1; + byte[] bytes = new byte[prefix + 2 * payload.length + 1]; + System.arraycopy(payload, 0, bytes, prefix, payload.length); + System.arraycopy(payload, 0, bytes, prefix + payload.length, payload.length); + bytes[bytes.length - 1] = 93; + try (Input input = new Input(new ByteArrayInputStream(bytes), bufferSize)) { + for (int i = 0; i < prefix; i++) { + Assert.assertEquals(0, input.readByte()); + } + Object[] values = {KryoUtil.kryo().readClassAndObject(input), KryoUtil.kryo().readClassAndObject(input)}; + Assert.assertEquals(93, input.readByte()); + return values; + } finally { + KryoUtil.kryo().reset(); + } + } + + private static void assertInterleavedRelations(List values) { + Assert.assertEquals(Condition.RelationType.SCAN, values.get(0)); + Assert.assertEquals(Condition.RelationType.TEXT_PREFIX, values.get(1)); + Assert.assertEquals(Condition.RelationType.TEXT_CONTAINS, values.get(2)); + Assert.assertEquals(Condition.RelationType.TEXT_REGEX, values.get(3)); + Assert.assertArrayEquals(new Condition.RelationType[]{Condition.RelationType.SCAN, null, + Condition.RelationType.TEXT_CONTAINS}, + (Object[]) values.get(4)); + Assert.assertArrayEquals(new Condition.RelationType[]{Condition.RelationType.TEXT_PREFIX, null, + Condition.RelationType.TEXT_REGEX}, + (Object[]) values.get(5)); + Assert.assertSame(values.get(4), values.get(6)); + Assert.assertSame(values.get(5), values.get(7)); + } + + private Properties relationFixtures() throws IOException { + Properties relations = new Properties(); + try (InputStream input = this.getClass().getResourceAsStream( + "/compatibility/2f827d6e8/core-relation-ordinals.properties")) { + Assert.assertNotNull(input); + relations.load(input); + } + return relations; + } + + private static Object readRelationFixture(Properties relations, String name) { + return KryoUtil.fromKryoWithType(Bytes.fromHex(relations.getProperty(name + ".hex"))); + } + + private void assertValue(String name, Object expected) { + Object decoded = this.read(name); + Assert.assertEquals(expected, decoded); + // Java API names may change. New writes need semantic compatibility, + // rather than continuing to emit removed core class names. + Assert.assertEquals(expected, roundTrip(decoded)); + } + + private Object read(String name) { + Assert.assertEquals(name, "true", this.fixtures.getProperty(name + ".baseline_readable")); + return this.decode(name); + } + + private Object decode(String name) { + BytesBuffer reader = BytesBuffer.wrap(Bytes.fromHex(this.fixtures.getProperty(name + ".hex"))); + Object decoded = reader.readProperty(DataType.OBJECT); + Assert.assertEquals(0, reader.remaining()); + return decoded; + } + + private static Object roundTrip(Object value) { + BytesBuffer writer = BytesBuffer.allocate(128); + writer.writeProperty(DataType.OBJECT, value); + return BytesBuffer.wrap(writer.bytes()).readProperty(DataType.OBJECT); + } + + private static Userdata expectedUserdata() { + Userdata userdata = new Userdata(); + userdata.put("tag", "legacy"); + userdata.put("count", 7); + userdata.put(Userdata.CREATE_TIME, new Date(1609459200123L)); + return userdata; + } + + private static List> expectedClasses() { + return new ArrayList<>(Arrays.asList(IdGenerator.LongId.class, + IdGenerator.StringId.class, IdGenerator.UuidId.class, + EdgeId.class, BinaryId.class, Shard.class, PropertyKey.class, + VertexLabel.class, EdgeLabel.class, IndexLabel.class)); + } + + private static Class nestedClass(Class owner, String name) { + return Arrays.stream(owner.getDeclaredClasses()) + .filter(type -> type.getSimpleName().equals(name)) + .findFirst().orElseThrow(AssertionError::new); + } + + private static void assertColumn(Object value) { + Assert.assertEquals(BackendColumn.class, value.getClass()); + BackendColumn column = (BackendColumn) value; + Assert.assertArrayEquals(new byte[]{1, 2}, column.name); + Assert.assertArrayEquals(new byte[]{3, 4}, column.value); + } + + private static void assertNested(Object value) { + Assert.assertTrue(value instanceof Map); + Map nested = (Map) value; + Assert.assertEquals(expectedClasses(), nested.get("classes")); + Assert.assertEquals(expectedUserdata(), nested.get("metadata")); + Assert.assertEquals(Id[][].class, nested.get("ids").getClass()); + Assert.assertArrayEquals(new Id[][]{new Id[]{null}, new Id[0]}, (Id[][]) nested.get("ids")); + Assert.assertEquals(Condition.RelationType.GTE, nested.get("predicate")); + assertColumn(nested.get("column")); + } +} diff --git a/hugegraph-struct/src/test/java/org/apache/hugegraph/id/IdCompatibilityTest.java b/hugegraph-struct/src/test/java/org/apache/hugegraph/id/IdCompatibilityTest.java new file mode 100644 index 0000000000..96eff3ba4b --- /dev/null +++ b/hugegraph-struct/src/test/java/org/apache/hugegraph/id/IdCompatibilityTest.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.id; + +import java.util.UUID; + +import org.apache.hugegraph.type.HugeType; +import org.apache.hugegraph.type.define.Directions; +import org.apache.hugegraph.util.StringEncoding; +import org.junit.Assert; +import org.junit.Test; + +public class IdCompatibilityTest { + + @Test + public void testNumericIdsRejectTextAndNullWithoutParsing() { + Id id = IdGenerator.of(42L); + Assert.assertFalse(id.equals(null)); + Assert.assertFalse(id.equals("42")); + Assert.assertFalse(id.equals("42.0")); + Assert.assertFalse(id.equals("not-a-number")); + Assert.assertFalse(id.equals(IdGenerator.of("42"))); + Id same = IdGenerator.of(new byte[]{0, 0, 0, 0, 0, 0, 0, 42}, Id.IdType.LONG); + Assert.assertEquals(id, same); + Assert.assertEquals(id.hashCode(), same.hashCode()); + } + + @Test + public void testUtf8IdsAgreeAcrossStringAndByteRepresentations() { + String text = "北京`>vertex"; + Id fromString = IdGenerator.of(text); + Id fromBytes = IdGenerator.of(StringEncoding.encode(text), Id.IdType.STRING); + Assert.assertEquals(fromString, fromBytes); + Assert.assertEquals(fromBytes, fromString); + Assert.assertEquals(fromString.hashCode(), fromBytes.hashCode()); + Assert.assertEquals(0, fromString.compareTo(fromBytes)); + Assert.assertEquals(0, fromBytes.compareTo(fromString)); + Assert.assertEquals(text, fromBytes.asObject()); + Assert.assertArrayEquals(StringEncoding.encode(text), fromString.asBytes()); + } + + @Test + public void testStoredIdsPreserveTypesAndEscapedEdgeParts() { + Id[] ids = { + IdGenerator.of(Long.MIN_VALUE), + IdGenerator.of("北京`>vertex"), + IdGenerator.of(UUID.fromString("00112233-4455-6677-8899-aabbccddeeff")), + new EdgeId(IdGenerator.of("owner>vertex"), Directions.OUT, + IdGenerator.of(1), IdGenerator.of(2), "value>with`escape", + IdGenerator.of(42)) + }; + for (Id id : ids) { + Id stored = IdUtil.readStoredString(IdUtil.writeStoredString(id)); + Assert.assertEquals(id.type(), stored.type()); + Assert.assertEquals(id, stored); + Assert.assertEquals(id.hashCode(), stored.hashCode()); + } + Assert.assertEquals(Directions.OUT, EdgeId.directionFromCode(HugeType.EDGE_OUT.code())); + Assert.assertEquals(Directions.IN, EdgeId.directionFromCode(HugeType.EDGE_IN.code())); + } +} diff --git a/hugegraph-struct/src/test/java/org/apache/hugegraph/id/StringIdComparisonTest.java b/hugegraph-struct/src/test/java/org/apache/hugegraph/id/StringIdComparisonTest.java new file mode 100644 index 0000000000..7a22f22434 --- /dev/null +++ b/hugegraph-struct/src/test/java/org/apache/hugegraph/id/StringIdComparisonTest.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.id; + +import org.apache.hugegraph.util.StringEncoding; +import org.junit.Assert; +import org.junit.Test; + +public class StringIdComparisonTest { + + @Test + public void testUtf16OrderAcrossRepresentations() { + String[] values = {"a", "aa", "北京", "\uD7FF", "\uD800\uDC00", "\uE000", "\uFFFF"}; + for (String left : values) { + for (String right : values) { + int expected = Integer.signum(left.compareTo(right)); + for (boolean leftBytes : new boolean[]{false, true}) { + for (boolean rightBytes : new boolean[]{false, true}) { + // Fresh IDs keep both directions independent of lazy decoding. + int forward = compare(left, leftBytes, right, rightBytes); + int reverse = compare(right, rightBytes, left, leftBytes); + Assert.assertEquals(expected, forward); + Assert.assertEquals(-forward, reverse); + } + } + } + } + } + + @Test + public void testOrderDoesNotChangeAfterLazyConversion() { + Id supplementary = newId("\uD800\uDC00", true); + Id privateUse = newId("\uE000", true); + int before = Integer.signum(supplementary.compareTo(privateUse)); + Assert.assertEquals(-1, before); + + supplementary.asString(); + Assert.assertEquals(before, Integer.signum(supplementary.compareTo(privateUse))); + privateUse.asString(); + Assert.assertEquals(before, Integer.signum(supplementary.compareTo(privateUse))); + supplementary.asBytes(); + privateUse.asBytes(); + Assert.assertEquals(before, Integer.signum(supplementary.compareTo(privateUse))); + Assert.assertEquals(-before, Integer.signum(privateUse.compareTo(supplementary))); + } + + @Test + public void testMixedUnicodeOrderIsTransitive() { + String beforeSurrogates = "\uD7FF"; + String supplementary = "\uD800\uDC00"; + String privateUse = "\uE000"; + for (boolean firstBytes : new boolean[]{false, true}) { + for (boolean secondBytes : new boolean[]{false, true}) { + for (boolean thirdBytes : new boolean[]{false, true}) { + Assert.assertTrue(compare(beforeSurrogates, firstBytes, + supplementary, secondBytes) < 0); + Assert.assertTrue(compare(supplementary, secondBytes, + privateUse, thirdBytes) < 0); + Assert.assertTrue(compare(beforeSurrogates, firstBytes, + privateUse, thirdBytes) < 0); + } + } + } + } + + private static int compare(String left, boolean leftBytes, String right, boolean rightBytes) { + return Integer.signum(newId(left, leftBytes).compareTo(newId(right, rightBytes))); + } + + private static Id newId(String value, boolean bytes) { + return bytes ? IdGenerator.of(StringEncoding.encode(value), Id.IdType.STRING) : + IdGenerator.of(value); + } +} diff --git a/hugegraph-struct/src/test/java/org/apache/hugegraph/query/SharedQueryTest.java b/hugegraph-struct/src/test/java/org/apache/hugegraph/query/SharedQueryTest.java new file mode 100644 index 0000000000..f73e6f416f --- /dev/null +++ b/hugegraph-struct/src/test/java/org/apache/hugegraph/query/SharedQueryTest.java @@ -0,0 +1,143 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.query; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.hugegraph.query.Aggregate.AggregateFunc; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.structure.BaseVertex; +import org.apache.hugegraph.type.HugeType; +import org.apache.hugegraph.type.define.DataType; +import org.apache.hugegraph.type.define.HugeKeys; +import org.junit.Assert; +import org.junit.Test; + +public class SharedQueryTest { + + @Test + public void testOffsetAdvancesOnlyByCurrentBatchSize() { + Query query = new Query(HugeType.VERTEX); + query.offset(5L); + query.limit(2L); + Assert.assertTrue(query.skipOffsetIfNeeded( + new LinkedHashSet<>(Arrays.asList(1, 2))).isEmpty()); + Assert.assertEquals(2L, query.actualOffset()); + Assert.assertTrue(query.skipOffsetIfNeeded( + new LinkedHashSet<>(Arrays.asList(3, 4))).isEmpty()); + Assert.assertEquals(4L, query.actualOffset()); + Assert.assertEquals(new LinkedHashSet<>(Arrays.asList(6, 7)), + query.skipOffsetIfNeeded( + new LinkedHashSet<>(Arrays.asList(5, 6, 7)))); + Assert.assertEquals(5L, query.actualOffset()); + } + + @Test + public void testContradictoryIntersectionsStayEmpty() { + ConditionQuery query = new ConditionQuery(HugeType.VERTEX); + query.query(Condition.eq(HugeKeys.LABEL, 1)); + query.query(Condition.eq(HugeKeys.LABEL, 2)); + query.query(Condition.in(HugeKeys.LABEL, Arrays.asList(2, 3))); + Assert.assertNull(query.condition(HugeKeys.LABEL)); + + ConditionQuery emptyFirst = new ConditionQuery(HugeType.VERTEX); + emptyFirst.query(Condition.in(HugeKeys.LABEL, Collections.emptyList())); + emptyFirst.query(Condition.in(HugeKeys.LABEL, Arrays.asList(2, 3))); + Assert.assertNull(emptyFirst.condition(HugeKeys.LABEL)); + } + + @Test + public void testSingleIdAndCopy() { + Id id = IdGenerator.of(123L); + IdQuery.OneIdQuery query = new IdQuery.OneIdQuery(HugeType.VERTEX, id); + BaseVertex vertex = new BaseVertex(id); + Assert.assertTrue(query.test(vertex)); + Assert.assertFalse(query.test(new BaseVertex(IdGenerator.of(124L)))); + IdQuery.OneIdQuery copy = (IdQuery.OneIdQuery) query.copy(); + query.resetIds(); + Assert.assertEquals(0, query.idsSize()); + Assert.assertTrue(query.test(vertex)); + Assert.assertEquals(id, copy.id()); + Assert.assertEquals(1, copy.idsSize()); + } + + @Test + public void testRangeIndexValueConsumedOncePerProperty() { + Id key = IdGenerator.of(10L); + Id id = IdGenerator.of(123L); + PropertyKey property = new PropertyKey(null, key, "age"); + property.dataType(DataType.INT); + BaseVertex vertex = new BaseVertex(id); + vertex.addProperty(property, 25); + ConditionQuery query = new ConditionQuery(HugeType.VERTEX); + query.query(Condition.gte(key, 20)); + query.query(Condition.lte(key, 30)); + query.recordIndexValue(key, id, 25); + query.recordIndexValue(key, id, 17); + query.selectedIndexField(key); + Assert.assertTrue(query.test(vertex)); + Assert.assertEquals(1, query.getLeftIndexOfElement(id).size()); + Assert.assertEquals(Collections.singleton(17), + query.getLeftIndexOfElement(id).iterator().next() + .indexFieldValues()); + } + + @Test + public void testExplicitFilterAndFreshElements() { + BaseVertex vertex = new BaseVertex(IdGenerator.of(123L)); + ConditionQuery query = new ConditionQuery(HugeType.VERTEX); + AtomicInteger calls = new AtomicInteger(); + query.registerResultsFilter(element -> { + calls.incrementAndGet(); + return false; + }); + Assert.assertFalse(query.test(vertex)); + Assert.assertEquals(1, calls.get()); + vertex.fresh(true); + Assert.assertTrue(query.test(vertex)); + Assert.assertEquals(1, calls.get()); + vertex.fresh(false); + Assert.assertTrue(query.test(vertex, element -> true)); + Assert.assertEquals(1, calls.get()); + } + + @Test + public void testAggregateDescriptorRetainsNumericStrategy() { + ConditionQuery query = new ConditionQuery(HugeType.VERTEX); + query.aggregate(AggregateFunc.AVG, "age"); + byte[] encoded = query.bytes(); + Assert.assertTrue(new String(encoded, StandardCharsets.UTF_8) + .contains("\"aggregate\":{\"func\":\"AVG\",\"column\":\"age\"}")); + ConditionQuery decoded = ConditionQuery.fromBytes(encoded); + Assert.assertEquals(AggregateFunc.AVG, decoded.aggregateNotNull().func()); + Assert.assertEquals("age", decoded.aggregateNotNull().column()); + Assert.assertEquals(25D, decoded.aggregateNotNull() + .reduce(Arrays.asList(20, 30).iterator()) + .doubleValue(), 0D); + query.aggregate(AggregateFunc.COUNT, null); + decoded = ConditionQuery.fromBytes(query.bytes()); + Assert.assertTrue(decoded.aggregateNotNull().countAll()); + Assert.assertEquals(0L, decoded.aggregateNotNull().defaultValue()); + } +} diff --git a/hugegraph-struct/src/test/java/org/apache/hugegraph/serializer/OlapKeyTest.java b/hugegraph-struct/src/test/java/org/apache/hugegraph/serializer/OlapKeyTest.java new file mode 100644 index 0000000000..7fb4eaecd0 --- /dev/null +++ b/hugegraph-struct/src/test/java/org/apache/hugegraph/serializer/OlapKeyTest.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.serializer; + +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.util.Bytes; +import org.junit.Assert; +import org.junit.Test; + +public class OlapKeyTest { + + @Test + public void testMergedKeyMatchesObservedRuntimeRequest() { + Assert.assertArrayEquals(Bytes.fromHex("080586313a616c696365"), + OlapKey.format(IdGenerator.of(5), IdGenerator.of("1:alice"))); + BytesBuffer key = BytesBuffer.wrap(OlapKey.format(IdGenerator.of(130), IdGenerator.of(1000))); + Assert.assertEquals(IdGenerator.of(130), key.readId()); + Assert.assertEquals(IdGenerator.of(1000), key.readId()); + Assert.assertEquals(0, key.remaining()); + } + + @Test + public void testValueIdentityUsesWholeVariableLengthPropertyId() { + byte[] observed = Bytes.fromHex("0563"); + Assert.assertTrue(OlapKey.matchesProperty(observed, IdGenerator.of(5))); + Assert.assertFalse(OlapKey.matchesProperty(observed, IdGenerator.of(8))); + byte[] largeProperty = BytesBuffer.allocate(16).writeVInt(130).writeVInt(99).bytes(); + Assert.assertTrue(OlapKey.matchesProperty(largeProperty, IdGenerator.of(130))); + Assert.assertFalse(OlapKey.matchesProperty(largeProperty, IdGenerator.of(1))); + Assert.assertFalse(OlapKey.matchesProperty(null, IdGenerator.of(5))); + Assert.assertFalse(OlapKey.matchesProperty(new byte[0], IdGenerator.of(5))); + Assert.assertFalse(OlapKey.matchesProperty(new byte[]{(byte) 0x81}, IdGenerator.of(5))); + Assert.assertFalse(OlapKey.matchesProperty(new byte[]{(byte) 0x80}, IdGenerator.of(5))); + } +} diff --git a/hugegraph-struct/src/test/java/org/apache/hugegraph/struct/schema/EdgeLabelMapTest.java b/hugegraph-struct/src/test/java/org/apache/hugegraph/struct/schema/EdgeLabelMapTest.java new file mode 100644 index 0000000000..1d1ca47931 --- /dev/null +++ b/hugegraph-struct/src/test/java/org/apache/hugegraph/struct/schema/EdgeLabelMapTest.java @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.struct.schema; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.apache.commons.lang3.tuple.Pair; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper; +import org.junit.Assert; +import org.junit.Test; + +public class EdgeLabelMapTest { + + @Test + public void testSingleLinkMetadataRegardlessOfOrder() throws Exception { + // Exact field shapes emitted by the pre-consolidation Server JsonUtil. + Map wire = map("{\"id\":3,\"name\":\"knows\",\"links\":[{\"1\":2}]," + + "\"sourceLabel\":\"1\",\"targetLabel\":\"2\"}"); + EdgeLabel decoded = EdgeLabel.fromMap(wire, null); + Assert.assertEquals(Collections.singleton(Pair.of(IdGenerator.of(1), IdGenerator.of(2))), + decoded.links()); + Map endpointsFirst = new LinkedHashMap<>(); + endpointsFirst.put(EdgeLabel.P.SOURCE_LABEL, wire.get(EdgeLabel.P.SOURCE_LABEL)); + endpointsFirst.put(EdgeLabel.P.TARGET_LABEL, wire.get(EdgeLabel.P.TARGET_LABEL)); + endpointsFirst.putAll(wire); + Assert.assertEquals(decoded.links(), EdgeLabel.fromMap(endpointsFirst, null).links()); + } + + @Test + public void testLegacyEndpointsWithoutLinks() throws Exception { + Map wire = map("{\"id\":3,\"name\":\"knows\",\"sourceLabel\":\"1\"," + + "\"targetLabel\":\"2\"}"); + EdgeLabel decoded = EdgeLabel.fromMap(wire, null); + Assert.assertEquals(IdGenerator.of(1), decoded.sourceLabel()); + Assert.assertEquals(IdGenerator.of(2), decoded.targetLabel()); + Assert.assertEquals(1, decoded.links().size()); + } + + @Test + public void testMultiLinksAcceptConsistentRedundantEndpoints() throws Exception { + Map wire = map("{\"id\":3,\"name\":\"knows\",\"links\":[{\"1\":2},{\"2\":4}]," + + "\"sourceLabel\":\"1\",\"targetLabel\":\"2\"}"); + EdgeLabel decoded = EdgeLabel.fromMap(wire, null); + Assert.assertEquals(2, decoded.links().size()); + Assert.assertTrue(decoded.checkLinkEqual(IdGenerator.of(1), IdGenerator.of(2))); + Assert.assertTrue(decoded.checkLinkEqual(IdGenerator.of(2), IdGenerator.of(4))); + } + + @Test + public void testConflictingEndpointsRejected() throws Exception { + Map wire = map("{\"id\":3,\"name\":\"knows\",\"links\":[{\"1\":2}]," + + "\"sourceLabel\":\"1\",\"targetLabel\":\"4\"}"); + IllegalArgumentException error = Assert.assertThrows(IllegalArgumentException.class, + () -> EdgeLabel.fromMap(wire, null)); + Assert.assertTrue(error.getMessage().contains("conflict")); + } + + @Test + public void testIncompleteEndpointsRejected() throws Exception { + Map wire = map("{\"id\":3,\"name\":\"knows\",\"sourceLabel\":\"1\"}"); + Assert.assertThrows(IllegalArgumentException.class, () -> EdgeLabel.fromMap(wire, null)); + } + + @Test + public void testMalformedLinksRejected() throws Exception { + for (String value : new String[]{"null", "{}", "[{}]", "[{\"1\":null}]", + "[{\"invalid\":2}]"}) { + Map wire = map("{\"id\":3,\"name\":\"knows\",\"links\":" + value + "}"); + Assert.assertThrows(IllegalArgumentException.class, () -> EdgeLabel.fromMap(wire, null)); + } + } + + @SuppressWarnings("unchecked") + private static Map map(String json) throws Exception { + return new ObjectMapper().readValue(json, LinkedHashMap.class); + } +} diff --git a/hugegraph-struct/src/test/java/org/apache/hugegraph/struct/schema/OrderedSchemaFieldsTest.java b/hugegraph-struct/src/test/java/org/apache/hugegraph/struct/schema/OrderedSchemaFieldsTest.java new file mode 100644 index 0000000000..2937e182ec --- /dev/null +++ b/hugegraph-struct/src/test/java/org/apache/hugegraph/struct/schema/OrderedSchemaFieldsTest.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.struct.schema; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.id.SplicingIdGenerator; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.query.IdQuery; +import org.apache.hugegraph.structure.BaseEdge; +import org.apache.hugegraph.structure.BaseVertex; +import org.apache.hugegraph.type.HugeType; +import org.apache.hugegraph.type.define.HugeKeys; +import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper; +import org.junit.Assert; +import org.junit.Test; + +public class OrderedSchemaFieldsTest { + + @Test + public void testPrimaryKeyOrderDrivesVertexIdAndQuery() throws Exception { + VertexLabel label = VertexLabel.fromMap(map("{\"id\":1,\"name\":\"person\"," + + "\"idStrategy\":\"PRIMARY_KEY\"," + + "\"primaryKeys\":[2,17]}"), null); + Assert.assertEquals(Arrays.asList(id(2), id(17)), label.primaryKeys()); + BaseVertex vertex = new BaseVertex(null, label); + vertex.addProperty(key(17), "first"); + vertex.addProperty(key(2), "second"); + Assert.assertEquals(Arrays.asList("second", "first"), vertex.primaryValues()); + Assert.assertEquals("second!first", vertex.name()); + Id expected = IdGenerator.of("1:second!first"); + vertex.id(SplicingIdGenerator.instance().generate(vertex)); + Assert.assertEquals(expected, vertex.id()); + IdQuery query = new IdQuery(HugeType.VERTEX); + query.query(expected); + Assert.assertTrue(query.test(vertex)); + } + + @Test + public void testSortKeyOrderDrivesEdgeIdAndQuery() throws Exception { + EdgeLabel label = EdgeLabel.fromMap(map("{\"id\":3,\"name\":\"knows\"," + + "\"sortKeys\":[2,17],\"links\":[{\"1\":2}]}"), null); + Assert.assertEquals(Arrays.asList(id(2), id(17)), label.sortKeys()); + BaseEdge edge = new BaseEdge(label, true); + edge.addProperty(key(17), "first"); + edge.addProperty(key(2), "second"); + edge.vertices(true, new BaseVertex(id(1)), new BaseVertex(id(2))); + edge.assignId(); + Assert.assertEquals(Arrays.asList("second", "first"), edge.sortValues()); + Assert.assertEquals("second!first", ((EdgeId) edge.id()).sortValues()); + Assert.assertTrue(Condition.eq(HugeKeys.SORT_VALUES, "second!first").test(edge)); + Assert.assertFalse(Condition.eq(HugeKeys.SORT_VALUES, "first!second").test(edge)); + } + + @Test + public void testWriterAcceptedRepeatedKeysAreNotSilentlyDiscarded() throws Exception { + VertexLabel vertex = VertexLabel.fromMap(map("{\"id\":1,\"name\":\"person\"," + + "\"primaryKeys\":[2,17,2]}"), null); + EdgeLabel edge = EdgeLabel.fromMap(map("{\"id\":3,\"name\":\"knows\"," + + "\"sortKeys\":[2,17,2]}"), null); + List expected = Arrays.asList(id(2), id(17), id(2)); + Assert.assertEquals(expected, vertex.primaryKeys()); + Assert.assertEquals(expected, edge.sortKeys()); + } + + private static Id id(int value) { + return IdGenerator.of(value); + } + + private static PropertyKey key(int value) { + return new PropertyKey(null, id(value), "key" + value); + } + + @SuppressWarnings("unchecked") + private static Map map(String json) throws Exception { + return new ObjectMapper().readValue(json, Map.class); + } +} diff --git a/hugegraph-struct/src/test/java/org/apache/hugegraph/struct/schema/SchemaElementTest.java b/hugegraph-struct/src/test/java/org/apache/hugegraph/struct/schema/SchemaElementTest.java new file mode 100644 index 0000000000..97c965f808 --- /dev/null +++ b/hugegraph-struct/src/test/java/org/apache/hugegraph/struct/schema/SchemaElementTest.java @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.struct.schema; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.type.define.SchemaStatus; +import org.apache.hugegraph.util.DateUtil; +import org.junit.Assert; +import org.junit.Test; + +public class SchemaElementTest { + + private static final String CREATE_TIME = "2026-05-14 10:11:12.345"; + + @Test + public void testCreateTimeNormalizationAtSharedBoundary() { + PropertyKey key = new PropertyKey(null, IdGenerator.of(1), "created"); + key.userdata(Userdata.CREATE_TIME, CREATE_TIME); + Assert.assertEquals(DateUtil.parse(CREATE_TIME), + key.userdata().get(Userdata.CREATE_TIME)); + + Date date = DateUtil.now(); + key.userdata(Userdata.CREATE_TIME, date); + Assert.assertSame(date, key.userdata().get(Userdata.CREATE_TIME)); + key.userdata(Userdata.CREATE_TIME, ""); + Assert.assertEquals("", key.userdata().get(Userdata.CREATE_TIME)); + key.userdata("note", CREATE_TIME); + Assert.assertEquals(CREATE_TIME, key.userdata().get("note")); + } + + @Test + public void testPersistedSchemaUserdataRestoresDate() { + Map userdata = new HashMap<>(); + userdata.put(Userdata.CREATE_TIME, CREATE_TIME); + userdata.put("count", 42); + Map serialized = new HashMap<>(); + serialized.put(VertexLabel.P.ID, 1); + serialized.put(VertexLabel.P.NAME, "person"); + serialized.put(VertexLabel.P.STATUS, SchemaStatus.CREATED.string()); + serialized.put(VertexLabel.P.USERDATA, userdata); + + VertexLabel label = VertexLabel.fromMap(serialized, null); + Assert.assertEquals(DateUtil.parse(CREATE_TIME), + label.userdata().get(Userdata.CREATE_TIME)); + Assert.assertEquals(42, label.userdata().get("count")); + Assert.assertEquals(SchemaStatus.CREATED, label.status()); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidCreateTimeRejected() { + Userdata userdata = new Userdata(); + userdata.put(Userdata.CREATE_TIME, "not-a-date"); + } + + @Test(expected = IllegalArgumentException.class) + public void testNullBulkUserdataRejected() { + new PropertyKey(null, IdGenerator.of(1), "created").userdata((Userdata) null); + } + + @Test + public void testCopyPreservesIdentityAndStatus() { + PropertyKey key = new PropertyKey(null, IdGenerator.of(1), "created"); + key.userdata("note", "unchanged"); + key.status(SchemaStatus.CREATING); + SchemaElement copy = key.copy(); + Assert.assertNotSame(key, copy); + Assert.assertEquals(key, copy); + Assert.assertEquals(key.hashCode(), copy.hashCode()); + Assert.assertEquals(key.status(), copy.status()); + Assert.assertEquals(key.userdata(), copy.userdata()); + } +} diff --git a/hugegraph-struct/src/test/java/org/apache/hugegraph/structure/SharedElementTest.java b/hugegraph-struct/src/test/java/org/apache/hugegraph/structure/SharedElementTest.java new file mode 100644 index 0000000000..2cf661aa02 --- /dev/null +++ b/hugegraph-struct/src/test/java/org/apache/hugegraph/structure/SharedElementTest.java @@ -0,0 +1,260 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.structure; + +import java.util.Arrays; +import java.util.Collection; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.query.Condition; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.Userdata; +import org.apache.hugegraph.struct.schema.VertexLabel; +import org.apache.hugegraph.type.HugeType; +import org.apache.hugegraph.type.define.Cardinality; +import org.apache.hugegraph.type.define.DataType; +import org.apache.hugegraph.type.define.IdStrategy; +import org.junit.Assert; +import org.junit.Test; + +public class SharedElementTest { + + @Test + public void testSingleUpdateCallbackSeesPreviousValue() { + BaseVertex vertex = vertex(1); + PropertyKey key = key(Cardinality.SINGLE); + vertex.addProperty(key, "before"); + AtomicBoolean notified = new AtomicBoolean(); + vertex.addProperty(key, "after", BaseProperty::new, property -> { + Assert.assertEquals("before", vertex.getPropertyValue(key.id())); + Assert.assertEquals("after", property.value()); + notified.set(true); + }, property -> Assert.fail("Single update notified after replacement")); + Assert.assertTrue(notified.get()); + Assert.assertEquals("after", vertex.getPropertyValue(key.id())); + } + + @Test + public void testCollectionUpdateSharesPropertyAndNotifiesAfterMutation() { + BaseVertex vertex = vertex(1); + PropertyKey key = key(Cardinality.SET); + BaseProperty property = vertex.addProperty(key, "first"); + vertex.addProperty(key, Arrays.asList("first", "second"), BaseProperty::new, + value -> Assert.fail("Collection invoked single callback"), value -> { + Assert.assertSame(property, value); + Assert.assertEquals(2, ((Collection) value.value()).size()); + }); + Assert.assertSame(property, vertex.getProperty(key.id())); + } + + @Test + public void testCloneStateAndCopyPropertyMapAreIndependent() throws Exception { + BaseVertex original = vertex(1); + PropertyKey key = key(Cardinality.SINGLE); + original.addProperty(key, "original"); + BaseVertex copy = (BaseVertex) original.clone(); + copy.copyProperties(original); + copy.removed(true); + copy.expiredTime(100); + copy.addProperty(key, "replacement"); + Assert.assertFalse(original.removed()); + Assert.assertEquals(0, original.expiredTime()); + Assert.assertEquals("original", original.getPropertyValue(key.id())); + Assert.assertEquals("replacement", copy.getPropertyValue(key.id())); + } + + @Test + public void testSwitchOwnerPreservesSharedPropertiesAndOriginalDirection() { + EdgeLabel label = new EdgeLabel(null, IdGenerator.of(3), "link"); + BaseVertex source = vertex(1); + BaseVertex target = vertex(2); + BaseEdge original = new BaseEdge(label, true); + original.vertices(true, source, target); + original.name(""); + original.assignId(); + PropertyKey key = key(Cardinality.SINGLE); + original.addProperty(key, "value"); + BaseEdge reverse = original.switchOwner(); + Assert.assertTrue(original.isOutEdge()); + Assert.assertFalse(reverse.isOutEdge()); + Assert.assertEquals(source.id(), original.ownerVertexId()); + Assert.assertEquals(target.id(), reverse.ownerVertexId()); + Assert.assertSame(original.getProperty(key.id()), reverse.getProperty(key.id())); + reverse.resetProperties(); + Assert.assertTrue(original.hasProperty(key.id())); + Assert.assertFalse(reverse.hasProperty(key.id())); + } + + @Test + public void testLazyPropertyReadsAreUsedByValueMapAndEncoding() { + BaseVertex vertex = vertex(1); + PropertyKey key = key(Cardinality.SINGLE); + BaseProperty lazy = new BaseProperty(key, null) { + @Override + public String value() { + return "loaded"; + } + }; + vertex.addProperty(lazy); + Assert.assertEquals("loaded", vertex.getPropertiesMap().get(key.id())); + Assert.assertEquals(key.serialValue("loaded", true), lazy.serialValue(true)); + Assert.assertTrue(Condition.eq(key.id(), "loaded").test(vertex)); + } + + @Test + public void testQueryDoesNotLoadPropertiesOrInsertDefaultsImplicitly() { + BaseVertex vertex = vertex(1); + PropertyKey key = key(Cardinality.SINGLE); + key.userdata(Userdata.DEFAULT_VALUE, "default"); + vertex.schemaLabel().property(key.id()); + vertex.propLoaded(false); + Assert.assertFalse(Condition.eq(key.id(), "default").test(vertex)); + Assert.assertFalse(vertex.propLoaded()); + Assert.assertFalse(vertex.defaultValueUpdated()); + + // Engine accessors explicitly load backend data before updating defaults. + vertex.propLoaded(true); + vertex.updateDefaultValues(id -> key); + Assert.assertTrue(Condition.eq(key.id(), "default").test(vertex)); + Assert.assertTrue(vertex.defaultValueUpdated()); + vertex.addProperty(key, "explicit"); + vertex.updateDefaultValues(id -> key); + Assert.assertEquals("explicit", vertex.getPropertyValue(key.id())); + } + + @Test + public void testFreshPropertyMapsCannotAffectOtherElements() throws Exception { + BaseVertex first = vertex(1); + BaseVertex second = vertex(2); + BaseVertex clonedEmpty = (BaseVertex) first.clone(); + PropertyKey key = key(Cardinality.SINGLE); + Assert.assertNull(first.removeProperty(key.id())); + first.properties().put(BaseElement.intFromId(key.id()), new BaseProperty<>(key, "first")); + Assert.assertEquals("first", first.getPropertyValue(key.id())); + Assert.assertFalse(second.hasProperties()); + Assert.assertFalse(clonedEmpty.hasProperties()); + second.properties().put(BaseElement.intFromId(key.id()), new BaseProperty<>(key, "second")); + first.properties().clear(); + Assert.assertEquals("second", second.getPropertyValue(key.id())); + Assert.assertFalse(clonedEmpty.hasProperties()); + BaseVertex copied = (BaseVertex) second.clone(); + copied.copyProperties(second); + copied.properties().clear(); + Assert.assertEquals("second", second.getPropertyValue(key.id())); + } + + @Test + public void testSharedPrimaryNameUsesReservedValueContract() { + PropertyKey key = key(Cardinality.SINGLE); + VertexLabel label = new VertexLabel(null, IdGenerator.of(10), "person"); + label.idStrategy(IdStrategy.PRIMARY_KEY); + label.primaryKeys(key.id()); + BaseVertex vertex = new BaseVertex(null, label); + vertex.addProperty(key, ""); + Assert.assertThrows(IllegalArgumentException.class, vertex::name); + for (char prefix = 0; prefix <= 3; prefix++) { + vertex.addProperty(key, prefix + "value"); + Assert.assertThrows(IllegalArgumentException.class, vertex::name); + } + vertex.addProperty(key, "a!b"); + Assert.assertEquals("a`!b", vertex.name()); + } + + @Test + public void testSharedEdgeNamePreservesSortValueNormalization() { + PropertyKey key = key(Cardinality.SINGLE); + EdgeLabel label = new EdgeLabel(null, IdGenerator.of(3), "link"); + BaseEdge edge = new BaseEdge(null, label); + Assert.assertEquals("", edge.name()); + label.sortKeys(key.id()); + edge.name(null); + edge.addProperty(key, ""); + Assert.assertEquals("", edge.name()); + edge.name(null); + edge.addProperty(key, "a!b"); + Assert.assertEquals("a`!b", edge.name()); + edge.name(null); + edge.addProperty(key, "\u0000value"); + Assert.assertThrows(IllegalArgumentException.class, edge::name); + } + + @Test + public void testStandaloneUnknownSchemaFactoryRequiresNoSupplier() { + BaseVertex owner = vertex(1); + EdgeLabel label = new EdgeLabel(null, IdGenerator.of(3), "link"); + label.sourceLabel(IdGenerator.of(10)); + label.targetLabel(IdGenerator.of(11)); + BaseEdge edge = BaseEdge.createEdge(null, owner, true, label, "sort", IdGenerator.of(2)); + Assert.assertSame(owner, edge.ownerVertex()); + Assert.assertTrue(owner.schemaLabel().undefined()); + Assert.assertTrue(edge.otherVertex().schemaLabel().undefined()); + Assert.assertEquals(IdGenerator.of(10), owner.schemaLabel().id()); + Assert.assertEquals(IdGenerator.of(11), edge.otherVertex().schemaLabel().id()); + Assert.assertEquals("sort", edge.name()); + Assert.assertEquals(IdGenerator.of(2), edge.otherVertexId()); + } + + @Test + public void testUniqueAdjacencyUsesSharedEdgeIdEquality() { + BaseVertex owner = vertex(1); + BaseVertex other = vertex(2); + EdgeLabel label = new EdgeLabel(null, IdGenerator.of(3), "link"); + owner.resetEdges(true); + BaseEdge first = new BaseEdge(label, true); + first.vertices(true, owner, other); + first.name(""); + first.assignId(); + BaseEdge duplicate = first.clone(); + Assert.assertTrue(owner.addEdge(first)); + Assert.assertFalse(owner.addEdge(duplicate)); + Assert.assertEquals(1, owner.edges().size()); + Assert.assertSame(first, owner.removeEdge(duplicate)); + Assert.assertTrue(owner.edges().isEmpty()); + } + + @Test + public void testClassificationPreservesStorageAndEngineContracts() { + VertexLabel variables = new VertexLabel(null, IdGenerator.of(10), "~variables"); + BaseVertex stored = new BaseVertex(IdGenerator.of(1), variables); + BaseVertex engine = new BaseVertex(IdGenerator.of(1), variables, + BaseVertex.TypeContext.ENGINE); + Assert.assertEquals(HugeType.TASK, stored.type()); + Assert.assertEquals(HugeType.VERTEX, engine.type()); + + VertexLabel server = new VertexLabel(null, IdGenerator.of(11), "~server"); + stored.schemaLabel(server); + engine.schemaLabel(server); + Assert.assertEquals(HugeType.VERTEX, stored.type()); + Assert.assertEquals(HugeType.SERVER, engine.type()); + } + + private static BaseVertex vertex(long value) { + Id id = IdGenerator.of(value); + return new BaseVertex(id, new VertexLabel(null, IdGenerator.of(10), "person")); + } + + private static PropertyKey key(Cardinality cardinality) { + PropertyKey key = new PropertyKey(null, IdGenerator.of(1), "name"); + key.dataType(DataType.TEXT); + key.cardinality(cardinality); + return key; + } +} diff --git a/hugegraph-struct/src/test/java/org/apache/hugegraph/structure/SharedIndexTest.java b/hugegraph-struct/src/test/java/org/apache/hugegraph/structure/SharedIndexTest.java new file mode 100644 index 0000000000..643fe4939e --- /dev/null +++ b/hugegraph-struct/src/test/java/org/apache/hugegraph/structure/SharedIndexTest.java @@ -0,0 +1,184 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.structure; + +import java.lang.reflect.Proxy; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.apache.hugegraph.HugeGraphSupplier; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; +import org.apache.hugegraph.type.HugeType; +import org.apache.hugegraph.type.define.DataType; +import org.apache.hugegraph.type.define.IndexType; +import org.junit.Assert; +import org.junit.Test; + +public class SharedIndexTest { + + @Test + public void testLegacyIndexIdAndHashBytes() { + // Fixed Server bytes from compatibility/2f827d6e8 fixtures, not a + // round-trip assertion using the same writer and reader. + Assert.assertArrayEquals(new byte[]{(byte) 160, 0, 0, 0, 3, (byte) 128, 0, 0, 7}, + Index.formatIndexId(HugeType.RANGE_INT_INDEX, + id(3), 7).asBytes()); + Assert.assertArrayEquals(new byte[]{(byte) 162, 0, 0, 0, 3, + (byte) 128, 0, 0, 0, 0, 0, 0, 7}, + Index.formatIndexId(HugeType.RANGE_LONG_INDEX, + id(3), 7L).asBytes()); + // Frozen Server index-builder-contract.properties stores this hash. + Assert.assertArrayEquals("SI:F:224054a2".getBytes(StandardCharsets.UTF_8), + Index.formatIndexHashId(HugeType.SECONDARY_INDEX, id(15), + "long-field-".repeat(20)).asBytes()); + Assert.assertThrows(IllegalStateException.class, + () -> Index.formatIndexHashId(HugeType.RANGE_INT_INDEX, id(3), 7)); + } + + @Test + public void testLegacyRangeIdParsesWithSchemaType() { + IndexLabel label = label(null); + label.indexType(IndexType.RANGE_INT); + label.indexFields(id(2)); + HugeGraphSupplier graph = graph(label, 100); + Index parsed = Index.parseIndexId(graph, HugeType.RANGE_INT_INDEX, + new byte[]{(byte) 160, 0, 0, 0, 3, + (byte) 128, 0, 0, 7}); + Assert.assertSame(label, parsed.indexLabel()); + Assert.assertEquals(7, parsed.fieldValues()); + } + + @Test + public void testCloneResetKeepsEveryExpirationEntry() { + IndexLabel label = label(null); + Index original = new Index(graph(label, 100), label); + original.fieldValues("value"); + original.elementIds(id(1), 90); + original.elementIds(id(2), 95); + original.elementIds(id(3), 110); + Set expired = original.expiredElementIds(); + Assert.assertEquals(2, expired.size()); + + Index deletion = original.clone(); + Assert.assertEquals(original.id(), deletion.id()); + deletion.resetElementIds(); + for (Index.IdWithExpiredTime entry : expired) { + deletion.elementIds(entry.id(), entry.expiredTime()); + } + Assert.assertEquals(ids(1, 2), deletion.elementIds()); + Assert.assertEquals(ids(3), original.elementIds()); + Set copied = deletion.expiredElementIds(); + long[] times = copied.stream().mapToLong(Index.IdWithExpiredTime::expiredTime).toArray(); + Assert.assertArrayEquals(new long[]{90, 95}, times); + Assert.assertEquals(ids(3), original.elementIds()); + } + + @Test + public void testExpirationBoundaryAndTtl() { + IndexLabel label = label(null); + HugeGraphSupplier graph = graph(label, 100); + Index index = new Index(graph, label(graph)); + index.elementIds(id(1), 0); + index.elementIds(id(2), 99); + index.elementIds(id(3), 100); + index.elementIds(id(4), 101); + Assert.assertEquals(1, index.expiredElementIds().size()); + Assert.assertEquals(ids(1, 3, 4), index.elementIds()); + index.resetElementIds(); + index.elementIds(id(4), 101); + Assert.assertTrue(index.hasTtl()); + Assert.assertEquals(1, index.ttl()); + Assert.assertEquals(101, index.expiredTime()); + } + + @Test + public void testSystemIndexDoesNotAcquirePropertyTtl() { + HugeGraphSupplier graph = graph(label(null), 100); + Index index = new Index(graph, IndexLabel.label(HugeType.VERTEX)); + index.elementIds(id(1), 120); + Assert.assertFalse(index.hasTtl()); + Assert.assertEquals(120, index.expiredTime()); + } + + @Test + public void testWriteModeResetAndExpiration() { + IndexLabel label = label(null); + Index index = new Index(graph(label, 100), label, true); + index.elementIds(id(1), 99); + Assert.assertEquals(1, index.expiredElementIds().size()); + Assert.assertThrows(IllegalStateException.class, index::elementId); + index.elementIds(id(2), 150); + Index clone = index.clone(); + clone.resetElementIds(); + clone.elementIds(id(3), 160); + Assert.assertEquals(id(2), index.elementId()); + Assert.assertEquals(150, index.expiredTime()); + Assert.assertEquals(id(3), clone.elementId()); + Assert.assertEquals(160, clone.expiredTime()); + Assert.assertTrue(clone.expiredElementIds().isEmpty()); + } + + private static Id id(long value) { + return IdGenerator.of(value); + } + + private static Set ids(long... values) { + Set result = new LinkedHashSet<>(); + Arrays.stream(values).mapToObj(SharedIndexTest::id).forEach(result::add); + return result; + } + + private static IndexLabel label(HugeGraphSupplier graph) { + IndexLabel label = new IndexLabel(graph, id(3), "by_value"); + label.baseType(HugeType.VERTEX_LABEL); + label.baseValue(id(1)); + label.indexType(IndexType.SECONDARY); + return label; + } + + private static HugeGraphSupplier graph(IndexLabel label, long now) { + final HugeGraphSupplier[] holder = new HugeGraphSupplier[1]; + holder[0] = (HugeGraphSupplier) Proxy.newProxyInstance( + HugeGraphSupplier.class.getClassLoader(), new Class[]{HugeGraphSupplier.class}, + (proxy, method, args) -> { + switch (method.getName()) { + case "now": + return now; + case "indexLabel": + return label; + case "vertexLabel": + VertexLabel vertexLabel = new VertexLabel(holder[0], id(1), "person"); + vertexLabel.ttl(1000); + return vertexLabel; + case "propertyKey": + PropertyKey key = new PropertyKey(holder[0], id(2), "value"); + key.dataType(DataType.INT); + return key; + default: + throw new UnsupportedOperationException(method.getName()); + } + }); + return holder[0]; + } +} diff --git a/hugegraph-struct/src/test/java/org/apache/hugegraph/structure/builder/IndexBuilderTest.java b/hugegraph-struct/src/test/java/org/apache/hugegraph/structure/builder/IndexBuilderTest.java new file mode 100644 index 0000000000..775c261cee --- /dev/null +++ b/hugegraph-struct/src/test/java/org/apache/hugegraph/structure/builder/IndexBuilderTest.java @@ -0,0 +1,284 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.structure.builder; + +import java.lang.reflect.Proxy; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.hugegraph.HugeGraphSupplier; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.query.MatchedIndex; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.EdgeLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; +import org.apache.hugegraph.structure.BaseVertex; +import org.apache.hugegraph.structure.BaseEdge; +import org.apache.hugegraph.structure.Index; +import org.apache.hugegraph.type.HugeType; +import org.apache.hugegraph.type.define.Cardinality; +import org.apache.hugegraph.type.define.DataType; +import org.apache.hugegraph.type.define.IndexType; +import org.apache.hugegraph.type.define.WriteType; +import org.apache.hugegraph.type.define.Directions; +import org.apache.hugegraph.type.define.EdgeLabelType; +import org.junit.Assert; +import org.junit.Test; + +public class IndexBuilderTest { + + @Test + public void testSearchIncludesOriginalTextAndIgnoresReservedSymbols() { + IndexBuilder builder = new IndexBuilder(supplier(), text -> Set.of("alpha", "beta", "\u0001", "\u0002")); + Assert.assertEquals(Set.of("alpha", "beta", "alpha beta"), builder.segmentWords("alpha beta")); + } + + @Test + public void testExplicitSearchWordsBypassAnalyzer() { + AtomicInteger calls = new AtomicInteger(); + IndexBuilder builder = new IndexBuilder(supplier(), text -> { + calls.incrementAndGet(); + return Set.of("analyzed"); + }); + Assert.assertEquals(Set.of("alpha", "beta"), builder.segmentWords("(alpha|beta|alpha)")); + Assert.assertEquals(Set.of("alpha"), builder.segmentWords("(alpha)")); + Assert.assertEquals(Set.of(""), builder.segmentWords("()")); + Assert.assertEquals(0, calls.get()); + } + + @Test + public void testSearchExpansionForCollectionIncludesJoinedText() { + HugeGraphSupplier graph = supplier(); + PropertyKey property = property(graph, 1, DataType.TEXT, Cardinality.LIST); + BaseVertex vertex = vertex(graph, property); + vertex.addProperty(property, List.of("alpha", "beta")); + IndexLabel label = index(graph, 1, IndexType.SEARCH, property); + IndexBuilder builder = new IndexBuilder(graph, text -> Set.of("alpha", "beta")); + Set words = new HashSet<>(); + builder.forEachIndex(vertex, label, index -> words.add(index.fieldValues())); + Assert.assertEquals(Set.of("alpha", "beta", "alpha beta"), words); + Assert.assertEquals("alpha beta", IndexBuilder.propertyValueToString(List.of("alpha", "beta"))); + } + + @Test + public void testNullablePrefixAndUniqueNullExpansion() { + HugeGraphSupplier graph = supplier(); + PropertyKey first = property(graph, 1, DataType.TEXT, Cardinality.SINGLE); + PropertyKey missing = property(graph, 2, DataType.TEXT, Cardinality.SINGLE); + PropertyKey last = property(graph, 3, DataType.TEXT, Cardinality.SINGLE); + BaseVertex vertex = vertex(graph, first, missing, last); + vertex.schemaLabel().nullableKeys(missing.id()); + vertex.addProperty(first, "first"); + vertex.addProperty(last, "last"); + IndexBuilder builder = new IndexBuilder(graph, text -> Set.of(text)); + IndexLabel secondary = index(graph, 1, IndexType.SECONDARY, first, missing, last); + List indexes = builder.buildIndex(vertex, secondary); + Assert.assertEquals(1, indexes.size()); + Assert.assertEquals("first", indexes.get(0).fieldValues()); + IndexLabel unique = index(graph, 2, IndexType.UNIQUE, first, missing, last); + Assert.assertEquals("first!\u0001!last", builder.buildIndex(vertex, unique).get(0).fieldValues()); + } + + @Test + public void testCollectionSecondaryExpansionPreservesDuplicateValuesAndExpiry() { + HugeGraphSupplier graph = supplier(); + PropertyKey property = property(graph, 1, DataType.INT, Cardinality.LIST); + BaseVertex vertex = vertex(graph, property); + vertex.addProperty(property, List.of(7, -1, 7)); + vertex.expiredTime(123L); + IndexLabel label = index(graph, 1, IndexType.SECONDARY, property); + List indexes = new ArrayList<>(); + new IndexBuilder(graph, text -> Set.of(text)).forEachIndex(vertex, label, indexes::add); + Assert.assertEquals(3, indexes.size()); + Assert.assertEquals(indexes.get(0).fieldValues(), indexes.get(2).fieldValues()); + Assert.assertNotEquals(indexes.get(0).fieldValues(), indexes.get(1).fieldValues()); + for (Index index : indexes) { + Assert.assertEquals(vertex.id(), index.elementId()); + Assert.assertEquals(123L, index.expiredTime()); + } + } + + @Test + public void testStoreRebuildIncludesParentIndexesAndPreservesSelectorOrderAndDuplicates() { + Map labels = new HashMap<>(); + Map indexes = new HashMap<>(); + HugeGraphSupplier graph = supplier(labels, indexes); + PropertyKey inherited = property(graph, 1, DataType.TEXT, Cardinality.SINGLE); + PropertyKey own = property(graph, 2, DataType.TEXT, Cardinality.SINGLE); + EdgeLabel parent = new EdgeLabel(graph, IdGenerator.of(3), "parent"); + parent.enableLabelIndex(false); + EdgeLabel child = new EdgeLabel(graph, IdGenerator.of(4), "child"); + child.edgeLabelType(EdgeLabelType.SUB); + child.fatherId(parent.id()); + child.enableLabelIndex(false); + labels.put(parent.id(), parent); + IndexLabel parentIndex = index(graph, 11, IndexType.SECONDARY, inherited); + parentIndex.baseType(HugeType.EDGE_LABEL); + parentIndex.baseValue(parent.id()); + IndexLabel childIndex = index(graph, 12, IndexType.SECONDARY, own); + childIndex.baseType(HugeType.EDGE_LABEL); + childIndex.baseValue(child.id()); + indexes.put(parentIndex.id(), parentIndex); + indexes.put(childIndex.id(), childIndex); + parent.indexLabels(parentIndex.id()); + child.indexLabels(childIndex.id()); + BaseEdge edge = new BaseEdge(new EdgeId(IdGenerator.of(1), Directions.OUT, parent.id(), child.id(), + "", IdGenerator.of(2)), child); + edge.isOutEdge(true); + edge.addProperty(inherited, "parent value"); + edge.addProperty(own, "child value"); + IndexBuilder builder = new IndexBuilder(graph, text -> Set.of(text)); + List rebuilt = builder.buildEdgeIndex(edge); + Assert.assertEquals(2, rebuilt.size()); + Assert.assertEquals(childIndex.id(), rebuilt.get(0).indexLabelId()); + Assert.assertEquals("child value", rebuilt.get(0).fieldValues()); + Assert.assertEquals(parentIndex.id(), rebuilt.get(1).indexLabelId()); + Assert.assertEquals("parent value", rebuilt.get(1).fieldValues()); + + child.indexLabels(parentIndex.id()); + List selected = new ArrayList<>(); + IndexBuilder.forEachIndexLabelId(edge, labels::get, selected::add); + List expected = new ArrayList<>(child.indexLabels()); + expected.addAll(parent.indexLabels()); + Assert.assertEquals(expected, selected); + Assert.assertEquals(2L, selected.stream().filter(parentIndex.id()::equals).count()); + Assert.assertEquals(3, builder.buildEdgeIndex(edge).size()); + } + + @Test + public void testOlapSelectorUsesProvidedStagedCandidates() { + HugeGraphSupplier graph = supplier(); + PropertyKey property = property(graph, 1, DataType.INT, Cardinality.SINGLE); + property.writeType(WriteType.OLAP_COMMON); + PropertyKey unrelated = property(graph, 2, DataType.INT, Cardinality.SINGLE); + BaseVertex vertex = new BaseVertex(IdGenerator.of(1), VertexLabel.OLAP_VL); + vertex.addProperty(property, 42); + IndexLabel staged = index(graph, 11, IndexType.RANGE_INT, property); + IndexLabel other = index(graph, 12, IndexType.RANGE_INT, unrelated); + List selected = new ArrayList<>(); + // The supplier has no index list; the caller's transaction candidates are authoritative. + IndexBuilder.forEachOlapIndexLabelId(vertex, List.of(other, staged), selected::add); + Assert.assertEquals(List.of(staged.id()), selected); + } + + @Test + public void testOlapSelectorRejectsZeroOrMultiplePropertiesBeforeCandidateTraversal() { + HugeGraphSupplier graph = supplier(); + BaseVertex vertex = new BaseVertex(IdGenerator.of(1), VertexLabel.OLAP_VL); + AtomicInteger traversals = new AtomicInteger(); + Iterable candidates = () -> { + traversals.incrementAndGet(); + return List.of().iterator(); + }; + assertInvalidOlap(vertex, candidates); + vertex.addProperty(property(graph, 1, DataType.INT, Cardinality.SINGLE), 42); + vertex.addProperty(property(graph, 2, DataType.INT, Cardinality.SINGLE), 43); + assertInvalidOlap(vertex, candidates); + Assert.assertEquals(0, traversals.get()); + } + + private static void assertInvalidOlap(BaseVertex vertex, Iterable candidates) { + try { + IndexBuilder.forEachOlapIndexLabelId(vertex, candidates, id -> Assert.fail("Unexpected selected index")); + Assert.fail("Olap selector must require exactly one property"); + } catch (IllegalArgumentException expected) { + Assert.assertTrue(expected.getMessage().contains("Expect only 1 property")); + } + } + + @Test + public void testMatchedIndexRetainsEngineEqualityAndReadOnlyLabels() { + HugeGraphSupplier graph = supplier(); + VertexLabel first = new VertexLabel(graph, IdGenerator.of(1), "first"); + VertexLabel second = new VertexLabel(graph, IdGenerator.of(2), "second"); + PropertyKey property = property(graph, 1, DataType.TEXT, Cardinality.SINGLE); + IndexLabel search = index(graph, 1, IndexType.SEARCH, property); + MatchedIndex match = new MatchedIndex(first, Set.of(search)); + MatchedIndex equal = new MatchedIndex(second, Set.of(search)); + Assert.assertEquals(match, equal); + Assert.assertEquals(match.hashCode(), equal.hashCode()); + Assert.assertTrue(match.containsSearchIndex()); + try { + match.indexLabels().clear(); + Assert.fail("Matched labels must remain read-only"); + } catch (UnsupportedOperationException expected) { + Assert.assertEquals(Set.of(search), match.indexLabels()); + } + } + + private static HugeGraphSupplier supplier() { + return supplier(Map.of(), Map.of()); + } + + private static HugeGraphSupplier supplier(Map labels, Map indexes) { + return (HugeGraphSupplier) Proxy.newProxyInstance(HugeGraphSupplier.class.getClassLoader(), + new Class[]{HugeGraphSupplier.class}, (proxy, method, args) -> { + switch (method.getName()) { + case "name": + case "toString": + return "index-builder-test"; + case "now": + return 0L; + case "edgeLabel": + return labels.get(args[0]); + case "indexLabel": + return indexes.get(args[0]); + case "hashCode": + return System.identityHashCode(proxy); + case "equals": + return proxy == args[0]; + default: + return null; + } + }); + } + + private static PropertyKey property(HugeGraphSupplier graph, int value, DataType type, Cardinality cardinality) { + PropertyKey property = new PropertyKey(graph, IdGenerator.of(value), "property" + value); + property.dataType(type); + property.cardinality(cardinality); + return property; + } + + private static BaseVertex vertex(HugeGraphSupplier graph, PropertyKey... properties) { + VertexLabel label = new VertexLabel(graph, IdGenerator.of(1), "vertex"); + for (PropertyKey property : properties) { + label.properties(Set.of(property.id())); + } + return new BaseVertex(IdGenerator.of(1), label); + } + + private static IndexLabel index(HugeGraphSupplier graph, int value, IndexType type, PropertyKey... fields) { + IndexLabel label = new IndexLabel(graph, IdGenerator.of(value), "index" + value); + label.baseType(HugeType.VERTEX_LABEL); + label.baseValue(IdGenerator.of(1)); + label.indexType(type); + for (PropertyKey property : fields) { + label.indexField(property.id()); + } + return label; + } +} diff --git a/hugegraph-struct/src/test/java/org/apache/hugegraph/type/SharedTypeCompatibilityTest.java b/hugegraph-struct/src/test/java/org/apache/hugegraph/type/SharedTypeCompatibilityTest.java new file mode 100644 index 0000000000..a1f08ef3ea --- /dev/null +++ b/hugegraph-struct/src/test/java/org/apache/hugegraph/type/SharedTypeCompatibilityTest.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.type; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import org.apache.hugegraph.type.define.Cardinality; +import org.apache.hugegraph.type.define.Directions; +import org.apache.hugegraph.type.define.EdgeLabelType; +import org.apache.hugegraph.type.define.HugeKeys; +import org.apache.hugegraph.type.define.SchemaStatus; +import org.apache.hugegraph.type.define.SerialEnum; +import org.junit.Assert; +import org.junit.Test; + +public class SharedTypeCompatibilityTest { + + @Test + public void testStoredTypeAndSchemaCodesRemainReadable() { + Assert.assertEquals(HugeType.VERTEX, HugeType.fromCode((byte) 101)); + Assert.assertEquals(HugeType.EDGE_OUT, HugeType.fromCode((byte) 130)); + Assert.assertEquals(HugeType.EDGE_IN, HugeType.fromCode((byte) 140)); + Assert.assertEquals(HugeType.OLAP, HugeType.fromCode((byte) 106)); + Assert.assertEquals(HugeType.UNIQUE_INDEX, HugeType.fromCode((byte) 178)); + Assert.assertEquals(HugeType.SYS_SCHEMA, HugeType.fromCode((byte) 250)); + Assert.assertEquals(HugeType.MAX_TYPE, HugeType.fromCode((byte) 255)); + Assert.assertEquals((byte) 211, HugeKeys.SUB_LABEL.code()); + Assert.assertEquals((byte) 250, HugeKeys.AGGREGATE_PROPERTIES.code()); + Assert.assertEquals(EdgeLabelType.GENERAL, + SerialEnum.fromCode(EdgeLabelType.class, (byte) 4)); + Assert.assertEquals(SchemaStatus.CLEARING, + SerialEnum.fromCode(SchemaStatus.class, (byte) 7)); + Assert.assertEquals(Cardinality.SET, + SerialEnum.fromCode(Cardinality.class, (byte) 3)); + Assert.assertEquals(Directions.IN, + SerialEnum.fromCode(Directions.class, (byte) 2)); + } + + @Test + public void testLazyAndConcurrentEnumRegistration() throws Exception { + // This extension does not call register() in a static initializer. + Assert.assertEquals(ExtensionType.VALUE, + SerialEnum.fromCode(ExtensionType.class, (byte) 42)); + ExecutorService executor = Executors.newFixedThreadPool(4); + try { + List> tasks = new ArrayList<>(); + for (int thread = 0; thread < 4; thread++) { + tasks.add(() -> { + for (int iteration = 0; iteration < 1000; iteration++) { + SerialEnum.register(Cardinality.class); + SerialEnum.register(ExtensionType.class); + Assert.assertEquals(Cardinality.LIST, + SerialEnum.fromCode(Cardinality.class, (byte) 2)); + Assert.assertEquals(ExtensionType.VALUE, + SerialEnum.fromCode(ExtensionType.class, (byte) 42)); + } + return null; + }); + } + List> results = executor.invokeAll(tasks, 10, TimeUnit.SECONDS); + for (Future result : results) { + Assert.assertFalse("Enum registration timed out", result.isCancelled()); + result.get(); + } + } finally { + executor.shutdownNow(); + } + } + + public enum ExtensionType implements SerialEnum { + VALUE; + + @Override + public byte code() { + return 42; + } + } +} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/NotSupportException.java b/hugegraph-struct/src/test/java/org/apache/hugegraph/util/UnsafeUtilTest.java similarity index 53% rename from hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/NotSupportException.java rename to hugegraph-struct/src/test/java/org/apache/hugegraph/util/UnsafeUtilTest.java index 50148f6b00..b948ea89b3 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/NotSupportException.java +++ b/hugegraph-struct/src/test/java/org/apache/hugegraph/util/UnsafeUtilTest.java @@ -15,20 +15,30 @@ * limitations under the License. */ -package org.apache.hugegraph.exception; +package org.apache.hugegraph.util; -import org.apache.hugegraph.HugeException; +import org.apache.hugegraph.util.collection.IntSet; +import org.junit.Assert; +import org.junit.Test; -public class NotSupportException extends HugeException { +import sun.misc.Unsafe; - private static final long serialVersionUID = -2914329541122906234L; - private static final String PREFIX = "Not support "; +public class UnsafeUtilTest { - public NotSupportException(String message) { - super(PREFIX + message); + @Test + public void testCollectionsShareUnsafeInstance() { + Assert.assertSame(UnsafeUtil.getUnsafe(), IntSet.UNSAFE); } - public NotSupportException(String message, Object... args) { - super(PREFIX + message, args); + @Test + public void testNativeMemoryReadWrite() { + Unsafe unsafe = UnsafeUtil.getUnsafe(); + long address = unsafe.allocateMemory(Long.BYTES); + try { + unsafe.putLong(address, 0x0123456789abcdefL); + Assert.assertEquals(0x0123456789abcdefL, unsafe.getLong(address)); + } finally { + unsafe.freeMemory(address); + } } } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/LimitExceedException.java b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/CanonicalRelationEnum.java.txt similarity index 66% rename from hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/LimitExceedException.java rename to hugegraph-struct/src/test/resources/compatibility/2f827d6e8/CanonicalRelationEnum.java.txt index 1c2950f11c..deba9a81f2 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/exception/LimitExceedException.java +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/CanonicalRelationEnum.java.txt @@ -14,20 +14,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -package org.apache.hugegraph.exception; - -import org.apache.hugegraph.HugeException; - -public class LimitExceedException extends HugeException { - - private static final long serialVersionUID = 7384276720045597709L; - - public LimitExceedException(String message) { - super(message); - } - - public LimitExceedException(String message, Object... args) { - super(message, args); - } -} +package org.apache.hugegraph.query; public class Condition { public enum RelationType {EQ,GT,GTE,LT,LTE,NEQ,IN,NOT_IN,PREFIX,TEXT_ANALYZER_CONTAINS,TEXT_CONTAINS,TEXT_MATCH_REGEX,TEXT_MATCH_EDIT_DISTANCE,TEXT_NOT_CONTAINS,TEXT_PREFIX,TEXT_NOT_PREFIX,TEXT_SUFFIX,TEXT_NOT_SUFFIX,TEXT_CONTAINS_ANY,CONTAINS,CONTAINS_VALUE,CONTAINS_KEY,TEXT_CONTAINS_FUZZY,TEXT_FUZZY,TEXT_CONTAINS_REGEX,TEXT_REGEX,SCAN} } diff --git a/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyCodecFixtureWriter.java.txt b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyCodecFixtureWriter.java.txt new file mode 100644 index 0000000000..f53b5b36af --- /dev/null +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyCodecFixtureWriter.java.txt @@ -0,0 +1,181 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy 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. + */ +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.UUID; +import org.apache.hugegraph.backend.id.EdgeId; +import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.backend.query.Aggregate.AggregateFunc; +import org.apache.hugegraph.backend.query.Condition; +import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.backend.serializer.BinaryBackendEntry.BinaryId; +import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.type.HugeType; +import org.apache.hugegraph.type.define.DataType; +import org.apache.hugegraph.type.define.Cardinality; +import org.apache.hugegraph.type.define.Directions; +import org.apache.hugegraph.type.define.HugeKeys; + +public class LegacyCodecFixtureWriter { + private static final String LICENSE = + "Licensed to the Apache Software Foundation (ASF) under one or more\n" + + "contributor license agreements. See the NOTICE file distributed with\n" + + "this work for additional information regarding copyright ownership.\n" + + "The ASF licenses this file to You under the Apache License, Version 2.0\n" + + "(the \"License\"); you may not use this file except in compliance with\n" + + "the License. You may obtain a copy of the License at\n\n" + + " http://www.apache.org/licenses/LICENSE-2.0\n\n" + + "Unless required by applicable law or agreed to in writing, software\n" + + "distributed under the License is distributed on an \"AS IS\" BASIS,\n" + + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" + + "See the License for the specific language governing permissions and\n" + + "limitations under the License.\n"; + private static final Map HEX = new LinkedHashMap<>(); + + public static void main(String[] args) throws Exception { + Path output = Path.of(args[0]); + Files.createDirectories(output); + System.out.println("Writer loaded from " + BytesBuffer.class.getProtectionDomain() + .getCodeSource().getLocation()); + long[] values = {Long.MIN_VALUE, -16385L, -16384L, -129L, -128L, -1L, + 0L, 1L, 127L, 128L, 16383L, 16384L, Long.MAX_VALUE}; + for (long value : values) { + put("id.long." + value, BytesBuffer.allocate(64).writeId(IdGenerator.of(value))); + put("vlong." + value, BytesBuffer.allocate(64).writeVLong(value)); + } + int[] ints = {Integer.MIN_VALUE, -129, -1, 0, 127, 128, 16383, 16384, + Integer.MAX_VALUE}; + for (int value : ints) { + put("vint." + value, BytesBuffer.allocate(64).writeVInt(value)); + } + put("id.text", BytesBuffer.allocate(64).writeId(IdGenerator.of("alice"))); + put("id.unicode", BytesBuffer.allocate(64).writeId(IdGenerator.of("顶点😀"))); + for (int length : new int[]{1, 64, 65, 256, 257, 16384}) { + put("id.text.length." + length, + BytesBuffer.allocate(64).writeId(IdGenerator.of("x".repeat(length)))); + } + put("id.uuid", BytesBuffer.allocate(64).writeId(IdGenerator.of( + UUID.fromString("01234567-89ab-cdef-0123-456789abcdef")))); + Id edge = new EdgeId(IdGenerator.of("alice"), Directions.OUT, IdGenerator.of(3L), + IdGenerator.of(4L), "2026!x", IdGenerator.of(99L)); + put("edge.out", BytesBuffer.allocate(128).writeEdgeId(edge)); + edge = new EdgeId(IdGenerator.of(99L), Directions.IN, IdGenerator.of(3L), + IdGenerator.of(4L), "2026!x", IdGenerator.of("alice")); + put("edge.in", BytesBuffer.allocate(128).writeEdgeId(edge)); + scalar("BOOLEAN", DataType.BOOLEAN, true); + scalar("BYTE", DataType.BYTE, (byte) -7); + scalar("INT", DataType.INT, -123456); + scalar("LONG", DataType.LONG, Long.MIN_VALUE); + scalar("FLOAT", DataType.FLOAT, 1.25f); + scalar("DOUBLE", DataType.DOUBLE, -123.125d); + scalar("DATE", DataType.DATE, new Date(1609459200123L)); + scalar("TEXT", DataType.TEXT, "属性😀\u0000"); + scalar("BLOB", DataType.BLOB, new byte[]{0, -1, 1, 127, -128}); + scalar("UUID", DataType.UUID, + UUID.fromString("01234567-89ab-cdef-0123-456789abcdef")); + scalar("OBJECT", DataType.OBJECT, new ArrayList<>(Arrays.asList("legacy", 7, true))); + scalar("UNKNOWN", DataType.UNKNOWN, "legacy-object"); + scalar("OBJECT_UNSUPPORTED_COLLECTION", DataType.OBJECT, Arrays.asList("legacy", 7, true)); + PropertyKey propertyKey = new PropertyKey(null, IdGenerator.of(101L), "legacy"); + propertyKey.dataType(DataType.INT); + schemaProperty("single", propertyKey, Cardinality.SINGLE, 7); + schemaProperty("list", propertyKey, Cardinality.LIST, Arrays.asList(7, -1, 7)); + schemaProperty("set", propertyKey, Cardinality.SET, + new LinkedHashSet<>(Arrays.asList(7, -1))); + byte[] stringIndex = "label!alice".getBytes(StandardCharsets.UTF_8); + put("index.string", BytesBuffer.allocate(64).writeIndexId( + new BinaryId(stringIndex, null), HugeType.SECONDARY_INDEX)); + byte[] intIndex = {(byte) 160, 0, 0, 0, 3, (byte) 128, 0, 0, 7}; + put("index.int", BytesBuffer.allocate(64).writeIndexId( + new BinaryId(intIndex, null), HugeType.RANGE_INT_INDEX)); + byte[] longIndex = {(byte) 162, 0, 0, 0, 3, (byte) 128, 0, 0, 0, 0, 0, 0, 7}; + put("index.long", BytesBuffer.allocate(64).writeIndexId( + new BinaryId(longIndex, null), HugeType.RANGE_LONG_INDEX)); + StringBuilder encoded = new StringBuilder("# " + LICENSE.replace("\n", "\n# ") + "\n"); + for (Map.Entry fixture : HEX.entrySet()) { + String line = fixture.getKey() + "=" + fixture.getValue(); + for (int start = 0; start < line.length(); start += 100) { + int end = Math.min(start + 100, line.length()); + encoded.append(line, start, end); + if (end < line.length()) { + encoded.append('\\'); + } + encoded.append('\n'); + } + } + Files.writeString(output.resolve("core-codecs.hex"), encoded.toString().replaceAll("(?m)[ \t]+$", ""), + StandardCharsets.UTF_8); + + ConditionQuery query = new ConditionQuery(HugeType.VERTEX); + query.eq(HugeKeys.LABEL, IdGenerator.of(3L)); + query.query(Condition.gte(IdGenerator.of(11L), 18)); + query.query(Condition.in(IdGenerator.of(12L), Arrays.asList(20L, 30L))); + query.query(Condition.eq(IdGenerator.of(13L), new Date(1609459200123L))); + query.query(Condition.or(Condition.eq(IdGenerator.of(14L), "alice"), + Condition.eq(IdGenerator.of(14L), "bob"))); + query.offset(7); + query.limit(19); + writeQuery(output, "core-query.json.txt", query); + ConditionQuery edgeQuery = new ConditionQuery(HugeType.EDGE); + edgeQuery.eq(HugeKeys.OWNER_VERTEX, IdGenerator.of("alice")); + edgeQuery.eq(HugeKeys.DIRECTION, Directions.OUT); + edgeQuery.eq(HugeKeys.LABEL, IdGenerator.of(3L)); + edgeQuery.page("AQIDBA=="); + edgeQuery.limit(5); + writeQuery(output, "core-edge-query.json.txt", edgeQuery); + ConditionQuery countQuery = new ConditionQuery(HugeType.VERTEX); + countQuery.aggregate(AggregateFunc.COUNT, null); + writeQuery(output, "core-count-query.json.txt", countQuery); + ConditionQuery avgQuery = new ConditionQuery(HugeType.VERTEX); + avgQuery.eq(HugeKeys.LABEL, IdGenerator.of(3L)); + avgQuery.aggregate(AggregateFunc.AVG, "age"); + writeQuery(output, "core-avg-query.json.txt", avgQuery); + System.out.println("Generated " + HEX.size() + " byte fixtures and 4 query fixtures"); + } + + private static void writeQuery(Path output, String name, ConditionQuery query) + throws Exception { + String prolog = "/*\n" + LICENSE + "*/\n"; + String payload = new String(query.bytes(), StandardCharsets.UTF_8); + Files.writeString(output.resolve(name), prolog + payload + "\n", StandardCharsets.UTF_8); + } + + private static void schemaProperty(String name, PropertyKey key, + Cardinality cardinality, Object value) { + key.cardinality(cardinality); + put("schema." + name, BytesBuffer.allocate(64).writeProperty(key, value)); + } + + private static void scalar(String name, DataType type, Object value) { + BytesBuffer buffer = BytesBuffer.allocate(128); + buffer.writeProperty(type, value); + put("property." + name, buffer); + } + + private static void put(String name, BytesBuffer buffer) { + StringBuilder hex = new StringBuilder(); + for (byte value : buffer.bytes()) { + hex.append(String.format("%02x", value & 0xff)); + } + HEX.put(name, hex.toString()); + } +} diff --git a/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyKryoFixtureWriter.java.txt b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyKryoFixtureWriter.java.txt new file mode 100644 index 0000000000..d2e75af556 --- /dev/null +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyKryoFixtureWriter.java.txt @@ -0,0 +1,189 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.lang.reflect.Array; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.UUID; +import org.apache.hugegraph.backend.id.EdgeId; +import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.backend.query.Aggregate; +import org.apache.hugegraph.backend.query.Condition; +import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.backend.serializer.BinaryBackendEntry.BinaryId; +import org.apache.hugegraph.backend.serializer.BytesBuffer; +import org.apache.hugegraph.backend.store.Shard; +import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.schema.EdgeLabel; +import org.apache.hugegraph.schema.IndexLabel; +import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.schema.Userdata; +import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.structure.GraphType; +import org.apache.hugegraph.type.define.DataType; +import org.apache.hugegraph.type.define.Directions; + +public class LegacyKryoFixtureWriter { + private static final Map OUTPUT = new LinkedHashMap<>(); + + public static void main(String[] args) throws Exception { + System.out.println("Kryo fixture writer loaded from " + BytesBuffer.class + .getProtectionDomain().getCodeSource().getLocation()); + Id longId = IdGenerator.of(7L); + Id stringId = IdGenerator.of("legacy-id"); + Id uuidId = IdGenerator.of(UUID.fromString("01234567-89ab-cdef-0123-456789abcdef")); + Id edgeId = new EdgeId(longId, Directions.OUT, IdGenerator.of(3L), + IdGenerator.of(4L), "sort", stringId); + Object[] instances = {longId, stringId, uuidId, edgeId, + new BinaryId(new byte[]{1, 2, 3}, longId), + new Shard("start", "end", 12L), + new PropertyKey(null, IdGenerator.of(11L), "age"), + new VertexLabel(null, IdGenerator.of(12L), "person"), + new EdgeLabel(null, IdGenerator.of(13L), "knows"), + new IndexLabel(null, IdGenerator.of(14L), "by-age")}; + String[] names = {"long_id", "string_id", "uuid_id", "edge_id", "binary_id", "shard", + "property_key", "vertex_label", "edge_label", "index_label"}; + for (int i = 0; i < names.length; i++) { + capture(names[i], instances[i]); + } + capture("aggregate_func", Aggregate.AggregateFunc.AVG); + capture("relation_type", Condition.RelationType.GTE); + capture("condition_type", Condition.ConditionType.OR); + capture("query_order", Query.Order.DESC); + capture("query_order_type", Query.OrderType.ORDER_STRICT); + capture("optimized_type", ConditionQuery.OptimizedType.INDEX_FILTER); + capture("id_type", Id.IdType.UUID); + capture("graph_type_class", GraphType.class); + capture("id_array", new Id[]{null}); + capture("id_matrix", new Id[][]{new Id[]{null}, new Id[0]}); + capture("shard_array", new Shard[]{null}); + capture("schema_array", new PropertyKey[]{null}); + Userdata userdata = new Userdata(); + userdata.put("tag", "legacy"); + userdata.put("count", 7); + userdata.put(Userdata.CREATE_TIME, new Date(1609459200123L)); + capture("userdata", userdata); + BackendColumn column = BackendColumn.of(new byte[]{1, 2}, new byte[]{3, 4}); + capture("backend_column", column); + capture("backend_column_array", new BackendColumn[]{column, null}); + capture("backend_column_class", BackendColumn.class); + ArrayList> classes = new ArrayList<>(); + for (Object instance : instances) { + classes.add(instance.getClass()); + } + capture("class_list", classes); + String[] contracts = {"org.apache.hugegraph.type.Nameable", + "org.apache.hugegraph.type.Typeable", + "org.apache.hugegraph.type.Indexable", + "org.apache.hugegraph.type.Propertiable", + "org.apache.hugegraph.backend.id.IdUtil", + "org.apache.hugegraph.backend.id.SplicingIdGenerator", + "org.apache.hugegraph.schema.builder.SchemaBuilder", + "org.apache.hugegraph.backend.query.serializer.AbstractSerializerAdapter", + "org.apache.hugegraph.backend.query.serializer.QueryAdapter", + "org.apache.hugegraph.backend.query.serializer.QueryIdAdapter"}; + ArrayList> contractClasses = new ArrayList<>(); + for (String contract : contracts) { + contractClasses.add(Class.forName(contract)); + } + capture("contract_classes", contractClasses); + String[] schemaNames = {"org.apache.hugegraph.schema.SchemaElement$TaskWithSchema", + "org.apache.hugegraph.schema.PropertyKey$P", + "org.apache.hugegraph.schema.VertexLabel$P", + "org.apache.hugegraph.schema.EdgeLabel$P", + "org.apache.hugegraph.schema.IndexLabel$P", + "org.apache.hugegraph.schema.SchemaElement$P", + "org.apache.hugegraph.schema.PropertyKey$Builder", + "org.apache.hugegraph.schema.VertexLabel$Builder", + "org.apache.hugegraph.schema.EdgeLabel$Builder", + "org.apache.hugegraph.schema.IndexLabel$Builder"}; + ArrayList> schemaClasses = new ArrayList<>(); + ArrayList schemaArrays = new ArrayList<>(); + for (String schemaName : schemaNames) { + Class schemaClass = Class.forName(schemaName); + schemaClasses.add(schemaClass); + schemaArrays.add(Array.newInstance(schemaClass, 1)); + } + capture("schema_nested_classes", schemaClasses); + capture("schema_nested_arrays", schemaArrays); + capture("index_classes", new ArrayList<>(Arrays.asList( + org.apache.hugegraph.structure.HugeIndex.class, + org.apache.hugegraph.structure.HugeIndex.IdWithExpiredTime.class))); + capture("index_array", new org.apache.hugegraph.structure.HugeIndex[]{null}); + capture("expiry_id_array", new org.apache.hugegraph.structure.HugeIndex.IdWithExpiredTime[]{null}); + capture("expiry_id", new org.apache.hugegraph.structure.HugeIndex.IdWithExpiredTime(longId, + 1609459260000L)); + Map nested = new LinkedHashMap<>(); + nested.put("classes", classes); + nested.put("metadata", userdata); + nested.put("ids", new Id[][]{new Id[]{null}, new Id[0]}); + nested.put("predicate", Condition.RelationType.GTE); + nested.put("column", column); + capture("nested", nested); + capture("unsupported_arrays_list", Arrays.asList("legacy", 7, true)); + String source = Files.readString(Path.of(args[1]), StandardCharsets.UTF_8); + String license = source.substring(0, source.indexOf("*/") + 2); + StringBuilder text = new StringBuilder(license.replace("/*", "#") + .replace("*/", "#").replace(" *", "#")).append('\n'); + OUTPUT.forEach((key, value) -> append(text, key + "=" + value)); + Files.writeString(Path.of(args[0]).resolve("core-kryo-objects.properties"), text, + StandardCharsets.UTF_8); + } + + private static void capture(String name, Object value) { + BytesBuffer buffer = BytesBuffer.allocate(128); + buffer.writeProperty(DataType.OBJECT, value); + OUTPUT.put(name + ".hex", hex(buffer.bytes())); + try { + Object decoded = BytesBuffer.wrap(buffer.bytes()).readProperty(DataType.OBJECT); + OUTPUT.put(name + ".baseline_readable", "true"); + OUTPUT.put(name + ".baseline_type", decoded.getClass().getName()); + System.out.println(name + ": baseline readable " + decoded.getClass().getName()); + } catch (RuntimeException error) { + OUTPUT.put(name + ".baseline_readable", "false"); + OUTPUT.put(name + ".baseline_error", error.getClass().getName() + ": " + + error.getMessage().replace('\n', ' ')); + System.out.println(name + ": baseline fails " + error.getMessage().split("\\n")[0]); + } + } + + private static void append(StringBuilder output, String line) { + for (int start = 0; start < line.length(); start += 100) { + int end = Math.min(start + 100, line.length()); + output.append(line, start, end); + if (end < line.length()) { + output.append('\\'); + } + output.append('\n'); + } + } + + private static String hex(byte[] bytes) { + StringBuilder text = new StringBuilder(); + for (byte value : bytes) { + text.append(String.format("%02x", value & 0xff)); + } + return text.toString(); + } +} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/Analyzer.java b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyRelationEnum.java.txt similarity index 79% rename from hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/Analyzer.java rename to hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyRelationEnum.java.txt index 8e7537e072..366bb30d7e 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/analyzer/Analyzer.java +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyRelationEnum.java.txt @@ -14,12 +14,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -package org.apache.hugegraph.analyzer; - -import java.util.Set; - -public interface Analyzer { - - Set segment(String text); -} +package org.apache.hugegraph.backend.query; public class Condition { public enum RelationType {EQ,GT,GTE,LT,LTE,NEQ,IN,NOT_IN,PREFIX,TEXT_CONTAINS,TEXT_CONTAINS_ANY,CONTAINS,CONTAINS_VALUE,CONTAINS_KEY,SCAN} } diff --git a/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyRowFixtureWriter.java.txt b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyRowFixtureWriter.java.txt new file mode 100644 index 0000000000..abf389945d --- /dev/null +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyRowFixtureWriter.java.txt @@ -0,0 +1,263 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.lang.reflect.Proxy; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.hugegraph.HugeGraph; +import org.apache.hugegraph.backend.id.EdgeId; +import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.backend.serializer.BinarySerializer; +import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.type.define.HugeKeys; +import org.apache.hugegraph.backend.store.BackendEntry; +import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; +import org.apache.hugegraph.schema.EdgeLabel; +import org.apache.hugegraph.schema.IndexLabel; +import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.structure.HugeEdge; +import org.apache.hugegraph.structure.HugeElement; +import org.apache.hugegraph.structure.HugeIndex; +import org.apache.hugegraph.structure.HugeVertex; +import org.apache.hugegraph.type.HugeType; +import org.apache.hugegraph.type.define.Cardinality; +import org.apache.hugegraph.type.define.DataType; +import org.apache.hugegraph.type.define.Directions; +import org.apache.hugegraph.type.define.Frequency; +import org.apache.hugegraph.type.define.IndexType; +import org.apache.hugegraph.type.define.WriteType; + +public class LegacyRowFixtureWriter { + private static final long NOW = 1609459200000L; + private static final long EXPIRY = NOW + 60000L; + private static final Map PROPERTIES = new HashMap<>(); + private static final Map VERTICES = new HashMap<>(); + private static final Map EDGES = new HashMap<>(); + private static final Map INDEXES = new HashMap<>(); + private static HugeGraph fixtureGraph; + private static FixtureSerializer fixtureSerializer; + private static final Map ROWS = new LinkedHashMap<>(); + + public static void main(String[] args) throws Exception { + HugeGraph graph = (HugeGraph) Proxy.newProxyInstance( + HugeGraph.class.getClassLoader(), new Class[]{HugeGraph.class}, + (proxy, method, values) -> { + switch (method.getName()) { + case "now": return NOW; + case "name": return "legacy-fixture"; + case "hugegraph": return proxy; + case "propertyKey": return PROPERTIES.get(((Id) values[0]).asLong()); + case "vertexLabel": + case "vertexLabelOrNone": return VERTICES.get(((Id) values[0]).asLong()); + case "edgeLabel": + case "edgeLabelOrNone": return EDGES.get(((Id) values[0]).asLong()); + case "indexLabel": return INDEXES.get(((Id) values[0]).asLong()); + default: throw new AssertionError("Unexpected graph call: " + method); + } + }); + fixtureGraph = graph; + PropertyKey single = property(graph, 1, "age", Cardinality.SINGLE); + PropertyKey list = property(graph, 2, "scores", Cardinality.LIST); + PropertyKey set = property(graph, 3, "groups", Cardinality.SET); + VertexLabel vertexLabel = new VertexLabel(graph, IdGenerator.of(4L), "person"); + vertexLabel.ttl(60000L); + vertexLabel.properties(single.id(), list.id(), set.id()); + VERTICES.put(4L, vertexLabel); + EdgeLabel edgeLabel = new EdgeLabel(graph, IdGenerator.of(5L), "knows"); + edgeLabel.ttl(60000L); + edgeLabel.frequency(Frequency.MULTIPLE); + edgeLabel.links(Pair.of(vertexLabel.id(), vertexLabel.id())); + edgeLabel.properties(single.id(), list.id(), set.id()); + EDGES.put(5L, edgeLabel); + HugeVertex source = new HugeVertex(graph, IdGenerator.of(1L), vertexLabel); + HugeVertex target = new HugeVertex(graph, IdGenerator.of(2L), vertexLabel); + fill(source, single, list, set); + source.expiredTime(EXPIRY); + FixtureSerializer serializer = new FixtureSerializer(); + fixtureSerializer = serializer; + System.out.println("Row writer loaded from " + BinarySerializer.class.getProtectionDomain() + .getCodeSource().getLocation()); + row("vertex", serializer.writeVertex(source)); + HugeEdge edge = new HugeEdge(graph, + new EdgeId(source.id(), Directions.OUT, edgeLabel.id(), edgeLabel.id(), + "2026!x", target.id()), edgeLabel); + edge.vertices(true, source, target); + fill(edge, single, list, set); + edge.expiredTime(EXPIRY); + row("edge.out", serializer.writeEdge(edge)); + row("edge.in", serializer.writeEdge(edge.switchOwner())); + PropertyKey olapKey = property(graph, 9, "rank", Cardinality.SINGLE); + olapKey.writeType(WriteType.OLAP_COMMON); + HugeVertex olap = new HugeVertex(graph, source.id(), VertexLabel.OLAP_VL); + olap.addProperty(olapKey, 42); + row("olap", serializer.writeVertex(olap)); + property(graph, 16L, "weight", Cardinality.SINGLE).dataType(DataType.LONG); + property(graph, 17L, "name", Cardinality.SINGLE).dataType(DataType.TEXT); + index("index.secondary", graph, serializer, 6L, IndexType.SECONDARY, "alice"); + index("index.int", graph, serializer, 7L, IndexType.RANGE_INT, 7); + index("index.long", graph, serializer, 8L, IndexType.RANGE_LONG, 7L); + VertexLabel timeless = new VertexLabel(graph, IdGenerator.of(10L), "timeless"); + timeless.properties(single.id(), list.id(), set.id()); + VERTICES.put(10L, timeless); + HugeVertex timelessVertex = new HugeVertex(graph, IdGenerator.of(3L), timeless); + fill(timelessVertex, single, list, set); + row("vertex.untimed", serializer.writeVertex(timelessVertex)); + EdgeLabel timelessEdgeLabel = new EdgeLabel(graph, IdGenerator.of(11L), "untimed"); + timelessEdgeLabel.links(Pair.of(vertexLabel.id(), vertexLabel.id())); + timelessEdgeLabel.properties(single.id(), list.id(), set.id()); + EDGES.put(11L, timelessEdgeLabel); + HugeEdge timelessEdge = new HugeEdge(graph, + new EdgeId(source.id(), Directions.OUT, timelessEdgeLabel.id(), timelessEdgeLabel.id(), + "", target.id()), timelessEdgeLabel); + timelessEdge.vertices(true, source, target); + fill(timelessEdge, single, list, set); + row("edge.untimed", serializer.writeEdge(timelessEdge)); + index("index.secondary.untimed", graph, serializer, 12L, + IndexType.SECONDARY, "alice", 10L); + index("index.int.untimed", graph, serializer, 13L, IndexType.RANGE_INT, 7, 10L); + index("index.long.untimed", graph, serializer, 14L, IndexType.RANGE_LONG, 7L, 10L); + index("index.hashed", graph, serializer, 15L, IndexType.SECONDARY, + "long-field-".repeat(20)); + HugeIndex systemIndex = new HugeIndex(graph, IndexLabel.label(HugeType.VERTEX)); + systemIndex.fieldValues(4L); + systemIndex.elementIds(source.id(), EXPIRY); + row("index.system", serializer.writeIndex(systemIndex)); + HugeIndex edgeSystemIndex = new HugeIndex(graph, IndexLabel.label(HugeType.EDGE)); + edgeSystemIndex.fieldValues(5L); + edgeSystemIndex.elementIds(edge.id(), EXPIRY); + row("index.system.edge", serializer.writeIndex(edgeSystemIndex)); + String producer = Files.readString(Path.of(args[1]), StandardCharsets.UTF_8); + String license = producer.substring(0, producer.indexOf("*/") + 2); + StringBuilder encoded = new StringBuilder(license.replace("/*", "#") + .replace("*/", "#").replace(" *", "#")).append('\n'); + encoded.append("now=").append(NOW).append('\n'); + encoded.append("expiry=").append(EXPIRY).append('\n'); + ROWS.forEach((key, value) -> encoded.append(key).append('=').append(value).append('\n')); + Files.createDirectories(Path.of(args[0])); + Files.writeString(Path.of(args[0]).resolve("core-rows.properties"), encoded, + StandardCharsets.UTF_8); + System.out.println("Generated 15 real legacy BinarySerializer rows"); + } + + private static PropertyKey property(HugeGraph graph, long id, String name, + Cardinality cardinality) { + PropertyKey key = new PropertyKey(graph, IdGenerator.of(id), name); + key.dataType(DataType.INT); + key.cardinality(cardinality); + PROPERTIES.put(id, key); + return key; + } + + private static void fill(HugeElement element, PropertyKey single, + PropertyKey list, PropertyKey set) { + element.addProperty(single, 7); + element.addProperty(list, Arrays.asList(7, -1, 7)); + element.addProperty(set, Arrays.asList(7, -1)); + } + + private static void index(String name, HugeGraph graph, BinarySerializer serializer, + long id, IndexType type, Object value) { + index(name, graph, serializer, id, type, value, 4L); + } + + private static void index(String name, HugeGraph graph, BinarySerializer serializer, + long id, IndexType type, Object value, long baseId) { + IndexLabel label = new IndexLabel(graph, IdGenerator.of(id), name); + label.indexType(type); + label.indexFields(IdGenerator.of(type == IndexType.RANGE_LONG ? 16L : + type == IndexType.SECONDARY ? 17L : 1L)); + label.baseType(HugeType.VERTEX_LABEL); + label.baseValue(IdGenerator.of(baseId)); + INDEXES.put(id, label); + HugeIndex index = new HugeIndex(graph, label); + index.fieldValues(value); + index.elementIds(IdGenerator.of(1L), baseId == 4L ? EXPIRY : 0L); + row(name, serializer.writeIndex(index)); + } + + private static void row(String name, BackendEntry entry) { + if (entry.type().isVertex()) { + HugeVertex decoded = fixtureSerializer.readVertex(fixtureGraph, entry); + if (decoded.sizeOfProperties() != 3 || + !Integer.valueOf(7).equals(decoded.getPropertyValue(IdGenerator.of(1L)))) { + throw new AssertionError("Legacy vertex self-read failed: " + name); + } + } else if (entry.type().isEdge()) { + HugeEdge decoded = fixtureSerializer.readEdge(fixtureGraph, entry); + if (decoded.sizeOfProperties() != 3 || + !Integer.valueOf(7).equals(decoded.getPropertyValue(IdGenerator.of(1L)))) { + throw new AssertionError("Legacy edge self-read failed: " + name); + } + } else if (entry.type() == HugeType.OLAP) { + HugeVertex decoded = new HugeVertex(fixtureGraph, IdGenerator.of(1L), VERTICES.get(4L)); + fixtureSerializer.parseOlap(entry.columns().iterator().next().value, decoded); + if (!Integer.valueOf(42).equals(decoded.getPropertyValue(IdGenerator.of(9L)))) { + throw new AssertionError("Legacy OLAP self-read failed"); + } + } else if (entry.type().isIndex()) { + ConditionQuery query = new ConditionQuery(entry.type()); + if (name.equals("index.secondary") || name.equals("index.secondary.untimed")) { + query.eq(HugeKeys.FIELD_VALUES, "alice"); + } else if (name.equals("index.hashed")) { + query.eq(HugeKeys.FIELD_VALUES, "long-field-".repeat(20)); + } else if (name.equals("index.system")) { + query.eq(HugeKeys.FIELD_VALUES, 4L); + } else if (name.equals("index.system.edge")) { + query.eq(HugeKeys.FIELD_VALUES, 5L); + } + HugeIndex decoded = fixtureSerializer.readIndex(fixtureGraph, query, entry); + Id expectedElement = name.equals("index.system.edge") ? + new EdgeId(IdGenerator.of(1L), Directions.OUT, + IdGenerator.of(5L), IdGenerator.of(5L), + "2026!x", IdGenerator.of(2L)) : IdGenerator.of(1L); + if (!decoded.elementIds().contains(expectedElement)) { + throw new AssertionError("Legacy index self-read failed: " + name); + } + } + ROWS.put(name + ".type", entry.type().name()); + ROWS.put(name + ".id", hex(entry.id().asBytes())); + ROWS.put(name + ".ttl", String.valueOf(entry.ttl())); + ROWS.put(name + ".columns", String.valueOf(entry.columnsSize())); + int number = 0; + for (BackendColumn column : entry.columns()) { + ROWS.put(name + ".column." + number + ".name", hex(column.name)); + ROWS.put(name + ".column." + number + ".value", hex(column.value)); + number++; + } + } + + private static class FixtureSerializer extends BinarySerializer { + private void parseOlap(byte[] bytes, HugeVertex vertex) { + super.parseVertexOlap(bytes, vertex); + } + } + + private static String hex(byte[] bytes) { + StringBuilder text = new StringBuilder(); + for (byte value : bytes) { + text.append(String.format("%02x", value & 0xff)); + } + return text.toString(); + } +} diff --git a/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyServerIndexQueryProbe.java.txt b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyServerIndexQueryProbe.java.txt new file mode 100644 index 0000000000..e51eca9f31 --- /dev/null +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyServerIndexQueryProbe.java.txt @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.Collections; +import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.backend.query.IdPrefixQuery; +import org.apache.hugegraph.backend.serializer.BinarySerializer; +import org.apache.hugegraph.type.HugeType; +import org.apache.hugegraph.type.define.HugeKeys; + +public class LegacyServerIndexQueryProbe { + public static void main(String[] args) throws Exception { + String input = "long-field-".repeat(20); + String value = ConditionQuery.concatValues(Collections.singletonList(input)); + ConditionQuery query = new ConditionQuery(HugeType.SECONDARY_INDEX); + query.eq(HugeKeys.INDEX_LABEL_ID, IdGenerator.of(15L)); + query.eq(HugeKeys.FIELD_VALUES, value); + IdPrefixQuery encoded = (IdPrefixQuery) new BinarySerializer().writeQuery(query); + String text = "server.query.field.length=" + value.length() + "\n" + + "server.query.prefix=" + hex(encoded.prefix().asBytes()) + "\n"; + Files.writeString(Path.of(args[0]).resolve("index-builder-contract.properties"), text, + StandardCharsets.UTF_8, StandardOpenOption.APPEND); + System.out.println("Original Server query: field " + value.length() + + " -> prefix " + hex(encoded.prefix().asBytes())); + } + private static String hex(byte[] bytes) { + StringBuilder text = new StringBuilder(); + for (byte value : bytes) { text.append(String.format("%02x", value & 0xff)); } + return text.toString(); + } +} diff --git a/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyStoreIndexBuilderProbe.java.txt b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyStoreIndexBuilderProbe.java.txt new file mode 100644 index 0000000000..c4a3fbdc2c --- /dev/null +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyStoreIndexBuilderProbe.java.txt @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.lang.reflect.Proxy; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collections; +import org.apache.hugegraph.HugeGraphSupplier; +import org.apache.hugegraph.backend.BackendColumn; +import org.apache.hugegraph.config.HugeConfig; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.serializer.BinaryElementSerializer; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; +import org.apache.hugegraph.structure.BaseVertex; +import org.apache.hugegraph.structure.Index; +import org.apache.hugegraph.structure.builder.IndexBuilder; +import org.apache.hugegraph.type.HugeType; +import org.apache.hugegraph.type.define.DataType; +import org.apache.hugegraph.type.define.IndexType; + +public class LegacyStoreIndexBuilderProbe { + public static void main(String[] args) throws Exception { + HugeConfig config = new HugeConfig(Collections.emptyMap()); + PropertyKey pkey = new PropertyKey(null, IdGenerator.of(17L), "name"); + pkey.dataType(DataType.TEXT); + VertexLabel vlabel = new VertexLabel(null, IdGenerator.of(4L), "person"); + vlabel.properties(pkey.id()); + vlabel.ttl(60000L); + HugeGraphSupplier graph = (HugeGraphSupplier) Proxy.newProxyInstance( + HugeGraphSupplier.class.getClassLoader(), new Class[]{HugeGraphSupplier.class}, + (proxy, method, values) -> { + switch (method.getName()) { + case "configuration": return config; + case "propertyKey": return pkey; + case "vertexLabel": + case "vertexLabelOrNone": return vlabel; + case "now": return 1609459200000L; + case "name": return "legacy-fixture"; + default: throw new AssertionError("Unexpected supplier call: " + method); + } + }); + IndexLabel ilabel = new IndexLabel(graph, IdGenerator.of(15L), "by-name"); + ilabel.indexType(IndexType.SECONDARY); + ilabel.baseType(HugeType.VERTEX_LABEL); + ilabel.baseValue(vlabel.id()); + ilabel.indexFields(pkey.id()); + String value = "long-field-".repeat(20); + BaseVertex vertex = new BaseVertex(IdGenerator.of(1L), vlabel); + vertex.addProperty(pkey, value); + vertex.expiredTime(1609459260000L); + IndexBuilder builder = new IndexBuilder(graph); + Index index = builder.buildIndex(vertex, ilabel).get(0); + BackendColumn column = new BinaryElementSerializer().writeIndex(index); + String producer = Files.readString(Path.of(args[1]), StandardCharsets.UTF_8); + String license = producer.substring(0, producer.indexOf("*/") + 2); + String text = license.replace("/*", "#").replace("*/", "#").replace(" *", "#") + "\n" + + "input.length=" + value.length() + "\n" + + "store.builder.field.length=" + index.fieldValues().toString().length() + "\n" + + "store.builder.field=" + index.fieldValues() + "\n" + + "store.builder.key=" + hex(column.name) + "\n" + + "store.builder.value=" + hex(column.value) + "\n"; + Files.writeString(Path.of(args[0]).resolve("index-builder-contract.properties"), text, + StandardCharsets.UTF_8); + System.out.println("Original Store IndexBuilder: input " + value.length() + + " -> field " + index.fieldValues()); + } + + private static String hex(byte[] bytes) { + StringBuilder text = new StringBuilder(); + for (byte value : bytes) { text.append(String.format("%02x", value & 0xff)); } + return text.toString(); + } +} diff --git a/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyStoreIndexFixtureWriter.java.txt b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyStoreIndexFixtureWriter.java.txt new file mode 100644 index 0000000000..9a9a468c4d --- /dev/null +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyStoreIndexFixtureWriter.java.txt @@ -0,0 +1,126 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.lang.reflect.Proxy; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import org.apache.hugegraph.HugeGraphSupplier; +import org.apache.hugegraph.backend.BackendColumn; +import org.apache.hugegraph.id.Id; +import org.apache.hugegraph.id.EdgeId; +import org.apache.hugegraph.type.define.Directions; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.serializer.BinaryElementSerializer; +import org.apache.hugegraph.struct.schema.IndexLabel; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.struct.schema.VertexLabel; +import org.apache.hugegraph.structure.Index; +import org.apache.hugegraph.type.HugeType; +import org.apache.hugegraph.type.define.DataType; +import org.apache.hugegraph.type.define.IndexType; + +public class LegacyStoreIndexFixtureWriter { + private static final long EXPIRY = 1609459260000L; + private static final Map INDEXES = new HashMap<>(); + private static final Map PROPERTIES = new HashMap<>(); + private static final Map OUTPUT = new LinkedHashMap<>(); + + public static void main(String[] args) throws Exception { + VertexLabel label = new VertexLabel(null, IdGenerator.of(4L), "person"); + label.ttl(60000L); + HugeGraphSupplier graph = (HugeGraphSupplier) Proxy.newProxyInstance( + HugeGraphSupplier.class.getClassLoader(), new Class[]{HugeGraphSupplier.class}, + (proxy, method, values) -> { + switch (method.getName()) { + case "vertexLabel": + case "vertexLabelOrNone": return label; + case "indexLabel": return INDEXES.get(((Id) values[0]).asLong()); + case "propertyKey": return PROPERTIES.get(((Id) values[0]).asLong()); + case "now": return 1609459200000L; + case "name": return "legacy-fixture"; + default: throw new AssertionError("Unexpected supplier call: " + method); + } + }); + PropertyKey intKey = new PropertyKey(graph, IdGenerator.of(1L), "age"); + intKey.dataType(DataType.INT); + PROPERTIES.put(1L, intKey); + PropertyKey longKey = new PropertyKey(graph, IdGenerator.of(16L), "weight"); + longKey.dataType(DataType.LONG); + PROPERTIES.put(16L, longKey); + BinaryElementSerializer serializer = new BinaryElementSerializer(); + System.out.println("Store index writer loaded from " + BinaryElementSerializer.class + .getProtectionDomain().getCodeSource().getLocation()); + user("secondary", graph, serializer, 6L, IndexType.SECONDARY, "alice"); + user("int", graph, serializer, 7L, IndexType.RANGE_INT, 7); + user("long", graph, serializer, 8L, IndexType.RANGE_LONG, 7L); + Index system = new Index(graph, IndexLabel.label(HugeType.VERTEX), true); + system.fieldValues(4L); + system.elementIds(IdGenerator.of(1L), EXPIRY); + row("system", serializer, graph, system); + Index edgeSystem = new Index(graph, IndexLabel.label(HugeType.EDGE), true); + edgeSystem.fieldValues(5L); + edgeSystem.elementIds(new EdgeId(IdGenerator.of(1L), Directions.OUT, + IdGenerator.of(5L), IdGenerator.of(5L), "2026!x", IdGenerator.of(2L)), EXPIRY); + row("system.edge", serializer, graph, edgeSystem); + String source = Files.readString(Path.of(args[1]), StandardCharsets.UTF_8); + String license = source.substring(0, source.indexOf("*/") + 2); + StringBuilder text = new StringBuilder(license.replace("/*", "#") + .replace("*/", "#").replace(" *", "#")).append('\n'); + OUTPUT.forEach((key, value) -> text.append(key).append('=').append(value).append('\n')); + Files.writeString(Path.of(args[0]).resolve("store-index-rows.properties"), text, + StandardCharsets.UTF_8); + System.out.println("Generated 5 original Store TTL index rows"); + } + + private static void user(String name, HugeGraphSupplier graph, + BinaryElementSerializer serializer, long id, + IndexType type, Object value) { + IndexLabel label = new IndexLabel(graph, IdGenerator.of(id), "index-" + id); + label.baseType(HugeType.VERTEX_LABEL); + label.baseValue(IdGenerator.of(4L)); + label.indexType(type); + label.indexFields(IdGenerator.of(type == IndexType.RANGE_LONG ? 16L : 1L)); + INDEXES.put(id, label); + Index index = new Index(graph, label, true); + index.fieldValues(value); + index.elementIds(IdGenerator.of(1L), EXPIRY); + row(name, serializer, graph, index); + } + + private static void row(String name, BinaryElementSerializer serializer, + HugeGraphSupplier graph, Index index) { + BackendColumn column = serializer.writeIndex(index); + Index decoded = serializer.parseIndex(graph, column, null); + if (decoded.expiredTime() != EXPIRY) { + throw new AssertionError("Legacy Store reader TTL mismatch: " + name); + } + OUTPUT.put(name + ".name", hex(column.name)); + OUTPUT.put(name + ".value", hex(column.value)); + OUTPUT.put(name + ".expiry", String.valueOf(EXPIRY)); + } + + private static String hex(byte[] bytes) { + StringBuilder text = new StringBuilder(); + for (byte value : bytes) { + text.append(String.format("%02x", value & 0xff)); + } + return text.toString(); + } +} diff --git a/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyStructFixtureWriter.java.txt b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyStructFixtureWriter.java.txt new file mode 100644 index 0000000000..02d42fe869 --- /dev/null +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/LegacyStructFixtureWriter.java.txt @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.UUID; +import org.apache.hugegraph.id.IdGenerator; +import org.apache.hugegraph.serializer.BytesBuffer; +import org.apache.hugegraph.struct.schema.PropertyKey; +import org.apache.hugegraph.type.define.Cardinality; +import org.apache.hugegraph.type.define.DataType; + +public class LegacyStructFixtureWriter { + private static final StringBuilder OUTPUT = new StringBuilder(); + + public static void main(String[] args) throws Exception { + System.out.println("Writer loaded from " + BytesBuffer.class.getProtectionDomain() + .getCodeSource().getLocation()); + Path source = Path.of(args[1]); + String producer = Files.readString(source, StandardCharsets.UTF_8); + String license = producer.substring(0, producer.indexOf("*/") + 2); + OUTPUT.append(license.replace("/*", "#").replace("*/", "#") + .replace(" *", "#")).append('\n'); + scalar(DataType.BOOLEAN, true); + scalar(DataType.BYTE, (byte) -7); + scalar(DataType.INT, -123456); + scalar(DataType.LONG, Long.MIN_VALUE); + scalar(DataType.FLOAT, 1.25f); + scalar(DataType.DOUBLE, -123.125d); + scalar(DataType.DATE, new Date(1609459200123L)); + scalar(DataType.TEXT, "属性😀\u0000"); + scalar(DataType.BLOB, new byte[]{0, -1, 1, 127, -128}); + scalar(DataType.UUID, UUID.fromString("01234567-89ab-cdef-0123-456789abcdef")); + PropertyKey key = new PropertyKey(null, IdGenerator.of(101L), "legacy"); + key.dataType(DataType.INT); + key.cardinality(Cardinality.LIST); + put("list", BytesBuffer.allocate(64).writeProperty(key, Arrays.asList(7, -1, 7))); + key.cardinality(Cardinality.SET); + put("set", BytesBuffer.allocate(64).writeProperty( + key, new LinkedHashSet<>(Arrays.asList(7, -1)))); + Files.writeString(Path.of(args[0]).resolve("struct-tagged-properties.hex"), + OUTPUT, StandardCharsets.UTF_8); + System.out.println("Generated 12 tagged property fixtures"); + } + + private static void scalar(DataType type, Object value) { + put(type.name(), BytesBuffer.allocate(128).writeProperty(Cardinality.SINGLE, type, value)); + } + + private static void put(String key, BytesBuffer buffer) { + OUTPUT.append(key).append('='); + for (byte value : buffer.bytes()) { + OUTPUT.append(String.format("%02x", value & 0xff)); + } + OUTPUT.append('\n'); + } +} diff --git a/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/README.md b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/README.md new file mode 100644 index 0000000000..c425ee6878 --- /dev/null +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/README.md @@ -0,0 +1,128 @@ + + +# Historical codec fixtures + +These files preserve historical payloads and the producer evidence needed to reproduce them. The `2f827d6e8` directory identifies the pre-consolidation source revision: [apache/hugegraph `2f827d6e8c9c62ae858f2fc122b3a192d015e2f4`](https://github.com/apache/hugegraph/commit/2f827d6e8c9c62ae858f2fc122b3a192d015e2f4). Core and Store/struct fixtures use their respective original implementations at that revision. Tests load the historical payloads described below without regenerating them with the current writer. The index-builder contract file records producer output; `SharedIndexTest` uses its captured Server hash as an assertion rather than loading that file. + +## Files and purpose + +| Fixture | Original producer | Compatibility contract | +|---------|-------------------|------------------------| +| `core-codecs.hex`, four `core-*.json.txt` files | `LegacyCodecFixtureWriter.java.txt`, baseline core | Scalar/ID/index bytes and `ConditionQuery.bytes()` JSON | +| `struct-tagged-properties.hex` | `LegacyStructFixtureWriter.java.txt`, baseline struct | Tagged scalar/LIST/SET properties and metadata recovery | +| `core-rows.properties` | `LegacyRowFixtureWriter.java.txt`, baseline core | Complete `BinarySerializer` rows, including property framing, TTL, OLAP and indexes | +| `store-index-rows.properties` | `LegacyStoreIndexFixtureWriter.java.txt`, baseline struct | Original `BinaryElementSerializer.writeIndex` keys and expiry values | +| `core-kryo-objects.properties` | `LegacyKryoFixtureWriter.java.txt`, baseline core | Relocated class descriptors and the original reader's supported/unsupported cases | +| `index-builder-contract.properties` | `LegacyStoreIndexBuilderProbe.java.txt` and `LegacyServerIndexQueryProbe.java.txt` | Existing Store long-text index/Server query mismatch | +| `core-relation-ordinals.properties` | `RelationFixtureWriter.java.txt` and pinned enum declarations | Legacy/canonical enum ordinals; see [provenance](relation-ordinals-provenance.md) | + +The `.java.txt` producers preserve reproducibility while keeping legacy imports outside test compilation. Store ingress and Server serializer tests carry copies of the relevant payloads because each module loads its own test resources. Keep those copies byte-identical when intentionally updating a fixture. + +`core-codecs.hex` contains 65 named `key=hex` payloads, with properties-style line continuations for large IDs. The JSON files wrap exact UTF-8 query output in an ASF comment prolog and final newline; tests remove those container boundaries. The tagged-property file contains 12 payloads. Source/fixture license headers must be retained. + +## Reproduce with the historical writers + +Use Java 11, UTF-8 and UTC in an isolated checkout of the pinned revision: + +```sh +git clone https://github.com/apache/hugegraph.git legacy-core +cd legacy-core +git checkout --detach 2f827d6e8c9c62ae858f2fc122b3a192d015e2f4 +mvn install -pl hugegraph-server/hugegraph-core -am -DskipTests +mvn dependency:build-classpath -pl hugegraph-server/hugegraph-core \ + -Dmdep.outputFile="$PWD/core-classpath.txt" +mvn install -pl hugegraph-struct -am -DskipTests +mvn dependency:build-classpath -pl hugegraph-struct \ + -Dmdep.outputFile="$PWD/struct-classpath.txt" +``` + +Copy each required `.java.txt` producer to a separate working directory as a `.java` file. Compile with `javac -proc:none -encoding UTF-8` against the relevant baseline module jar and its Maven runtime classpath. Put that baseline jar first; exclude the current shared implementations and other HugeGraph versions. Use separate core and struct classpaths, with no core jar for struct producers. Keep the pinned IndexBuilder's analyzer dependencies even for secondary-index probes. + +Run with `java -Dfile.encoding=UTF-8 -Duser.timezone=UTC` and these arguments: + +| Producer class | Arguments | +|----------------|-----------| +| `LegacyCodecFixtureWriter` | `` | +| `LegacyStructFixtureWriter` | ` ` | +| `LegacyRowFixtureWriter` | ` ` | +| `LegacyStoreIndexFixtureWriter` | ` ` | +| `LegacyKryoFixtureWriter` | ` ` | +| `LegacyStoreIndexBuilderProbe` | ` ` | +| `LegacyServerIndexQueryProbe` | ``; run after the Store probe, in a separate core-classpath process, to append the Server prefix | + +Compare output payloads with the committed resources before accepting changes. The source revision, producer source and payload bytes are the provenance; rebuilt jar hashes can differ because of Maven archive timestamps. Do not replace historical inputs with output from a new writer. Enum-shell reproduction has its own instructions in [relation ordinal provenance](relation-ordinals-provenance.md). + +## Scalar and query coverage + +The scalar fixtures cover signed varint/varlong limits and width boundaries; long, Unicode string and UUID IDs, string-header width changes and the 16 KiB limit; incoming/outgoing edge IDs with parent/sublabel; every scalar property type, including the shaded Kryo fallback; schema-driven SINGLE/LIST/SET values; and string plus 4/8-byte range index IDs. The range-index input is an explicit type/label/value layout, not a full index-builder output. + +Query fixtures cover vertex labels, numeric ranges, typed IN lists, dates, OR, limit/offset, edge ownership/direction/page tokens and executable COUNT(*)/AVG(age) strategies with their JSON aggregate shape. Legacy JSON dates encode local wall time without a zone: `2021-01-01 00:00:00.123` represents epoch `1609459200123` in UTC and `1609430400123` in Asia/Singapore. Tests calculate expected local time without changing the JVM default zone after adapters initialize. + +Core schema-driven properties are untagged; Store/struct properties carry a cardinality/type tag. Both formats share scalar suffixes but remain separate wire entry points. Tests compare their suffixes against independently produced core bytes; they must not read untagged core values as tagged Store properties. + +## Complete row and TTL contracts + +`core-rows.properties` contains 15 complete rows produced by the real baseline `HugeVertex`, `HugeEdge`, `HugeIndex`, properties and `BinarySerializer`. A proxy supplies schema lookup and a fixed clock and rejects unexpected graph calls. The producer validates rows with the original reader; its OLAP reader subclass only exposes `parseVertexOlap`, without overriding encoding. Row IDs, names and values are hex; `type`, `ttl` and `columns` retain `BackendEntry` metadata. + +| Schema | Definition | +|--------|------------| +| Properties 1/2/3 | `age` INT SINGLE = 7; `scores` INT LIST = `[7, -1, 7]`; `groups` INT SET = `{-1, 7}` | +| Property 9 | `rank` INT SINGLE OLAP_COMMON = 42 | +| Properties 16/17 | `weight` LONG SINGLE (range-long); `name` TEXT SINGLE (secondary) | +| Vertex labels 4/10 | `person` TTL 60000 / `timeless` without TTL; both use properties 1/2/3 | +| Edge labels 5/11 | `knows` TTL 60000 / `untimed` without TTL; both link 4→4 and use properties 1/2/3 | +| Index labels 6/7/8 | Secondary/range-int/range-long on vertex label 4 | +| Index labels 12/13/14 | Secondary/range-int/range-long on vertex label 10 | +| Index label 15 | Secondary on vertex label 4, hashed long-string key | + +The clock is `1609459200000`; timed rows expire at `1609459260000`. Vertex IDs are 1 (timed) and 3 (untimed). Edges connect 1 and 2 with sort value `2026!x`, or an empty sort value for the untimed edge. Index values are `alice`, integer 7, long 7, or `"long-field-".repeat(20)`. Default serializer flags enable key/index ID prefixes and disable partition prefixes. + +The OLAP column name is the vertex ID; its value is the property ID plus an untagged scalar. Merged-row tests supply an existing vertex, matching the original reader's main-row-then-OLAP-columns convention. + +Core system vertex/edge label indexes receive positive expiry but retain stable keys and empty values without expiry suffixes. Their fields are vertex label 4 and edge label 5 (with the full edge ID). Store's original user secondary/range and system-label indexes use the same expiration above, with no key expiry suffix and a 13-byte value envelope: `0x00 + Base64(big-endian long)`. + +Shared schema readers must read those Store rows while ordinary schema writers retain the Server key/hash/TTL layout. Tagged writers retain their Store format. Label TTL regression checks cover recovered expiry, `expiredElementIds`, clone/reset isolation, elimination, append and re-read: the exact original key remains stable, core's primitive writer emits its original empty value and the storage writer retains its expiry envelope. + +`property.OBJECT_UNSUPPORTED_COLLECTION` is a skip-only fixture: skipping must retain the trailing marker and TTL without instantiating Kryo data. It does not assert that the collection is readable. These row fixtures do not cover every partition layout, storage transaction or RocksDB/HStore runtime path. + +## Relocated Kryo descriptors + +`core-kryo-objects.properties` contains 36 unmodified original OBJECT payloads. Its `baseline_readable` fields record the original default reader's behavior. Twenty-four were readable: query/ID enums, Userdata with string/int/date entries, Class literals, a `BackendColumn` and populated array, null-element moved-type arrays/matrices, and nested mutable maps/lists. These must decode to the canonical runtime types and values. New writes may use canonical names; semantic roundtrips do not require retaining deprecated Java API names. + +Twelve written payloads were unreadable because the original reader required missing no-arg constructors: LongId/StringId/UuidId/EdgeId/BinaryId/Shard, four schema instances, IdWithExpiredTime and Arrays$ArrayList. Preserve class resolution without a ClassNotFound regression; these fixtures do not change the general instantiation policy or promise newly supported model instances. The readable OBJECT collection is a mutable `ArrayList` rather than `Arrays.asList`. + +Schema/index descriptor fixtures include TaskWithSchema, five P classes, four Builder interfaces, HugeIndex/IdWithExpiredTime Class literals and typed arrays. Empty/null-element arrays and Class literals remain supported even for types whose populated instances are unreadable. No readable live-graph HugeIndex OBJECT instance is claimed. Resolver tests separately accept the JVM 255-dimension boundary, reject 256/5000 dimensions before allocation, and delegate unknown and primitive descriptors to the normal resolver. + +## Existing IndexBuilder/query mismatch + +For TEXT property 17, index label 15, vertex label 4 and `"long-field-".repeat(20)`, the original Store `buildIndex` truncates the 220-character value to `long-field-long-fiel` (20 characters). Its key starts with that literal. The original Server `BinarySerializer.writeQuery`, using `ConditionQuery.concatValues` on the full value, emits hashed prefix `53493a463a323234303534613200`. The Store key does not match that query. + +The fixture records both executed paths, rather than combining guessed helper outputs. Writer/query alignment tests use the original Server prefix while retaining old Store row decoding. Installations using old Store rebuilding may need to rebuild affected indexes; decoding alone cannot repair the mismatch. + +## Payload integrity + +These SHA-256 values identify committed fixture bytes, independent of rebuilt jar timestamps: + +| File | SHA-256 | +|------|---------| +| `core-rows.properties` | `d90cfe0b349edb832bf7425b6b8e2ddb06b3eff3f29e834cf8363b0d2fb84662` | +| `store-index-rows.properties` | `e9e9c967884d0d91b6cf6d5eabf2050a9bad0fe7898d1c47b58535ebdf1b9431` | +| `core-kryo-objects.properties` | `45c10201a1f88b38771fd5bd4e609f461729ac1d5e8fb94304fa176bfd5cf369` | +| `index-builder-contract.properties` | `3be36ba02c4afd58aab383549b041368fab4b9e8e32474122457b5608970161b` | + +Scalar/query and complete-row tests establish these codec contracts, not full storage transactions or query-runtime compatibility. Those require integration and storage tests. diff --git a/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/RelationFixtureWriter.java.txt b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/RelationFixtureWriter.java.txt new file mode 100644 index 0000000000..703cb3a919 --- /dev/null +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/RelationFixtureWriter.java.txt @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import org.apache.tinkerpop.shaded.kryo.Kryo; +import org.apache.tinkerpop.shaded.kryo.io.Output; +import org.apache.hugegraph.backend.query.Condition.RelationType; +public class RelationFixtureWriter { + public static void main(String[] args) { + System.out.println("legacy.names=" + String.join(",", Arrays.stream(RelationType.values()).map(Enum::name).toArray(String[]::new))); + for (RelationType value : RelationType.values()) write("enum." + value, value); + write("array", RelationType.values()); + write("matrix", new RelationType[][]{RelationType.values(), null, new RelationType[0]}); + Map nested = new LinkedHashMap<>(); + nested.put("values", new ArrayList<>(Arrays.asList(RelationType.values()))); + nested.put("array", RelationType.values()); nested.put("last", RelationType.SCAN); + write("nested", nested); + RelationType[] oldArray = {RelationType.SCAN, null, RelationType.TEXT_CONTAINS}; + org.apache.hugegraph.query.Condition.RelationType[] currentArray = { + org.apache.hugegraph.query.Condition.RelationType.TEXT_PREFIX, null, + org.apache.hugegraph.query.Condition.RelationType.TEXT_REGEX}; + write("interleaved", new ArrayList<>(Arrays.asList(RelationType.SCAN, + org.apache.hugegraph.query.Condition.RelationType.TEXT_PREFIX, + RelationType.TEXT_CONTAINS, org.apache.hugegraph.query.Condition.RelationType.TEXT_REGEX, + oldArray, currentArray, oldArray, currentArray))); + } + private static void write(String name, Object value) { + Output output = new Output(4096); new Kryo().writeClassAndObject(output, value); + StringBuilder hex = new StringBuilder(); + for (byte b : output.toBytes()) hex.append(String.format("%02x", b & 255)); + System.out.println(name + ".hex=" + hex); + } +} diff --git a/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-avg-query.json.txt b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-avg-query.json.txt new file mode 100644 index 0000000000..78757f8fdc --- /dev/null +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-avg-query.json.txt @@ -0,0 +1,17 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +{"conditions":[{"cls":"S","el":{"key":"LABEL","relation":"EQ","value":{"id":3,"cls":"org.apache.hugegraph.backend.id.IdGenerator$LongId"}}}],"optimizedType":"NONE","ids":[],"mustSortByInput":true,"resultType":"VERTEX","offset":0,"actualOffset":0,"actualStoreOffset":0,"limit":9223372036854775807,"skipDegree":9223372036854775807,"capacity":800000,"showHidden":false,"showDeleting":false,"showExpired":false,"olap":false,"withProperties":true,"orderType":"ORDER_STRICT","olapPks":[],"aggregate":{"func":"AVG","column":"age"}} diff --git a/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-codecs.hex b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-codecs.hex new file mode 100644 index 0000000000..9665439e6e --- /dev/null +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-codecs.hex @@ -0,0 +1,420 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +id.long.-9223372036854775808=708000000000000000 +vlong.-9223372036854775808=81808080808080808000 +id.long.-16385=17bfff +vlong.-16385=81fffffffffffffeff7f +id.long.-16384=17c000 +vlong.-16384=81ffffffffffffff8000 +id.long.-129=077f +vlong.-129=81fffffffffffffffe7f +id.long.-128=0780 +vlong.-128=81ffffffffffffffff00 +id.long.-1=07ff +vlong.-1=81ffffffffffffffff7f +id.long.0=0800 +vlong.0=00 +id.long.1=0801 +vlong.1=01 +id.long.127=087f +vlong.127=7f +id.long.128=0880 +vlong.128=8100 +id.long.16383=183fff +vlong.16383=ff7f +id.long.16384=184000 +vlong.16384=818000 +id.long.9223372036854775807=787fffffffffffffff +vlong.9223372036854775807=ffffffffffffffff7f +vint.-2147483648=8880808000 +vint.-129=8ffffffe7f +vint.-1=8fffffff7f +vint.0=00 +vint.127=7f +vint.128=8100 +vint.16383=ff7f +vint.16384=818000 +vint.2147483647=87ffffff7f +id.text=84616c696365 +id.unicode=89e9a1b6e782b9f09f9880 +id.text.length.1=8078 +id.text.length.64=bf78787878787878787878787878787878787878787878787878787878787878787878787878787878\ +787878787878787878787878787878787878787878787878 +id.text.length.65=c040787878787878787878787878787878787878787878787878787878787878787878787878787878\ +7878787878787878787878787878787878787878787878787878 +id.text.length.256=c0ff78787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +87878787878787878787878787878787878 +id.text.length.257=c10078787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878 +id.text.length.16384=ffff787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +8787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787\ +878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878 +id.uuid=7f0123456789abcdef0123456789abcdef +edge.out=84616c6963658208030804323032362178000863 +edge.in=08638c080308043230323621780084616c696365 +property.BOOLEAN=01 +property.BYTE=8fffffff79 +property.INT=8ffff8bb40 +property.LONG=81808080808080808000 +property.FLOAT=3fa00000 +property.DOUBLE=c05ec80000000000 +property.DATE=aeebd9f9e07b +property.TEXT=0be5b19ee680a7f09f988000 +property.BLOB=0500ff017f80 +property.UUID=0123456789abcdef0123456789abcdef +property.OBJECT=2301006a6176612e7574696c2e41727261794c6973f4010303016c65676163f9020e0501 +property.UNKNOWN=0f03016c65676163792d6f626a6563f4 +property.OBJECT_UNSUPPORTED_COLLECTION=2a01006a6176612e7574696c2e4172726179732441727261794c6973f4010\ +303016c65676163f9020e0501 +schema.single=07 +schema.list=03078fffffff7f07 +schema.set=02078fffffff7f +index.string=6c6162656c21616c69636500 +index.int=a00000000380000007 +index.long=a2000000038000000000000007 diff --git a/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-count-query.json.txt b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-count-query.json.txt new file mode 100644 index 0000000000..68cf5a6f85 --- /dev/null +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-count-query.json.txt @@ -0,0 +1,17 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +{"conditions":[],"optimizedType":"NONE","ids":[],"mustSortByInput":true,"resultType":"VERTEX","offset":0,"actualOffset":0,"actualStoreOffset":0,"limit":9223372036854775807,"skipDegree":9223372036854775807,"capacity":800000,"showHidden":false,"showDeleting":false,"showExpired":false,"olap":false,"withProperties":true,"orderType":"ORDER_STRICT","olapPks":[],"aggregate":{"func":"COUNT"}} diff --git a/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-edge-query.json.txt b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-edge-query.json.txt new file mode 100644 index 0000000000..fed3f9cfa3 --- /dev/null +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-edge-query.json.txt @@ -0,0 +1,17 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +{"conditions":[{"cls":"S","el":{"key":"OWNER_VERTEX","relation":"EQ","value":{"id":"alice","cls":"org.apache.hugegraph.backend.id.IdGenerator$StringId"}}},{"cls":"S","el":{"key":"DIRECTION","relation":"EQ","value":"OUT"}},{"cls":"S","el":{"key":"LABEL","relation":"EQ","value":{"id":3,"cls":"org.apache.hugegraph.backend.id.IdGenerator$LongId"}}}],"optimizedType":"NONE","ids":[],"mustSortByInput":true,"resultType":"EDGE","offset":0,"actualOffset":0,"actualStoreOffset":0,"limit":5,"skipDegree":9223372036854775807,"page":"AQIDBA\u003d\u003d","capacity":800000,"showHidden":false,"showDeleting":false,"showExpired":false,"olap":false,"withProperties":true,"orderType":"ORDER_STRICT","olapPks":[]} diff --git a/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-kryo-objects.properties b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-kryo-objects.properties new file mode 100644 index 0000000000..0f644d2219 --- /dev/null +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-kryo-objects.properties @@ -0,0 +1,247 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # +long_id.hex=3701006f72672e6170616368652e6875676567726170682e6261636b656e642e69642e496447656e65726174\ +6f72244c6f6e6749e401010e +long_id.baseline_readable=false +long_id.baseline_error=org.apache.tinkerpop.shaded.kryo.KryoException: Class cannot be created (miss\ +ing no-arg constructor): org.apache.hugegraph.backend.id.IdGenerator$LongId +string_id.hex=4201006f72672e6170616368652e6875676567726170682e6261636b656e642e69642e496447656e657261\ +746f7224537472696e6749e40100016c65676163792d69e4 +string_id.baseline_readable=false +string_id.baseline_error=org.apache.tinkerpop.shaded.kryo.KryoException: Class cannot be created (mi\ +ssing no-arg constructor): org.apache.hugegraph.backend.id.IdGenerator$StringId +uuid_id.hex=4601006f72672e6170616368652e6875676567726170682e6261636b656e642e69642e496447656e65726174\ +6f72245575696449e401010123456789abcdef0123456789abcdef +uuid_id.baseline_readable=false +uuid_id.baseline_error=org.apache.tinkerpop.shaded.kryo.KryoException: Class cannot be created (miss\ +ing no-arg constructor): org.apache.hugegraph.backend.id.IdGenerator$UuidId +edge_id.hex=813501006f72672e6170616368652e6875676567726170682e6261636b656e642e69642e4564676549e40100\ +00010201016f72672e6170616368652e6875676567726170682e6261636b656e642e69642e496447656e657261746f72244c\ +6f6e6749e401010601026f72672e6170616368652e6875676567726170682e6261636b656e642e69642e496447656e657261\ +746f7224537472696e6749e40100016c65676163792d69e4010101010e01736f72f40101010108 +edge_id.baseline_readable=false +edge_id.baseline_error=org.apache.tinkerpop.shaded.kryo.KryoException: Class cannot be created (miss\ +ing no-arg constructor): org.apache.hugegraph.backend.id.EdgeId +binary_id.hex=81040100c4016f72672e6170616368652e6875676567726170682e6261636b656e642e73657269616c697a\ +65722e42696e6172794261636b656e64456e7472792442696e617279496401010401020301016f72672e6170616368652e68\ +75676567726170682e6261636b656e642e69642e496447656e657261746f72244c6f6e6749e401010e +binary_id.baseline_readable=false +binary_id.baseline_error=org.apache.tinkerpop.shaded.kryo.KryoException: Class cannot be created (mi\ +ssing no-arg constructor): org.apache.hugegraph.backend.serializer.BinaryBackendEntry$BinaryId +shard.hex=3601006f72672e6170616368652e6875676567726170682e6261636b656e642e73746f72652e53686172e40101\ +656ee4180173746172f4 +shard.baseline_readable=false +shard.baseline_error=org.apache.tinkerpop.shaded.kryo.KryoException: Class cannot be created (missin\ +g no-arg constructor): org.apache.hugegraph.backend.store.Shard +property_key.hex=811801006f72672e6170616368652e6875676567726170682e736368656d612e50726f70657274794b6\ +5f9010101010101090001016f72672e6170616368652e6875676567726170682e6261636b656e642e69642e496447656e657\ +261746f72244c6f6e6749e4010116016167e5010101026f72672e6170616368652e6875676567726170682e736368656d612\ +e55736572646174e101000101 +property_key.baseline_readable=false +property_key.baseline_error=org.apache.tinkerpop.shaded.kryo.KryoException: Class cannot be created \ +(missing no-arg constructor): org.apache.hugegraph.schema.PropertyKey +vertex_label.hex=815001006f72672e6170616368652e6875676567726170682e736368656d612e5665727465784c61626\ +5ec01010001016f72672e6170616368652e6875676567726170682e6261636b656e642e69642e496447656e657261746f722\ +44c6f6e6749e4010118010101026a6176612e7574696c2e486173685365f4010001706572736fee0102010001036a6176612\ +e7574696c2e41727261794c6973f4010001020100010100010101010001046f72672e6170616368652e68756765677261706\ +82e736368656d612e55736572646174e10100 +vertex_label.baseline_readable=false +vertex_label.baseline_error=org.apache.tinkerpop.shaded.kryo.KryoException: Class cannot be created \ +(missing no-arg constructor): org.apache.hugegraph.schema.VertexLabel +edge_label.hex=815a01006f72672e6170616368652e6875676567726170682e736368656d612e456467654c616265ec010\ +101010001010001016f72672e6170616368652e6875676567726170682e6261636b656e642e69642e496447656e657261746\ +f72244c6f6e6749e401011a01026a6176612e7574696c2e486173685365f4010001020100016b6e6f77f3010201000102010\ +001036a6176612e7574696c2e41727261794c6973f401000101010100010101010c0001010c01046f72672e6170616368652\ +e6875676567726170682e736368656d612e55736572646174e10100 +edge_label.baseline_readable=false +edge_label.baseline_error=org.apache.tinkerpop.shaded.kryo.KryoException: Class cannot be created (m\ +issing no-arg constructor): org.apache.hugegraph.schema.EdgeLabel +index_label.hex=813201006f72672e6170616368652e6875676567726170682e736368656d612e496e6465784c616265ec\ +01012001016f72672e6170616368652e6875676567726170682e6261636b656e642e69642e496447656e657261746f72244c\ +6f6e6749e401010000010101011c01026a6176612e7574696c2e41727261794c6973f4010001010162792d6167e501010103\ +6f72672e6170616368652e6875676567726170682e736368656d612e55736572646174e10100 +index_label.baseline_readable=false +index_label.baseline_error=org.apache.tinkerpop.shaded.kryo.KryoException: Class cannot be created (\ +missing no-arg constructor): org.apache.hugegraph.schema.IndexLabel +aggregate_func.hex=3e01006f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e41676\ +77265676174652441676772656761746546756ee30104 +aggregate_func.baseline_readable=true +aggregate_func.baseline_type=org.apache.hugegraph.backend.query.Aggregate$AggregateFunc +relation_type.hex=3d01006f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e\ +646974696f6e2452656c6174696f6e547970e50103 +relation_type.baseline_readable=true +relation_type.baseline_type=org.apache.hugegraph.backend.query.Condition$RelationType +condition_type.hex=3e01006f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6\ +e646974696f6e24436f6e646974696f6e547970e50104 +condition_type.baseline_readable=true +condition_type.baseline_type=org.apache.hugegraph.backend.query.Condition$ConditionType +query_order.hex=3201006f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e51756572\ +79244f726465f20102 +query_order.baseline_readable=true +query_order.baseline_type=org.apache.hugegraph.backend.query.Query$Order +query_order_type.hex=3601006f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e517\ +5657279244f72646572547970e50103 +query_order_type.baseline_readable=true +query_order_type.baseline_type=org.apache.hugegraph.backend.query.Query$OrderType +optimized_type.hex=4301006f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6\ +e646974696f6e5175657279244f7074696d697a6564547970e50105 +optimized_type.baseline_readable=true +optimized_type.baseline_type=org.apache.hugegraph.backend.query.ConditionQuery$OptimizedType +id_type.hex=2d01006f72672e6170616368652e6875676567726170682e6261636b656e642e69642e4964244964547970e5\ +0103 +id_type.baseline_readable=true +id_type.baseline_type=org.apache.hugegraph.backend.id.Id$IdType +graph_type_class.hex=3d01006a6176612e6c616e672e436c6173f30101016f72672e6170616368652e687567656772617\ +0682e7374727563747572652e4772617068547970e500 +graph_type_class.baseline_readable=true +graph_type_class.baseline_type=java.lang.Class +id_array.hex=2a01005b4c6f72672e6170616368652e6875676567726170682e6261636b656e642e69642e4964bb010200 +id_array.baseline_readable=true +id_array.baseline_type=[Lorg.apache.hugegraph.backend.id.Id; +id_matrix.hex=2f01005b5b4c6f72672e6170616368652e6875676567726170682e6261636b656e642e69642e4964bb0103\ +0102000101 +id_matrix.baseline_readable=true +id_matrix.baseline_type=[[Lorg.apache.hugegraph.backend.id.Id; +shard_array.hex=3001005b4c6f72672e6170616368652e6875676567726170682e6261636b656e642e73746f72652e5368\ +617264bb010200 +shard_array.baseline_readable=true +shard_array.baseline_type=[Lorg.apache.hugegraph.backend.store.Shard; +schema_array.hex=2f01005b4c6f72672e6170616368652e6875676567726170682e736368656d612e50726f70657274794\ +b6579bb010200 +schema_array.baseline_readable=true +schema_array.baseline_type=[Lorg.apache.hugegraph.schema.PropertyKey; +userdata.hex=6301006f72672e6170616368652e6875676567726170682e736368656d612e55736572646174e1010303017\ +e6372656174655f74696de501016a6176612e7574696c2e446174e501fbe0f9d9eb2e0301636f756ef4020e03017461e7030\ +16c65676163f9 +userdata.baseline_readable=true +userdata.baseline_type=org.apache.hugegraph.schema.Userdata +backend_column.hex=4801006f72672e6170616368652e6875676567726170682e6261636b656e642e73746f72652e42616\ +36b656e64456e747279244261636b656e64436f6c756dee010103010201030304 +backend_column.baseline_readable=true +backend_column.baseline_type=org.apache.hugegraph.backend.store.BackendEntry$BackendColumn +backend_column_array.hex=810f0100c1015b4c6f72672e6170616368652e6875676567726170682e6261636b656e642e7\ +3746f72652e4261636b656e64456e747279244261636b656e64436f6c756d6e3b010301016f72672e6170616368652e68756\ +76567726170682e6261636b656e642e73746f72652e4261636b656e64456e747279244261636b656e64436f6c756dee01010\ +301020103030400 +backend_column_array.baseline_readable=true +backend_column_array.baseline_type=[Lorg.apache.hugegraph.backend.store.BackendEntry$BackendColumn; +backend_column_class.hex=5201006a6176612e6c616e672e436c6173f30101016f72672e6170616368652e68756765677\ +26170682e6261636b656e642e73746f72652e4261636b656e64456e747279244261636b656e64436f6c756dee00 +backend_column_class.baseline_readable=true +backend_column_class.baseline_type=java.lang.Class +class_list.hex=842601006a6176612e7574696c2e41727261794c6973f4010a01016a6176612e6c616e672e436c6173f30\ +101026f72672e6170616368652e6875676567726170682e6261636b656e642e69642e496447656e657261746f72244c6f6e6\ +749e40001010101036f72672e6170616368652e6875676567726170682e6261636b656e642e69642e496447656e657261746\ +f7224537472696e6749e40001010101046f72672e6170616368652e6875676567726170682e6261636b656e642e69642e496\ +447656e657261746f72245575696449e40001010101056f72672e6170616368652e6875676567726170682e6261636b656e6\ +42e69642e4564676549e4000101010106c4016f72672e6170616368652e6875676567726170682e6261636b656e642e73657\ +269616c697a65722e42696e6172794261636b656e64456e7472792442696e61727949640001010101076f72672e617061636\ +8652e6875676567726170682e6261636b656e642e73746f72652e53686172e40001010101086f72672e6170616368652e687\ +5676567726170682e736368656d612e50726f70657274794b65f90001010101096f72672e6170616368652e6875676567726\ +170682e736368656d612e5665727465784c616265ec00010101010a6f72672e6170616368652e6875676567726170682e736\ +368656d612e456467654c616265ec00010101010b6f72672e6170616368652e6875676567726170682e736368656d612e496\ +e6465784c616265ec00 +class_list.baseline_readable=true +class_list.baseline_type=java.util.ArrayList +contract_classes.hex=843801006a6176612e7574696c2e41727261794c6973f4010a01016a6176612e6c616e672e436c6\ +173f30101026f72672e6170616368652e6875676567726170682e747970652e4e616d6561626ce50001010101036f72672e6\ +170616368652e6875676567726170682e747970652e5479706561626ce50001010101046f72672e6170616368652e6875676\ +567726170682e747970652e496e64657861626ce50001010101056f72672e6170616368652e6875676567726170682e74797\ +0652e50726f706572746961626ce50001010101066f72672e6170616368652e6875676567726170682e6261636b656e642e6\ +9642e4964557469ec0001010101076f72672e6170616368652e6875676567726170682e6261636b656e642e69642e53706c6\ +963696e67496447656e657261746ff20001010101086f72672e6170616368652e6875676567726170682e736368656d612e6\ +275696c6465722e536368656d614275696c6465f2000101010109c8016f72672e6170616368652e6875676567726170682e6\ +261636b656e642e71756572792e73657269616c697a65722e416273747261637453657269616c697a6572416461707465720\ +0010101010a6f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e73657269616c697a657\ +22e5175657279416461707465f200010101010b6f72672e6170616368652e6875676567726170682e6261636b656e642e717\ +56572792e73657269616c697a65722e51756572794964416461707465f200 +contract_classes.baseline_readable=true +contract_classes.baseline_type=java.util.ArrayList +schema_nested_classes.hex=841f01006a6176612e7574696c2e41727261794c6973f4010a01016a6176612e6c616e672e\ +436c6173f30101026f72672e6170616368652e6875676567726170682e736368656d612e536368656d61456c656d656e7424\ +5461736b57697468536368656de10001010101036f72672e6170616368652e6875676567726170682e736368656d612e5072\ +6f70657274794b657924d00001010101046f72672e6170616368652e6875676567726170682e736368656d612e5665727465\ +784c6162656c24d00001010101056f72672e6170616368652e6875676567726170682e736368656d612e456467654c616265\ +6c24d00001010101066f72672e6170616368652e6875676567726170682e736368656d612e496e6465784c6162656c24d000\ +01010101076f72672e6170616368652e6875676567726170682e736368656d612e536368656d61456c656d656e7424d00001\ +010101086f72672e6170616368652e6875676567726170682e736368656d612e50726f70657274794b6579244275696c6465\ +f20001010101096f72672e6170616368652e6875676567726170682e736368656d612e5665727465784c6162656c24427569\ +6c6465f200010101010a6f72672e6170616368652e6875676567726170682e736368656d612e456467654c6162656c244275\ +696c6465f200010101010b6f72672e6170616368652e6875676567726170682e736368656d612e496e6465784c6162656c24\ +4275696c6465f200 +schema_nested_classes.baseline_readable=true +schema_nested_classes.baseline_type=java.util.ArrayList +schema_nested_arrays.hex=842401006a6176612e7574696c2e41727261794c6973f4010a01015b4c6f72672e617061636\ +8652e6875676567726170682e736368656d612e536368656d61456c656d656e74245461736b57697468536368656d61bb010\ +20001025b4c6f72672e6170616368652e6875676567726170682e736368656d612e50726f70657274794b65792450bb01020\ +001035b4c6f72672e6170616368652e6875676567726170682e736368656d612e5665727465784c6162656c2450bb0102000\ +1045b4c6f72672e6170616368652e6875676567726170682e736368656d612e456467654c6162656c2450bb01020001055b4\ +c6f72672e6170616368652e6875676567726170682e736368656d612e496e6465784c6162656c2450bb01020001065b4c6f7\ +2672e6170616368652e6875676567726170682e736368656d612e536368656d61456c656d656e742450bb01020001075b4c6\ +f72672e6170616368652e6875676567726170682e736368656d612e50726f70657274794b6579244275696c646572bb01020\ +001085b4c6f72672e6170616368652e6875676567726170682e736368656d612e5665727465784c6162656c244275696c646\ +572bb01020001095b4c6f72672e6170616368652e6875676567726170682e736368656d612e456467654c6162656c2442756\ +96c646572bb010200010a5b4c6f72672e6170616368652e6875676567726170682e736368656d612e496e6465784c6162656\ +c244275696c646572bb010200 +schema_nested_arrays.baseline_readable=true +schema_nested_arrays.baseline_type=java.util.ArrayList +index_classes.hex=811401006a6176612e7574696c2e41727261794c6973f4010201016a6176612e6c616e672e436c6173\ +f30101026f72672e6170616368652e6875676567726170682e7374727563747572652e48756765496e6465f8000101010103\ +6f72672e6170616368652e6875676567726170682e7374727563747572652e48756765496e64657824496457697468457870\ +6972656454696de500 +index_classes.baseline_readable=true +index_classes.baseline_type=java.util.ArrayList +index_array.hex=3001005b4c6f72672e6170616368652e6875676567726170682e7374727563747572652e48756765496e\ +646578bb010200 +index_array.baseline_readable=true +index_array.baseline_type=[Lorg.apache.hugegraph.structure.HugeIndex; +expiry_id_array.hex=4201005b4c6f72672e6170616368652e6875676567726170682e7374727563747572652e48756765\ +496e646578244964576974684578706972656454696d65bb010200 +expiry_id_array.baseline_readable=true +expiry_id_array.baseline_type=[Lorg.apache.hugegraph.structure.HugeIndex$IdWithExpiredTime; +expiry_id.hex=7a01006f72672e6170616368652e6875676567726170682e7374727563747572652e48756765496e646578\ +244964576974684578706972656454696de501c0e9fab3d75d01016f72672e6170616368652e6875676567726170682e6261\ +636b656e642e69642e496447656e657261746f72244c6f6e6749e401010e +expiry_id.baseline_readable=false +expiry_id.baseline_error=org.apache.tinkerpop.shaded.kryo.KryoException: Class cannot be created (mi\ +ssing no-arg constructor): org.apache.hugegraph.structure.HugeIndex$IdWithExpiredTime +nested.hex=870301006a6176612e7574696c2e4c696e6b6564486173684d61f001050301636c61737365f301016a6176612\ +e7574696c2e41727261794c6973f4010a01026a6176612e6c616e672e436c6173f30101036f72672e6170616368652e68756\ +76567726170682e6261636b656e642e69642e496447656e657261746f72244c6f6e6749e40001020101046f72672e6170616\ +368652e6875676567726170682e6261636b656e642e69642e496447656e657261746f7224537472696e6749e400010201010\ +56f72672e6170616368652e6875676567726170682e6261636b656e642e69642e496447656e657261746f72245575696449e\ +40001020101066f72672e6170616368652e6875676567726170682e6261636b656e642e69642e4564676549e400010201010\ +7c4016f72672e6170616368652e6875676567726170682e6261636b656e642e73657269616c697a65722e42696e617279426\ +1636b656e64456e7472792442696e61727949640001020101086f72672e6170616368652e6875676567726170682e6261636\ +b656e642e73746f72652e53686172e40001020101096f72672e6170616368652e6875676567726170682e736368656d612e5\ +0726f70657274794b65f900010201010a6f72672e6170616368652e6875676567726170682e736368656d612e56657274657\ +84c616265ec00010201010b6f72672e6170616368652e6875676567726170682e736368656d612e456467654c616265ec000\ +10201010c6f72672e6170616368652e6875676567726170682e736368656d612e496e6465784c616265ec0003016d6574616\ +46174e1010d6f72672e6170616368652e6875676567726170682e736368656d612e55736572646174e1010303017e6372656\ +174655f74696de5010e6a6176612e7574696c2e446174e501fbe0f9d9eb2e0301636f756ef4020e03017461e703016c65676\ +163f903016964f3010f5b5b4c6f72672e6170616368652e6875676567726170682e6261636b656e642e69642e4964bb01030\ +10200010103017072656469636174e501106f72672e6170616368652e6875676567726170682e6261636b656e642e7175657\ +2792e436f6e646974696f6e2452656c6174696f6e547970e501030301636f6c756dee01116f72672e6170616368652e68756\ +76567726170682e6261636b656e642e73746f72652e4261636b656e64456e747279244261636b656e64436f6c756dee01010\ +3010201030304 +nested.baseline_readable=true +nested.baseline_type=java.util.LinkedHashMap +unsupported_arrays_list.hex=2a01006a6176612e7574696c2e4172726179732441727261794c6973f4010303016c6567\ +6163f9020e0501 +unsupported_arrays_list.baseline_readable=false +unsupported_arrays_list.baseline_error=org.apache.tinkerpop.shaded.kryo.KryoException: Class cannot \ +be created (missing no-arg constructor): java.util.Arrays$ArrayList diff --git a/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-query.json.txt b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-query.json.txt new file mode 100644 index 0000000000..8d86059b09 --- /dev/null +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-query.json.txt @@ -0,0 +1,17 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +{"conditions":[{"cls":"S","el":{"key":"LABEL","relation":"EQ","value":{"id":3,"cls":"org.apache.hugegraph.backend.id.IdGenerator$LongId"}}},{"cls":"U","el":{"key":{"cls":"L","el":{"id":11}},"relation":"GTE","value":18,"valuecls":"java.lang.Integer"}},{"cls":"U","el":{"key":{"cls":"L","el":{"id":12}},"relation":"IN","value":[20,30],"valuecls":"java.lang.Long"}},{"cls":"U","el":{"key":{"cls":"L","el":{"id":13}},"relation":"EQ","value":"2021-01-01 00:00:00.123","valuecls":"java.util.Date"}},{"cls":"O","el":{"left":{"cls":"U","el":{"key":{"cls":"L","el":{"id":14}},"relation":"EQ","value":"alice"}},"right":{"cls":"U","el":{"key":{"cls":"L","el":{"id":14}},"relation":"EQ","value":"bob"}}}}],"optimizedType":"NONE","ids":[],"mustSortByInput":true,"resultType":"VERTEX","offset":7,"actualOffset":0,"actualStoreOffset":0,"limit":19,"skipDegree":9223372036854775807,"capacity":800000,"showHidden":false,"showDeleting":false,"showExpired":false,"olap":false,"withProperties":true,"orderType":"ORDER_STRICT","olapPks":[]} diff --git a/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-relation-ordinals.properties b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-relation-ordinals.properties new file mode 100644 index 0000000000..e810113beb --- /dev/null +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-relation-ordinals.properties @@ -0,0 +1,37 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # +# Independently generated with shaded Kryo 3.5.1; see relation-ordinals-provenance.md. +legacy.names=EQ,GT,GTE,LT,LTE,NEQ,IN,NOT_IN,PREFIX,TEXT_CONTAINS,TEXT_CONTAINS_ANY,CONTAINS,CONTAINS_VALUE,CONTAINS_KEY,SCAN +enum.EQ.hex=01006f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e646974696f6e2452656c6174696f6e547970e50101 +enum.GT.hex=01006f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e646974696f6e2452656c6174696f6e547970e50102 +enum.GTE.hex=01006f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e646974696f6e2452656c6174696f6e547970e50103 +enum.LT.hex=01006f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e646974696f6e2452656c6174696f6e547970e50104 +enum.LTE.hex=01006f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e646974696f6e2452656c6174696f6e547970e50105 +enum.NEQ.hex=01006f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e646974696f6e2452656c6174696f6e547970e50106 +enum.IN.hex=01006f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e646974696f6e2452656c6174696f6e547970e50107 +enum.NOT_IN.hex=01006f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e646974696f6e2452656c6174696f6e547970e50108 +enum.PREFIX.hex=01006f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e646974696f6e2452656c6174696f6e547970e50109 +enum.TEXT_CONTAINS.hex=01006f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e646974696f6e2452656c6174696f6e547970e5010a +enum.TEXT_CONTAINS_ANY.hex=01006f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e646974696f6e2452656c6174696f6e547970e5010b +enum.CONTAINS.hex=01006f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e646974696f6e2452656c6174696f6e547970e5010c +enum.CONTAINS_VALUE.hex=01006f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e646974696f6e2452656c6174696f6e547970e5010d +enum.CONTAINS_KEY.hex=01006f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e646974696f6e2452656c6174696f6e547970e5010e +enum.SCAN.hex=01006f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e646974696f6e2452656c6174696f6e547970e5010f +array.hex=01005b4c6f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e646974696f6e2452656c6174696f6e54797065bb0110010101020103010401050106010701080109010a010b010c010d010e010f +matrix.hex=01005b5b4c6f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e646974696f6e2452656c6174696f6e54797065bb01040110010101020103010401050106010701080109010a010b010c010d010e010f000101 +nested.hex=01006a6176612e7574696c2e4c696e6b6564486173684d61f00103030176616c7565f301016a6176612e7574696c2e41727261794c6973f4010f01026f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e646974696f6e2452656c6174696f6e547970e5010101020102010201030102010401020105010201060102010701020108010201090102010a0102010b0102010c0102010d0102010e0102010f030161727261f901035b4c6f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e646974696f6e2452656c6174696f6e54797065bb011005060708090a0b0c0d0e0f1011121303016c6173f4010213 +interleaved.hex=01006a6176612e7574696c2e41727261794c6973f4010801016f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e646974696f6e2452656c6174696f6e547970e5010f01026f72672e6170616368652e6875676567726170682e71756572792e436f6e646974696f6e2452656c6174696f6e547970e5010f0101010a0102011a01035b4c6f72672e6170616368652e6875676567726170682e6261636b656e642e71756572792e436f6e646974696f6e2452656c6174696f6e54797065bb010403000501045b4c6f72672e6170616368652e6875676567726170682e71756572792e436f6e646974696f6e2452656c6174696f6e54797065bb0104040006010307010408 diff --git a/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-rows.properties b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-rows.properties new file mode 100644 index 0000000000..fd489e58c1 --- /dev/null +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/core-rows.properties @@ -0,0 +1,108 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # +now=1609459200000 +expiry=1609459260000 +vertex.type=VERTEX +vertex.id=0801 +vertex.ttl=60000 +vertex.columns=1 +vertex.column.0.name=0801 +vertex.column.0.value=08040301070203078fffffff7f0703028fffffff7f07aeebd9fdb460 +edge.out.type=EDGE_OUT +edge.out.id=08018208050805323032362178000802 +edge.out.ttl=60000 +edge.out.columns=1 +edge.out.column.0.name=08018208050805323032362178000802 +edge.out.column.0.value=0301070203078fffffff7f0703028fffffff7f07aeebd9fdb460 +edge.in.type=EDGE_IN +edge.in.id=08028c08050805323032362178000801 +edge.in.ttl=60000 +edge.in.columns=1 +edge.in.column.0.name=08028c08050805323032362178000801 +edge.in.column.0.value=0301070203078fffffff7f0703028fffffff7f07aeebd9fdb460 +olap.type=OLAP +olap.id=0801 +olap.ttl=0 +olap.columns=1 +olap.column.0.name=0801 +olap.column.0.value=092a +index.secondary.type=SECONDARY_INDEX +index.secondary.id=53493a363a616c69636500 +index.secondary.ttl=60000 +index.secondary.columns=1 +index.secondary.column.0.name=53493a363a616c696365000801aeebd9fdb460 +index.secondary.column.0.value= +index.int.type=RANGE_INT_INDEX +index.int.id=a00000000780000007 +index.int.ttl=60000 +index.int.columns=1 +index.int.column.0.name=a000000007800000070801aeebd9fdb460 +index.int.column.0.value= +index.long.type=RANGE_LONG_INDEX +index.long.id=a2000000088000000000000007 +index.long.ttl=60000 +index.long.columns=1 +index.long.column.0.name=a20000000880000000000000070801aeebd9fdb460 +index.long.column.0.value= +vertex.untimed.type=VERTEX +vertex.untimed.id=0803 +vertex.untimed.ttl=0 +vertex.untimed.columns=1 +vertex.untimed.column.0.name=0803 +vertex.untimed.column.0.value=080a0301070203078fffffff7f0703028fffffff7f07 +edge.untimed.type=EDGE_OUT +edge.untimed.id=080182080b080b000802 +edge.untimed.ttl=0 +edge.untimed.columns=1 +edge.untimed.column.0.name=080182080b080b000802 +edge.untimed.column.0.value=0301070203078fffffff7f0703028fffffff7f07 +index.secondary.untimed.type=SECONDARY_INDEX +index.secondary.untimed.id=53493a433a616c69636500 +index.secondary.untimed.ttl=0 +index.secondary.untimed.columns=1 +index.secondary.untimed.column.0.name=53493a433a616c696365000801 +index.secondary.untimed.column.0.value= +index.int.untimed.type=RANGE_INT_INDEX +index.int.untimed.id=a00000000d80000007 +index.int.untimed.ttl=0 +index.int.untimed.columns=1 +index.int.untimed.column.0.name=a00000000d800000070801 +index.int.untimed.column.0.value= +index.long.untimed.type=RANGE_LONG_INDEX +index.long.untimed.id=a20000000e8000000000000007 +index.long.untimed.ttl=0 +index.long.untimed.columns=1 +index.long.untimed.column.0.name=a20000000e80000000000000070801 +index.long.untimed.column.0.value= +index.hashed.type=SECONDARY_INDEX +index.hashed.id=53493a463a323234303534613200 +index.hashed.ttl=60000 +index.hashed.columns=1 +index.hashed.column.0.name=53493a463a3232343035346132000801aeebd9fdb460 +index.hashed.column.0.value=6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d6c6f6e672d6669656c642d +index.system.type=VERTEX_LABEL_INDEX +index.system.id=56493a2d313a3400 +index.system.ttl=0 +index.system.columns=1 +index.system.column.0.name=56493a2d313a34000801 +index.system.column.0.value= +index.system.edge.type=EDGE_LABEL_INDEX +index.system.edge.id=45493a2d323a3500 +index.system.edge.ttl=0 +index.system.edge.columns=1 +index.system.edge.column.0.name=45493a2d323a35007e08018208050805323032362178000802 +index.system.edge.column.0.value= diff --git a/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/index-builder-contract.properties b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/index-builder-contract.properties new file mode 100644 index 0000000000..a6139eef41 --- /dev/null +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/index-builder-contract.properties @@ -0,0 +1,23 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # +input.length=220 +store.builder.field.length=20 +store.builder.field=long-field-long-fiel +store.builder.key=53493a463a6c6f6e672d6669656c642d6c6f6e672d6669656c000801 +store.builder.value=00414141426472732f576d413d +server.query.field.length=220 +server.query.prefix=53493a463a323234303534613200 diff --git a/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/relation-ordinals-provenance.md b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/relation-ordinals-provenance.md new file mode 100644 index 0000000000..2d29d69331 --- /dev/null +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/relation-ordinals-provenance.md @@ -0,0 +1,42 @@ + + +# Relation ordinal fixture provenance + +`core-relation-ordinals.properties` contains raw `Kryo.writeClassAndObject` payloads without a BytesBuffer property-length prefix. The Kryo enum serializer bundled in `gremlin-shaded` 3.5.1 encodes minimal enum shells with these exact class names and declaration orders: + +| Enum declaration | Source revision | Values | +|------------------|-----------------|--------| +| Core `org.apache.hugegraph.backend.query.Condition.RelationType` | [2f827d6e8c9c62ae858f2fc122b3a192d015e2f4](https://github.com/apache/hugegraph/blob/2f827d6e8c9c62ae858f2fc122b3a192d015e2f4/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/Condition.java) | 15 | +| Struct `org.apache.hugegraph.query.Condition.RelationType` | [9c52f40f9a8e5a6c25feb78669d57e45ba0f4ec8](https://github.com/apache/hugegraph/blob/9c52f40f9a8e5a6c25feb78669d57e45ba0f4ec8/hugegraph-struct/src/main/java/org/apache/hugegraph/query/Condition.java) | 27 | + +Enum methods and predicate lambdas do not contribute to Kryo EnumSerializer bytes. These payloads were independently encoded from the pinned declarations, not produced by a full baseline core build. The legacy GTE bytes equal `relation_type.hex` in `core-kryo-objects.properties` after removing its `3d` property-length prefix, providing a cross-check against the original core writer. + +## Regeneration + +Work outside production sources, using the preserved `.java.txt` files: + +1. Copy `LegacyRelationEnum.java.txt` to `org/apache/hugegraph/backend/query/Condition.java` and `CanonicalRelationEnum.java.txt` to `org/apache/hugegraph/query/Condition.java`. +2. Copy `RelationFixtureWriter.java.txt` to `RelationFixtureWriter.java`. +3. Compile all three against `gremlin-shaded-3.5.1.jar`, then run `RelationFixtureWriter` with that jar and the output classes on the classpath. +4. Preserve the ASF header when saving the printed properties, and compare the resulting payloads with the committed fixture before accepting a change. + +## Invariants + +Populated typed arrays, matrices and nested values exercise repeated class descriptors and nullable components. The interleaved sample combines legacy and canonical scalar/array descriptors and repeats arrays to check object identity. New writers retain canonical default ordinal encoding. This fixture tests enum encoding compatibility; it does not establish deployed use of enum OBJECT properties. + +Fixture SHA-256: `93ee6acba21f94737cae3f929931fc09c879b930f47f0d43697a2b7f2654d1b4`. diff --git a/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/store-index-rows.properties b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/store-index-rows.properties new file mode 100644 index 0000000000..7f5a599ed4 --- /dev/null +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/store-index-rows.properties @@ -0,0 +1,31 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # +secondary.name=53493a363a616c696365000801 +secondary.value=00414141426472732f576d413d +secondary.expiry=1609459260000 +int.name=a000000007800000070801 +int.value=00414141426472732f576d413d +int.expiry=1609459260000 +long.name=a20000000880000000000000070801 +long.value=00414141426472732f576d413d +long.expiry=1609459260000 +system.name=56493a2d313a34000801 +system.value=00414141426472732f576d413d +system.expiry=1609459260000 +system.edge.name=45493a2d323a35007e08018208050805323032362178000802 +system.edge.value=00414141426472732f576d413d +system.edge.expiry=1609459260000 diff --git a/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/struct-tagged-properties.hex b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/struct-tagged-properties.hex new file mode 100644 index 0000000000..0602e40ed4 --- /dev/null +++ b/hugegraph-struct/src/test/resources/compatibility/2f827d6e8/struct-tagged-properties.hex @@ -0,0 +1,28 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # +BOOLEAN=4201 +BYTE=438fffffff79 +INT=448ffff8bb40 +LONG=4581808080808080808000 +FLOAT=463fa00000 +DOUBLE=47c05ec80000000000 +DATE=4aaeebd9f9e07b +TEXT=480be5b19ee680a7f09f988000 +BLOB=490500ff017f80 +UUID=4b0123456789abcdef0123456789abcdef +list=8403078fffffff7f07 +set=c402078fffffff7f diff --git a/install-dist/release-docs/LICENSE b/install-dist/release-docs/LICENSE index c89ada3234..88e9caa90b 100644 --- a/install-dist/release-docs/LICENSE +++ b/install-dist/release-docs/LICENSE @@ -217,9 +217,9 @@ Apache 2.0 licenses The following components are provided under the Apache License. See project link for details. The text of each license is the standard Apache 2.0 license. -hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/Nameable.java from https://github.com/JanusGraph/janusgraph -hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/Cardinality.java from https://github.com/JanusGraph/janusgraph -hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/StringEncoding.java from https://github.com/JanusGraph/janusgraph +hugegraph-struct/src/main/java/org/apache/hugegraph/type/Namifiable.java from https://github.com/JanusGraph/janusgraph +hugegraph-struct/src/main/java/org/apache/hugegraph/type/define/Cardinality.java from https://github.com/JanusGraph/janusgraph +hugegraph-struct/src/main/java/org/apache/hugegraph/util/StringEncoding.java from https://github.com/JanusGraph/janusgraph hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeScriptTraversal.java from https://github.com/apache/tinkerpop hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/ProcessBasicSuite.java from https://github.com/apache/tinkerpop hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/StructureBasicSuite.java from https://github.com/apache/tinkerpop @@ -511,7 +511,6 @@ the corresponding per-component license file. https://central.sonatype.com/artifact/org.apache.commons/commons-collections4/4.4 -> Apache 2.0 https://central.sonatype.com/artifact/org.apache.commons/commons-compress/1.21 -> Apache 2.0 https://central.sonatype.com/artifact/org.apache.commons/commons-configuration2/2.10.1 -> Apache 2.0 - https://central.sonatype.com/artifact/org.apache.commons/commons-configuration2/2.8.0 -> Apache 2.0 https://central.sonatype.com/artifact/org.apache.commons/commons-configuration2/2.9.0 -> Apache 2.0 https://central.sonatype.com/artifact/org.apache.commons/commons-crypto/1.1.0 -> Apache 2.0 https://central.sonatype.com/artifact/org.apache.commons/commons-lang3/3.12.0 -> Apache 2.0 @@ -636,7 +635,6 @@ the corresponding per-component license file. https://central.sonatype.com/artifact/org.gridkit.jvmtool/sjk-stacktrace/0.22 -> Apache 2.0 https://central.sonatype.com/artifact/org.gridkit.lab/jvm-attach-api/1.5 -> Apache 2.0 https://central.sonatype.com/artifact/org.javassist/javassist/3.21.0-GA -> Apache 2.0 - https://central.sonatype.com/artifact/org.javassist/javassist/3.24.0-GA -> Apache 2.0 https://central.sonatype.com/artifact/org.javassist/javassist/3.25.0-GA -> Apache 2.0 https://central.sonatype.com/artifact/org.javassist/javassist/3.28.0-GA -> Apache 2.0 https://central.sonatype.com/artifact/org.javatuples/javatuples/1.2 -> Apache 2.0 @@ -669,15 +667,6 @@ the corresponding per-component license file. https://central.sonatype.com/artifact/org.perfkit.sjk.parsers/sjk-jfr5/0.5 -> Apache 2.0 https://central.sonatype.com/artifact/org.perfkit.sjk.parsers/sjk-jfr6/0.7 -> Apache 2.0 https://central.sonatype.com/artifact/org.perfkit.sjk.parsers/sjk-nps/0.9 -> Apache 2.0 - https://central.sonatype.com/artifact/org.powermock/powermock-api-mockito2/2.0.0-RC.3 -> Apache 2.0 - https://central.sonatype.com/artifact/org.powermock/powermock-api-support/2.0.0-RC.3 -> Apache 2.0 - https://central.sonatype.com/artifact/org.powermock/powermock-classloading-base/2.0.0-RC.3 -> Apache 2.0 - https://central.sonatype.com/artifact/org.powermock/powermock-classloading-xstream/2.0.0-RC.3 -> Apache 2.0 - https://central.sonatype.com/artifact/org.powermock/powermock-core/2.0.0-RC.3 -> Apache 2.0 - https://central.sonatype.com/artifact/org.powermock/powermock-module-junit4-common/2.0.0-RC.3 -> Apache 2.0 - https://central.sonatype.com/artifact/org.powermock/powermock-module-junit4-rule/2.0.0-RC.3 -> Apache 2.0 - https://central.sonatype.com/artifact/org.powermock/powermock-module-junit4/2.0.0-RC.3 -> Apache 2.0 - https://central.sonatype.com/artifact/org.powermock/powermock-reflect/2.0.0-RC.3 -> Apache 2.0 https://central.sonatype.com/artifact/org.roaringbitmap/RoaringBitmap/0.9.38 -> Apache 2.0 https://central.sonatype.com/artifact/org.roaringbitmap/shims/0.9.38 -> Apache 2.0 https://central.sonatype.com/artifact/org.rocksdb/rocksdbjni/8.10.2 -> Apache 2.0 @@ -725,7 +714,6 @@ Third party BSD licenses The following components are provided under the BSD License. See project link for details. The text of each license is also included in licenses/LICENSE-[project].txt. - https://central.sonatype.com/artifact/com.thoughtworks.xstream/xstream/1.4.10 -> BSD https://central.sonatype.com/artifact/dk.brics.automaton/automaton/1.11-8 -> BSD https://central.sonatype.com/artifact/jline/jline/2.14.6 -> BSD https://central.sonatype.com/artifact/org.hamcrest/hamcrest-core/1.3 -> BSD @@ -908,14 +896,6 @@ The text of each license is also included in licenses/LICENSE-[project].txt. https://central.sonatype.com/artifact/junit/junit/4.13.1 -> EPL 1.0 https://central.sonatype.com/artifact/junit/junit/4.13.2 -> EPL 1.0 -======================================================================== -Third party Public Domain licenses -======================================================================== -The following components are provided under the Public Domain License. See project link for details. -The text of each license is also included in licenses/LICENSE-[project].txt. - - https://central.sonatype.com/artifact/xmlpull/xmlpull/1.1.3.1 -> Public Domain - https://central.sonatype.com/artifact/xpp3/xpp3_min/1.1.4c -> Public Domain # # jansi 2.4.0 (https://github.com/fusesource/jansi) diff --git a/install-dist/release-docs/NOTICE b/install-dist/release-docs/NOTICE index 8f505aa265..81b0ed929b 100644 --- a/install-dist/release-docs/NOTICE +++ b/install-dist/release-docs/NOTICE @@ -3106,3 +3106,15 @@ as per accompanying LICENSE file. A list of contributors may be found from CREDITS file, which is included in some artifacts (usually source distributions); but is always available from the source code management (SCM) system project uses. + +======================================================================== + +commons-text-1.10.0 NOTICE + +======================================================================== + +Apache Commons Text +Copyright 2014-2022 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (https://www.apache.org/). diff --git a/install-dist/release-docs/licenses/LICENSE-commons-configuration2-2.8.0.txt b/install-dist/release-docs/licenses/LICENSE-commons-configuration2-2.8.0.txt deleted file mode 100644 index d645695673..0000000000 --- a/install-dist/release-docs/licenses/LICENSE-commons-configuration2-2.8.0.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. diff --git a/install-dist/release-docs/licenses/LICENSE-powermock-api-mockito2-2.0.0-RC.3.txt b/install-dist/release-docs/licenses/LICENSE-powermock-api-mockito2-2.0.0-RC.3.txt deleted file mode 100644 index 0cf7145a38..0000000000 --- a/install-dist/release-docs/licenses/LICENSE-powermock-api-mockito2-2.0.0-RC.3.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2007-2017 PowerMock Contributors - - 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. diff --git a/install-dist/release-docs/licenses/LICENSE-powermock-api-support-2.0.0-RC.3.txt b/install-dist/release-docs/licenses/LICENSE-powermock-api-support-2.0.0-RC.3.txt deleted file mode 100644 index 0cf7145a38..0000000000 --- a/install-dist/release-docs/licenses/LICENSE-powermock-api-support-2.0.0-RC.3.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2007-2017 PowerMock Contributors - - 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. diff --git a/install-dist/release-docs/licenses/LICENSE-powermock-classloading-base-2.0.0-RC.3.txt b/install-dist/release-docs/licenses/LICENSE-powermock-classloading-base-2.0.0-RC.3.txt deleted file mode 100644 index 0cf7145a38..0000000000 --- a/install-dist/release-docs/licenses/LICENSE-powermock-classloading-base-2.0.0-RC.3.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2007-2017 PowerMock Contributors - - 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. diff --git a/install-dist/release-docs/licenses/LICENSE-powermock-classloading-xstream-2.0.0-RC.3.txt b/install-dist/release-docs/licenses/LICENSE-powermock-classloading-xstream-2.0.0-RC.3.txt deleted file mode 100644 index 0cf7145a38..0000000000 --- a/install-dist/release-docs/licenses/LICENSE-powermock-classloading-xstream-2.0.0-RC.3.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2007-2017 PowerMock Contributors - - 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. diff --git a/install-dist/release-docs/licenses/LICENSE-powermock-core-2.0.0-RC.3.txt b/install-dist/release-docs/licenses/LICENSE-powermock-core-2.0.0-RC.3.txt deleted file mode 100644 index 0cf7145a38..0000000000 --- a/install-dist/release-docs/licenses/LICENSE-powermock-core-2.0.0-RC.3.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2007-2017 PowerMock Contributors - - 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. diff --git a/install-dist/release-docs/licenses/LICENSE-powermock-module-junit4-2.0.0-RC.3.txt b/install-dist/release-docs/licenses/LICENSE-powermock-module-junit4-2.0.0-RC.3.txt deleted file mode 100644 index 0cf7145a38..0000000000 --- a/install-dist/release-docs/licenses/LICENSE-powermock-module-junit4-2.0.0-RC.3.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2007-2017 PowerMock Contributors - - 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. diff --git a/install-dist/release-docs/licenses/LICENSE-powermock-module-junit4-common-2.0.0-RC.3.txt b/install-dist/release-docs/licenses/LICENSE-powermock-module-junit4-common-2.0.0-RC.3.txt deleted file mode 100644 index 0cf7145a38..0000000000 --- a/install-dist/release-docs/licenses/LICENSE-powermock-module-junit4-common-2.0.0-RC.3.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2007-2017 PowerMock Contributors - - 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. diff --git a/install-dist/release-docs/licenses/LICENSE-powermock-module-junit4-rule-2.0.0-RC.3.txt b/install-dist/release-docs/licenses/LICENSE-powermock-module-junit4-rule-2.0.0-RC.3.txt deleted file mode 100644 index 0cf7145a38..0000000000 --- a/install-dist/release-docs/licenses/LICENSE-powermock-module-junit4-rule-2.0.0-RC.3.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2007-2017 PowerMock Contributors - - 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. diff --git a/install-dist/release-docs/licenses/LICENSE-powermock-reflect-2.0.0-RC.3.txt b/install-dist/release-docs/licenses/LICENSE-powermock-reflect-2.0.0-RC.3.txt deleted file mode 100644 index 0cf7145a38..0000000000 --- a/install-dist/release-docs/licenses/LICENSE-powermock-reflect-2.0.0-RC.3.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2007-2017 PowerMock Contributors - - 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. diff --git a/install-dist/release-docs/licenses/LICENSE-javassist-3.24.0-GA.txt b/install-dist/release-docs/licenses/LICENSE-spring-boot-jarmode-layertools-2.7.1.txt similarity index 98% rename from install-dist/release-docs/licenses/LICENSE-javassist-3.24.0-GA.txt rename to install-dist/release-docs/licenses/LICENSE-spring-boot-jarmode-layertools-2.7.1.txt index d645695673..823c1c8e98 100644 --- a/install-dist/release-docs/licenses/LICENSE-javassist-3.24.0-GA.txt +++ b/install-dist/release-docs/licenses/LICENSE-spring-boot-jarmode-layertools-2.7.1.txt @@ -1,7 +1,7 @@ Apache License Version 2.0, January 2004 - http://www.apache.org/licenses/ + https://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION @@ -179,7 +179,7 @@ APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" + boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a @@ -187,16 +187,16 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright {yyyy} {name of copyright owner} 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 + https://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. + limitations under the License. \ No newline at end of file diff --git a/install-dist/release-docs/licenses/LICENSE-xmlpull-1.1.3.1.txt b/install-dist/release-docs/licenses/LICENSE-xmlpull-1.1.3.1.txt deleted file mode 100644 index d412a90f28..0000000000 --- a/install-dist/release-docs/licenses/LICENSE-xmlpull-1.1.3.1.txt +++ /dev/null @@ -1 +0,0 @@ -http://www.xmlpull.org/v1/download/unpacked/LICENSE.txt diff --git a/install-dist/release-docs/licenses/LICENSE-xpp3_min-1.1.4c.txt b/install-dist/release-docs/licenses/LICENSE-xpp3_min-1.1.4c.txt deleted file mode 100644 index 3a5baed068..0000000000 --- a/install-dist/release-docs/licenses/LICENSE-xpp3_min-1.1.4c.txt +++ /dev/null @@ -1 +0,0 @@ -http://creativecommons.org/licenses/publicdomain diff --git a/install-dist/release-docs/licenses/LICENSE-xstream-1.4.10.txt b/install-dist/release-docs/licenses/LICENSE-xstream-1.4.10.txt deleted file mode 100644 index 01f3f3133e..0000000000 --- a/install-dist/release-docs/licenses/LICENSE-xstream-1.4.10.txt +++ /dev/null @@ -1,28 +0,0 @@ -(BSD Style License) - -Copyright (c) 2003-2006, Joe Walnes -Copyright (c) 2006-2020, XStream Committers -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list of -conditions and the following disclaimer. Redistributions in binary form must reproduce -the above copyright notice, this list of conditions and the following disclaimer in -the documentation and/or other materials provided with the distribution. - -Neither the name of XStream nor the names of its contributors may be used to endorse -or promote products derived from this software without specific prior written -permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY -WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. diff --git a/install-dist/scripts/dependency/check_dependencies.sh b/install-dist/scripts/dependency/check_dependencies.sh index 0fadfa3132..47a7ff5ae1 100644 --- a/install-dist/scripts/dependency/check_dependencies.sh +++ b/install-dist/scripts/dependency/check_dependencies.sh @@ -16,20 +16,12 @@ # limitations under the License. # -BASE_PATH=$( - cd "$(dirname "$0")" || exit 1 - pwd -) +set -euo pipefail -# check whether there are new third-party dependencies by diff command, -# diff generated 'current-dependencies.txt' file with 'known-dependencies.txt' file. -diff -w -B -U0 <(sort <"${BASE_PATH}"/known-dependencies.txt) \ - <(sort <"${BASE_PATH}"/current-dependencies.txt) >${BASE_PATH}/result.txt +BASE_PATH=$(cd "$(dirname "$0")" && pwd) +KNOWN_FILE=${1:-$BASE_PATH/known-dependencies.txt} +CURRENT_FILE=${2:-$BASE_PATH/current-dependencies.txt} -# if has new third-party,the Action will fail and print diff -if [ -s "${BASE_PATH}"/result.txt ]; then - cat "${BASE_PATH}"/result.txt - exit 1 -else - echo 'All third dependencies is known!' -fi +# Missing/malformed inputs and scan failures must not produce a green diff. +python3 "$BASE_PATH/dependency_inventory.py" check \ + --known "$KNOWN_FILE" --current "$CURRENT_FILE" diff --git a/install-dist/scripts/dependency/dependency_inventory.py b/install-dist/scripts/dependency/dependency_inventory.py new file mode 100644 index 0000000000..f80728487a --- /dev/null +++ b/install-dist/scripts/dependency/dependency_inventory.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python3 +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Inventory the union of Maven runtime dependencies and actually shipped jars. + +Keep the historical filename exclusions for project artifacts. Boot repackaging +can inject jars or include provided dependencies absent from Maven's runtime +scope, so collect flat and nested distribution libraries as well. Comparison +remains strict: removals and additions both require updating the approved list. +""" + +import argparse +import difflib +import io +import os +from pathlib import Path +import re +import sys +import tempfile +import zipfile + + +class InventoryFailure(Exception): + pass + + +def third_party(name): + # Preserve the former egrep -v '^hg|hugegraph|hubble' inventory convention. + return not re.search(r'^hg|hugegraph|hubble', name) + + +def validate_name(name): + if not re.fullmatch(r'[A-Za-z0-9_.+-]+\.jar', name): + raise InventoryFailure(f'Invalid dependency jar filename: {name}') + + +def scan_shipped_jar(source, name, origin, result): + validate_name(name) + try: + with zipfile.ZipFile(source) as archive: + if third_party(name): + result.add(name) + for entry in archive.namelist(): + if entry.startswith(('BOOT-INF/lib/', 'WEB-INF/lib/')) and entry.endswith('.jar'): + scan_shipped_jar(io.BytesIO(archive.read(entry)), Path(entry).name, + origin + '!/' + entry, result) + except (OSError, zipfile.BadZipFile, RuntimeError) as error: + raise InventoryFailure(f'Cannot inspect shipped jar {origin}: {error}') from error + + +def collect(runtime, root, revision): + if not re.fullmatch(r'[A-Za-z0-9_.+-]+', revision): + raise InventoryFailure(f'Invalid distribution revision: {revision}') + if not runtime.is_dir(): + raise InventoryFailure(f'Missing Maven runtime dependency directory: {runtime}') + files = sorted(runtime.iterdir()) + if not files: + raise InventoryFailure(f'Empty Maven runtime dependency directory: {runtime}') + result = set() + for path in files: + validate_name(path.name) + try: + # Runtime copy has already resolved each artifact; validate its jar + # without treating nested project packaging as new Maven coordinates. + with zipfile.ZipFile(path): + pass + except (OSError, zipfile.BadZipFile) as error: + raise InventoryFailure(f'Cannot inspect resolved jar {path}: {error}') from error + if third_party(path.name): + result.add(path.name) + for kind in ('server', 'pd', 'store'): + distribution = root / ('hugegraph-' + kind) / f'apache-hugegraph-{kind}-{revision}' + library = distribution / 'lib' + jars = sorted(library.rglob('*.jar')) + if not library.is_dir() or not jars: + raise InventoryFailure(f'Missing packaged {kind} dependency jars: {library}') + for directory in ('ext', 'plugins'): + jars.extend(sorted((distribution / directory).rglob('*.jar'))) + for path in jars: + scan_shipped_jar(path, path.name, str(path), result) + if not result: + raise InventoryFailure('No third-party dependencies found') + return result + + +def read_inventory(path): + values = [] + for line in path.read_text().splitlines(): + name = line.strip() + if name: + validate_name(name) + values.append(name) + if not values: + raise InventoryFailure(f'Empty dependency inventory: {path}') + if len(values) != len(set(values)): + raise InventoryFailure(f'Duplicate dependency inventory entries: {path}') + return sorted(values) + + +def compare(known, current): + approved, observed = read_inventory(known), read_inventory(current) + difference = ''.join(difflib.unified_diff([name + '\n' for name in approved], + [name + '\n' for name in observed], + fromfile=str(known), tofile=str(current), n=0)) + if difference: + print(difference, end='') + return 1 + print('All third-party dependencies match the approved runtime and shipped inventory.') + return 0 + + +def write_inventory(output, names): + output.parent.mkdir(parents=True, exist_ok=True) + temporary = None + try: + with tempfile.NamedTemporaryFile(mode='w', dir=output.parent, delete=False) as handle: + temporary = Path(handle.name) + handle.write('\n'.join(sorted(names)) + '\n') + os.replace(temporary, output) + finally: + if temporary is not None: + temporary.unlink(missing_ok=True) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + commands = parser.add_subparsers(dest='command', required=True) + producer = commands.add_parser('collect') + producer.add_argument('--runtime', type=Path, required=True) + producer.add_argument('--root', type=Path, required=True) + producer.add_argument('--revision', required=True) + producer.add_argument('--output', type=Path, required=True) + checker = commands.add_parser('check') + checker.add_argument('--known', type=Path, required=True) + checker.add_argument('--current', type=Path, required=True) + args = parser.parse_args() + try: + if args.command == 'check': + return compare(args.known, args.current) + names = collect(args.runtime, args.root, args.revision) + write_inventory(args.output, names) + print(f'Wrote {len(names)} runtime and shipped dependency filenames to {args.output}') + return 0 + except (InventoryFailure, OSError, UnicodeError) as error: + print(f'Dependency inventory FAILED: {error}', file=sys.stderr) + return 1 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/install-dist/scripts/dependency/known-dependencies.txt b/install-dist/scripts/dependency/known-dependencies.txt index 567cf670a0..5abf41d10b 100644 --- a/install-dist/scripts/dependency/known-dependencies.txt +++ b/install-dist/scripts/dependency/known-dependencies.txt @@ -54,8 +54,6 @@ commons-collections4-4.4.jar commons-compress-1.21.jar commons-configuration-1.10.jar commons-configuration2-2.10.1.jar -commons-configuration2-2.8.0.jar -commons-configuration2-2.9.0.jar commons-crypto-1.1.0.jar commons-io-2.12.0.jar commons-io-2.7.jar @@ -137,7 +135,6 @@ grpc-core-1.28.1.jar grpc-core-1.39.0.jar grpc-core-1.47.0.jar grpc-grpclb-1.39.0.jar -grpc-netty-1.39.0.jar grpc-netty-1.47.0.jar grpc-netty-shaded-1.28.0.jar grpc-netty-shaded-1.39.0.jar @@ -162,7 +159,6 @@ guava-32.0.1-android.jar hamcrest-2.2.jar hamcrest-3.0.jar hamcrest-core-1.3.jar -hanlp-portable-1.5.0.jar hanlp-portable-1.8.3.jar hbase-client-2.6.5.jar hbase-common-2.6.5.jar @@ -227,7 +223,6 @@ jansi-2.4.0.jar javaparser-core-3.26.3.jar javapoet-1.13.0.jar javassist-3.21.0-GA.jar -javassist-3.24.0-GA.jar javassist-3.25.0-GA.jar javassist-3.28.0-GA.jar javatuples-1.2.jar @@ -244,7 +239,6 @@ jcip-annotations-1.0-1.jar jcl-over-slf4j-1.7.25.jar jcodings-1.0.58.jar jcommander-1.30.jar -jcseg-core-2.2.0.jar jcseg-core-2.6.2.jar jctools-core-2.1.1.jar jedis-2.5.1.jar @@ -279,11 +273,8 @@ jetty-util-ajax-9.4.51.v20230217.jar jetty-webapp-9.4.51.v20230217.jar jetty-xml-9.4.51.v20230217.jar jieba-analysis-1.0.2.jar -jjwt-api-0.11.2.jar jjwt-api-0.11.5.jar -jjwt-impl-0.11.2.jar jjwt-impl-0.11.5.jar -jjwt-jackson-0.11.2.jar jjwt-jackson-0.11.5.jar jline-2.14.6.jar jna-5.12.1.jar @@ -363,13 +354,11 @@ log4j-slf4j-impl-2.18.0.jar logging-interceptor-3.12.12.jar logging-interceptor-4.10.0.jar lombok-1.18.24.jar +lombok-1.18.30.jar lookout-api-1.4.1.jar -lucene-analyzers-common-5.2.1.jar lucene-analyzers-common-8.11.2.jar -lucene-analyzers-smartcn-7.4.0.jar lucene-analyzers-smartcn-8.11.2.jar lucene-backward-codecs-5.2.1.jar -lucene-core-7.4.0.jar lucene-core-8.11.2.jar lucene-misc-5.2.1.jar lucene-queries-4.7.2.jar @@ -463,15 +452,6 @@ perfmark-api-0.23.0.jar perfmark-api-0.25.0.jar picocli-4.7.6.jar pinyin4j-2.5.0.jar -powermock-api-mockito2-2.0.0-RC.3.jar -powermock-api-support-2.0.0-RC.3.jar -powermock-classloading-base-2.0.0-RC.3.jar -powermock-classloading-xstream-2.0.0-RC.3.jar -powermock-core-2.0.0-RC.3.jar -powermock-module-junit4-2.0.0-RC.3.jar -powermock-module-junit4-common-2.0.0-RC.3.jar -powermock-module-junit4-rule-2.0.0-RC.3.jar -powermock-reflect-2.0.0-RC.3.jar proto-google-common-protos-1.17.0.jar proto-google-common-protos-2.0.1.jar protobuf-java-3.11.0.jar @@ -517,6 +497,7 @@ spring-boot-2.5.15.jar spring-boot-actuator-2.5.15.jar spring-boot-actuator-autoconfigure-2.5.15.jar spring-boot-autoconfigure-2.5.15.jar +spring-boot-jarmode-layertools-2.7.1.jar spring-boot-starter-2.5.15.jar spring-boot-starter-actuator-2.5.15.jar spring-boot-starter-jetty-2.5.15.jar @@ -558,10 +539,7 @@ websocket-common-9.4.51.v20230217.jar websocket-server-9.4.51.v20230217.jar websocket-servlet-9.4.51.v20230217.jar word-1.3.jar -xmlpull-1.1.3.1.jar xmlunit-core-2.8.4.jar -xpp3_min-1.1.4c.jar -xstream-1.4.10.jar zjsonpatch-0.3.0.jar zookeeper-3.8.6.jar zookeeper-jute-3.8.6.jar diff --git a/install-dist/scripts/dependency/regenerate_known_dependencies.sh b/install-dist/scripts/dependency/regenerate_known_dependencies.sh index 5251f0658a..8b6d54bcda 100644 --- a/install-dist/scripts/dependency/regenerate_known_dependencies.sh +++ b/install-dist/scripts/dependency/regenerate_known_dependencies.sh @@ -16,18 +16,27 @@ # limitations under the License. # -BASE_PATH=$(cd "$(dirname $0)" || exit; pwd) -DEP_PATH=$BASE_PATH/all_dependencies +set -euo pipefail + +BASE_PATH=$(cd "$(dirname "$0")" && pwd) +ROOT_PATH=$(cd "$BASE_PATH/../../.." && pwd) FILE_NAME=${1:-known-dependencies.txt} +MAVEN_COMMAND=${MAVEN_COMMAND:-mvn} -if [[ -d $DEP_PATH ]];then - echo "rm -r -f DEP_PATH" - rm -r -f $DEP_PATH +if [[ "$FILE_NAME" = /* ]]; then + OUTPUT_PATH=$FILE_NAME +else + OUTPUT_PATH=$BASE_PATH/$FILE_NAME fi -cd "$BASE_PATH"/../../../ || exit - -mvn dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory=$DEP_PATH +# Only remove this invocation's new temporary directory, never a shared folder. +DEPENDENCY_TEMP=$(mktemp -d "${TMPDIR:-/tmp}/hugegraph-dependencies.XXXXXX") +trap 'rm -rf -- "$DEPENDENCY_TEMP"' EXIT -ls $DEP_PATH | egrep -v "^hg|hugegraph|hubble" | sort -n > $BASE_PATH/$FILE_NAME -rm -r -f $DEP_PATH +cd "$ROOT_PATH" +"$MAVEN_COMMAND" -B -ntp dependency:copy-dependencies -DincludeScope=runtime \ + "-DoutputDirectory=$DEPENDENCY_TEMP/runtime" +REVISION=$("$MAVEN_COMMAND" -q -DforceStdout help:evaluate -Dexpression=project.version) +python3 "$BASE_PATH/dependency_inventory.py" collect \ + --runtime "$DEPENDENCY_TEMP/runtime" --root "$ROOT_PATH" \ + --revision "$REVISION" --output "$OUTPUT_PATH" diff --git a/install-dist/scripts/dependency/test_dependency_inventory.py b/install-dist/scripts/dependency/test_dependency_inventory.py new file mode 100644 index 0000000000..65e0c6e130 --- /dev/null +++ b/install-dist/scripts/dependency/test_dependency_inventory.py @@ -0,0 +1,156 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import contextlib +import io +import os +from pathlib import Path +import shutil +import subprocess +import tempfile +import unittest +import zipfile + +import dependency_inventory as inventory + + +class DependencyInventoryTest(unittest.TestCase): + + def setUp(self): + self.temporary = tempfile.TemporaryDirectory() + self.addCleanup(self.temporary.cleanup) + self.root = Path(self.temporary.name) / 'checkout' + self.runtime = self.root / 'runtime' + self.runtime.mkdir(parents=True) + self.jar(self.runtime / 'resolved-1.jar') + for kind in ('server', 'pd', 'store'): + directory = self.root / ('hugegraph-' + kind) / f'apache-hugegraph-{kind}-1.7.0/lib' + directory.mkdir(parents=True) + nested = self.jar_bytes({'example/Type.class': b'class fixture'}) + self.jar(directory / 'hugegraph-executable.jar', { + 'BOOT-INF/lib/injected-2.jar': nested, + }) + + def jar_bytes(self, entries=None): + data = io.BytesIO() + with zipfile.ZipFile(data, 'w') as archive: + for name, value in (entries or {'example/Type.class': b'class fixture'}).items(): + archive.writestr(name, value) + return data.getvalue() + + def jar(self, path, entries=None): + path.write_bytes(self.jar_bytes(entries)) + + def test_runtime_and_nested_shipped_union(self): + self.assertEqual(inventory.collect(self.runtime, self.root, '1.7.0'), + {'resolved-1.jar', 'injected-2.jar'}) + + def test_missing_runtime_empty_runtime_and_package_are_failures(self): + (self.root / 'empty').mkdir() + for directory in (self.root / 'absent', self.root / 'empty'): + with self.assertRaises(inventory.InventoryFailure): + inventory.collect(directory, self.root, '1.7.0') + shutil.rmtree(self.root / 'hugegraph-store') + with self.assertRaisesRegex(inventory.InventoryFailure, 'Missing packaged store'): + inventory.collect(self.runtime, self.root, '1.7.0') + + def test_corrupt_nested_or_runtime_jar_is_failure(self): + self.jar(self.root / 'hugegraph-pd/apache-hugegraph-pd-1.7.0/lib/hugegraph-executable.jar', { + 'BOOT-INF/lib/injected-2.jar': b'not a jar', + }) + with self.assertRaisesRegex(inventory.InventoryFailure, 'Cannot inspect shipped jar'): + inventory.collect(self.runtime, self.root, '1.7.0') + (self.runtime / 'resolved-1.jar').write_text('not a jar') + with self.assertRaisesRegex(inventory.InventoryFailure, 'Cannot inspect resolved jar'): + inventory.collect(self.runtime, self.root, '1.7.0') + + def test_checker_strict_additions_removals_and_missing_inputs(self): + known, current = self.root / 'known.txt', self.root / 'current.txt' + known.write_text('one-1.jar\ntwo-2.jar\n') + current.write_text('two-2.jar\none-1.jar\n') + with contextlib.redirect_stdout(io.StringIO()): + self.assertEqual(inventory.compare(known, current), 0) + for value in ('one-1.jar\n', 'one-1.jar\ntwo-2.jar\nnew-3.jar\n'): + current.write_text(value) + self.assertEqual(inventory.compare(known, current), 1) + for value in ('', 'not-a-jar\n', 'one-1.jar\none-1.jar\n'): + current.write_text(value) + with self.assertRaises(inventory.InventoryFailure): + inventory.compare(known, current) + current.unlink() + with self.assertRaises(OSError): + inventory.compare(known, current) + + def script_fixture(self): + directory = self.root / 'install-dist/scripts/dependency' + directory.mkdir(parents=True) + original = Path(__file__).parent + for name in ('regenerate_known_dependencies.sh', 'check_dependencies.sh', 'dependency_inventory.py'): + shutil.copyfile(original / name, directory / name) + maven = self.root / 'fake-mvn' + maven.write_text('''#!/usr/bin/env python3 +import os, pathlib, sys, zipfile +if os.environ.get('FAKE_MAVEN_FAIL'): + sys.exit(int(os.environ['FAKE_MAVEN_FAIL'])) +if 'dependency:copy-dependencies' in sys.argv: + value = next(value for value in sys.argv if value.startswith('-DoutputDirectory=')) + directory = pathlib.Path(value.split('=', 1)[1]) + directory.mkdir(parents=True) + with zipfile.ZipFile(directory / 'resolved-1.jar', 'w') as archive: + archive.writestr('example/Type.class', b'class fixture') +else: + print('1.7.0') +''') + maven.chmod(0o755) + return directory, dict(os.environ, MAVEN_COMMAND=str(maven)) + + def test_shell_producer_consumer_contract(self): + directory, environment = self.script_fixture() + current = self.root / 'target/dependency/current.txt' + generated = subprocess.run(['bash', str(directory / 'regenerate_known_dependencies.sh'), str(current)], + env=environment, capture_output=True, text=True) + self.assertEqual(generated.returncode, 0, generated.stderr) + self.assertEqual(inventory.read_inventory(current), ['injected-2.jar', 'resolved-1.jar']) + known = directory / 'known-dependencies.txt' + known.write_text(current.read_text()) + checked = subprocess.run(['bash', str(directory / 'check_dependencies.sh'), str(known), str(current)], + capture_output=True, text=True) + self.assertEqual(checked.returncode, 0, checked.stderr) + current.unlink() + missing = subprocess.run(['bash', str(directory / 'check_dependencies.sh'), str(known), str(current)], + capture_output=True, text=True) + self.assertNotEqual(missing.returncode, 0) + + def test_shell_maven_failure_does_not_publish_inventory(self): + directory, environment = self.script_fixture() + current = self.root / 'current.txt' + result = subprocess.run(['bash', str(directory / 'regenerate_known_dependencies.sh'), str(current)], + env=dict(environment, FAKE_MAVEN_FAIL='17'), capture_output=True, text=True) + self.assertEqual(result.returncode, 17) + self.assertFalse(current.exists()) + + def test_shell_missing_package_does_not_publish_inventory(self): + directory, environment = self.script_fixture() + shutil.rmtree(self.root / 'hugegraph-store') + current = self.root / 'current.txt' + result = subprocess.run(['bash', str(directory / 'regenerate_known_dependencies.sh'), str(current)], + env=environment, capture_output=True, text=True) + self.assertNotEqual(result.returncode, 0) + self.assertIn('Missing packaged store', result.stderr) + self.assertFalse(current.exists()) + + +if __name__ == '__main__': + unittest.main() diff --git a/install-dist/scripts/shared-foundation/check_shared_foundation.py b/install-dist/scripts/shared-foundation/check_shared_foundation.py new file mode 100644 index 0000000000..0e6ad5c415 --- /dev/null +++ b/install-dist/scripts/shared-foundation/check_shared_foundation.py @@ -0,0 +1,466 @@ +#!/usr/bin/env python3 +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Check shared ownership, resolved dependencies and shipped classpaths. + +Run after a reactor install/package: + python3 install-dist/scripts/shared-foundation/check_shared_foundation.py --revision 1.8.0 + +--source-only is an explicitly narrower check for fast source-edit iterations. +The full check always regenerates dependency trees; stale tree files are not evidence. +""" + +import argparse +import io +from pathlib import Path +import re +import subprocess +import sys +import xml.etree.ElementTree as ET +import zipfile + + +SOURCE_MODULES = ( + 'hugegraph-server/hugegraph-core', + 'hugegraph-struct', + 'hugegraph-commons/hugegraph-common', + 'hugegraph-commons/hugegraph-rpc', +) +DEPENDENCY_MODULES = ( + 'hugegraph-struct', + 'hugegraph-commons/hugegraph-common', + 'hugegraph-commons/hugegraph-rpc', + 'hugegraph-pd/hg-pd-service', + 'hugegraph-store/hg-store-core', + 'hugegraph-store/hg-store-node', +) +REQUIRED_ARTIFACTS = { + 'server': {'hugegraph-core', 'hugegraph-struct', 'hugegraph-common', 'hugegraph-rpc'}, + 'pd': {'hg-pd-service', 'hg-pd-core', 'hugegraph-common'}, + 'store': {'hg-store-node', 'hg-store-core', 'hugegraph-struct', 'hugegraph-common'}, +} +SCOPES = {'compile', 'runtime', 'provided', 'test', 'system', 'import'} +GROUP = 'org.apache.hugegraph' +SERVER_ARTIFACTS = {'hugegraph-server', 'hugegraph-core', 'hugegraph-api', 'hugegraph-dist', + 'hugegraph-hstore', 'hugegraph-hbase', 'hugegraph-rocksdb', 'hugegraph-example'} +SOURCE_IMPORT_CONFIGS = ( + 'hugegraph-server/hugegraph-dist/src/assembly/static/conf/gremlin-server.yaml', + 'hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft1/gremlin-server.yaml', + 'hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft2/gremlin-server.yaml', + 'hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft3/gremlin-server.yaml', +) + + +class CheckFailure(Exception): + pass + + +def retired_classes(): + path = Path(__file__).with_name('retired-core-classes.txt') + result = {line.strip() for line in path.read_text().splitlines() + if line.strip() and not line.startswith('#')} + if not result or any(not name.startswith(GROUP + '.') for name in result): + raise CheckFailure(f'Missing or invalid retired-owner manifest: {path}') + return result + + +def java_member_classes(source, package): + # Strip comments/literals before matching declarations, so references to a + # retired type in documentation, strings or class literals are harmless. + source = re.sub(r'//[^\n]*|/\*.*?\*/|"(?:\\.|[^"\\])*"|\'(?:\\.|[^\'\\])*\'', + '', source, flags=re.DOTALL) + tokens = re.findall(r'[A-Za-z_$][\w$]*|[{}.()]', source) + scopes = [] + pending = None + names = set() + for index, token in enumerate(tokens): + if (token in ('class', 'interface', 'enum') and + (index == 0 or tokens[index - 1] != '.') and + (not scopes or scopes[-1] is not None) and index + 1 < len(tokens) and + re.fullmatch(r'[A-Za-z_$][\w$]*', tokens[index + 1])): + pending = tokens[index + 1] + elif token == '{': + scopes.append(pending) + if pending is not None: + names.add(package + '.' + '$'.join(name for name in scopes if name is not None)) + pending = None + elif token == '}' and scopes: + scopes.pop() + return names + + +def is_retired_class(name, retired): + return any(name == owner or name.startswith(owner + '$') for owner in retired) + + +def server_module_inventory(root): + boundary = (root / 'hugegraph-server').resolve() + projects, visited, active = {}, set(), set() + + def visit(pom): + try: + pom = pom.resolve() + except (OSError, RuntimeError) as error: + raise CheckFailure(f'Cannot resolve declared Server POM: {pom}: {error}') from error + try: + pom.relative_to(boundary) + except ValueError as error: + raise CheckFailure(f'Declared Server POM escapes its reactor: {pom}') from error + if pom in active: + raise CheckFailure(f'Cyclic Server module declaration: {pom}') + if pom in visited: + return + if not pom.is_file(): + raise CheckFailure(f'Missing declared Server POM: {pom}') + try: + project = ET.parse(pom).getroot() + except ET.ParseError as error: + raise CheckFailure(f'Invalid Server module POM: {pom}: {error}') from error + if project.tag.rsplit('}', 1)[-1] != 'project': + raise CheckFailure(f'Invalid Server project element: {pom}') + namespace = project.tag[:-len('project')] + artifact = (project.findtext(namespace + 'artifactId') or '').strip() + if not re.fullmatch(r'[A-Za-z0-9_.-]+', artifact): + raise CheckFailure(f'Missing or nonliteral Server artifactId: {pom}') + if pom.parent in projects and projects[pom.parent] != artifact: + raise CheckFailure(f'Server projects share a source directory: {pom.parent}') + projects[pom.parent] = artifact + active.add(pom) + # Include every possible profile, irrespective of the current host or + # active profiles. Inactive modules must not become a retirement loophole. + modules = project.findall(namespace + 'modules/' + namespace + 'module') + modules.extend(project.findall(namespace + 'profiles/' + namespace + 'profile/' + + namespace + 'modules/' + namespace + 'module')) + for declaration in modules: + value = (declaration.text or '').strip() + if not value or '$' in value: + raise CheckFailure(f'Empty or nonliteral Server module declaration: {pom}: {value}') + target = pom.parent / value + visit(target if target.suffix == '.xml' or target.is_file() else target / 'pom.xml') + active.remove(pom) + visited.add(pom) + + visit(boundary / 'pom.xml') + test_roots = [directory for directory, artifact in projects.items() if artifact == 'hugegraph-test'] + return {directory: artifact for directory, artifact in projects.items() + if not any(directory == test or test in directory.parents for test in test_roots)} + + +def check_sources(root, retired): + root = root.resolve() + owners = {} + counts = {} + production_roots = set() + for module in SOURCE_MODULES: + directories = [root / module / 'src/main' / kind for kind in ('java', 'dev')] + if not any(list(directory.rglob('*.java')) for directory in directories): + raise CheckFailure(f'Missing production sources: {root / module / "src/main"}') + production_roots.update(directories) + # Use the same recursively declared reactor inventory as shipped ownership, + # never search copied distributions or target directories for module POMs. + for module in server_module_inventory(root): + production_roots.update(module / 'src/main' / kind for kind in ('java', 'dev')) + # Generated grpc sources in src/main/java are outside the shared-owner + # scan. Hand-maintained production sources beside them must still be checked. + for pattern in ('hugegraph-*/src/main/dev', 'hugegraph-*/*/src/main/dev'): + production_roots.update(directory for directory in root.glob(pattern) + if directory.relative_to(root).parts[0] != 'hugegraph-server') + for directory in sorted(production_roots): + module = str(directory.parent.parent.parent.relative_to(root)) + files = sorted(directory.rglob('*.java')) + counts[module] = counts.get(module, 0) + len(files) + for path in files: + source = path.read_text() + package = re.search(r'^\s*package\s+([\w.]+)\s*;', source, re.MULTILINE) + if not package: + raise CheckFailure(f'Cannot determine source package: {path}') + name = package.group(1) + '.' + path.stem + if not name.startswith(GROUP + '.'): + continue + if module == 'hugegraph-server' or module.startswith('hugegraph-server/'): + declared = java_member_classes(source, package.group(1)) | {name} + if any(is_retired_class(declaration, retired) for declaration in declared): + raise CheckFailure(f'Retired shared implementation returned to Server: {path}') + if name in owners: + raise CheckFailure(f'Duplicate source FQCN {name}: {owners[name]} and {path}') + owners[name] = path + print(f'Source ownership checked: {counts}') + return owners + + +def class_imports(path): + if not path.is_file(): + raise CheckFailure(f'Missing Gremlin import configuration: {path}') + # This is a deliberately narrow reader for classImports flow/block lists, + # not a YAML implementation. Unknown shapes fail rather than evade checks. + lines = [re.sub(r'#.*$', '', line) for line in path.read_text().splitlines()] + imports = [] + for index, line in enumerate(lines): + match = re.match(r'^(\s*)classImports\s*:\s*(.*)$', line) + if not match: + continue + indent, tail = len(match.group(1)), match.group(2).strip() + if tail.startswith('['): + body = '\n'.join([tail] + lines[index + 1:]) + end = body.find(']') + if end < 0: + raise CheckFailure(f'Unterminated classImports list: {path}') + values = body[1:end].split(',') + elif not tail: + values = [] + for following in lines[index + 1:]: + if not following.strip(): + continue + following_indent = len(following) - len(following.lstrip()) + entry = following.strip() + if following_indent < indent or (following_indent == indent and not entry.startswith('-')): + break + if not entry.startswith('- '): + raise CheckFailure(f'Unsupported classImports entry: {path}: {entry}') + values.append(entry[2:]) + else: + raise CheckFailure(f'Unsupported classImports shape: {path}: {tail}') + for value in values: + name = value.strip().strip('"\'') + if not name: + continue + if not re.fullmatch(r'[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)+', name): + raise CheckFailure(f'Invalid classImports class name: {path}: {name}') + imports.append(name) + if not imports: + raise CheckFailure(f'Missing or empty classImports list: {path}') + return imports + + +def check_class_imports(path, available, local_only=False): + imports = class_imports(path) + for name in imports: + # JDK classes are supplied by the runtime, not distribution jars. + # Gremlin startup tests verify runtime loading, beyond this ownership check. + if name.startswith('java.') or (local_only and not name.startswith(GROUP + '.')): + continue + if name not in available: + raise CheckFailure(f'Gremlin classImports class is unavailable: {name} ({path})') + print(f'Gremlin classImports checked: {path} ({len(imports)} imports)') + + +def check_source_imports(root, owners): + for path in SOURCE_IMPORT_CONFIGS: + check_class_imports(root / path, owners, local_only=True) + + +def parse_tree(path, expected_artifact): + if not path.is_file(): + raise CheckFailure(f'Missing resolved dependency tree: {path}') + nodes = [] + for line in path.read_text().splitlines(): + if not line.strip(): + continue + coordinate = re.sub(r'^[\s|+\\-]*', '', line).strip() + coordinate = re.sub(r' \(optional\)$', '', coordinate) + parts = coordinate.split(':') + if (len(parts) < 4 or len(parts) > 6 or + any(not part or re.search(r'\s', part) for part in parts)): + raise CheckFailure(f'Malformed resolved tree line in {path}: {line}') + if nodes and parts[-1] not in SCOPES: + raise CheckFailure(f'Missing dependency scope in {path}: {line}') + nodes.append((parts[0], parts[1])) + if not nodes or nodes[0] != (GROUP, expected_artifact): + raise CheckFailure(f'Wrong or empty dependency tree root: {path}; expected {expected_artifact}') + return nodes + + +def check_tree(path, module): + artifact = module.rsplit('/', 1)[-1] + nodes = parse_tree(path, artifact) + forbidden = set() + if module.startswith(('hugegraph-pd/', 'hugegraph-store/')): + forbidden.add('hugegraph-core') + if artifact == 'hugegraph-struct': + forbidden.update(('hugegraph-core', 'hugegraph-rpc')) + if artifact == 'hugegraph-rpc': + forbidden.update(('hugegraph-core', 'hugegraph-struct')) + if artifact == 'hugegraph-common': + forbidden.update(('hugegraph-core', 'hugegraph-struct', 'hugegraph-server', + 'hugegraph-store', 'hugegraph-pd')) + for group, name in nodes[1:]: + if group != GROUP: + continue + component_dependency = (name.startswith(('hg-pd-', 'hg-store-')) or + name in ('hugegraph-pd', 'hugegraph-store')) + if name in forbidden or (artifact in ('hugegraph-struct', 'hugegraph-common', 'hugegraph-rpc') and + component_dependency): + raise CheckFailure(f'Forbidden resolved dependency of {artifact}: {group}:{name} ({path})') + print(f'Resolved dependency boundary checked: {artifact} ({len(nodes) - 1} dependencies)') + + +def select_tree(lines, artifact): + starts = [i for i, line in enumerate(lines) if line.startswith(GROUP + ':')] + selected = [] + for index, start in enumerate(starts): + if lines[start].split(':')[1] == artifact: + stop = starts[index + 1] if index + 1 < len(starts) else len(lines) + selected.append(lines[start:stop]) + if len(selected) != 1: + raise CheckFailure(f'Expected exactly one current reactor tree for {artifact}') + return '\n'.join(selected[0]) + '\n' + + +def resolve_dependencies(root, maven): + directory = root / 'target/shared-foundation' + directory.mkdir(parents=True, exist_ok=True) + modules = set(DEPENDENCY_MODULES) + # Cover every distributed submodule, including standalone client/transfer + # modules and tests, not only dependencies currently reachable from services. + for parent in ('hugegraph-pd', 'hugegraph-store'): + modules.update(str(path.parent.relative_to(root)) + for path in (root / parent).glob('*/pom.xml')) + for module in modules: + if not (root / module / 'pom.xml').is_file(): + raise CheckFailure(f'Missing expected Maven module: {module}') + output = directory / 'reactor-dependencies.txt' + output.unlink(missing_ok=True) + # Resolve current reactor models, never reuse old tree files. Upstream + # project POMs are read from this checkout rather than a stale local install. + subprocess.run([ + maven, '-B', '-ntp', '-pl', ','.join(sorted(modules)), '-am', + 'org.apache.maven.plugins:maven-dependency-plugin:3.8.1:tree', + '-DoutputType=text', f'-DoutputFile={output}', '-DappendOutput=true', + ], cwd=root, check=True) + if not output.is_file(): + raise CheckFailure(f'Missing resolved reactor dependencies: {output}') + lines = output.read_text().splitlines() + for module in sorted(modules): + artifact = module.rsplit('/', 1)[-1] + selected = directory / (artifact + '.txt') + selected.write_text(select_tree(lines, artifact)) + check_tree(selected, module) + + +def properties(text): + return {key.strip(): value.strip() for line in text.splitlines() + if line.strip() and not line.lstrip().startswith(('#', '!')) and '=' in line + for key, value in [line.split('=', 1)]} + + +def server_artifact_ids(root): + return set(server_module_inventory(root).values()) + + +def scan_jar(source, label, owners, artifacts, retired, distribution, available=None, + expected_revision=None, server_artifacts=None): + if server_artifacts is None: + server_artifacts = SERVER_ARTIFACTS + try: + archive = zipfile.ZipFile(source) + except (OSError, zipfile.BadZipFile) as error: + raise CheckFailure(f'Invalid shipped jar {label}: {error}') from error + with archive: + names = archive.namelist() + identities = set() + for name in names: + if name.startswith('META-INF/maven/') and name.endswith('/pom.properties'): + values = properties(archive.read(name).decode('utf-8')) + if values.get('groupId') == GROUP: + artifact = values.get('artifactId') + if not artifact or not values.get('version'): + raise CheckFailure(f'Incomplete artifact metadata in {label}: {name}') + if expected_revision is not None and values['version'] != expected_revision: + raise CheckFailure(f'Stale shipped artifact {GROUP}:{artifact}:{values["version"]} ' + f'in {label}; expected {expected_revision}') + identities.add(artifact) + artifacts.update(identities) + if distribution in ('pd', 'store') and 'hugegraph-core' in identities: + raise CheckFailure(f'Forbidden hugegraph-core shipped in {distribution}: {label}') + seen_entries = set() + for name in names: + if name.startswith(('BOOT-INF/lib/', 'WEB-INF/lib/')) and name.endswith('.jar'): + scan_jar(io.BytesIO(archive.read(name)), f'{label}!/{name}', owners, + artifacts, retired, distribution, available, expected_revision, server_artifacts) + continue + normalized = re.sub(r'^(?:BOOT-INF/classes/|WEB-INF/classes/|META-INF/versions/\d+/)', '', name) + if available is not None and normalized.endswith('.class'): + available.add(normalized[:-6].replace('/', '.')) + if not normalized.startswith('org/apache/hugegraph/') or not normalized.endswith('.class'): + continue + if name in seen_entries: + raise CheckFailure(f'Duplicate class entry inside jar {label}: {name}') + seen_entries.add(name) + fqcn = normalized[:-6].replace('/', '.') + if identities & server_artifacts and is_retired_class(fqcn, retired): + raise CheckFailure(f'Retired shared class shipped in Server: {fqcn} ({label})') + previous = owners.get(fqcn) + if previous is not None and previous != label: + raise CheckFailure(f'Duplicate shipped FQCN {fqcn}: {previous} and {label}') + # Multi-release variants within the same jar are a single owner. + owners[fqcn] = label + + +def check_distribution(path, kind, retired, expected_revision=None, server_artifacts=None): + library = path / 'lib' + jars = sorted(library.rglob('*.jar')) + if not library.is_dir() or not jars: + raise CheckFailure(f'Missing shipped {kind} lib jars: {library}') + for name in ('ext', 'plugins'): + if (path / name).exists(): + jars.extend(sorted((path / name).rglob('*.jar'))) + owners = {} + artifacts = set() + available = set() + for jar in jars: + scan_jar(jar, str(jar), owners, artifacts, retired, kind, available, expected_revision, server_artifacts) + missing = REQUIRED_ARTIFACTS[kind] - artifacts + if missing: + raise CheckFailure(f'Missing expected artifacts in {kind} distribution: {sorted(missing)}') + if not owners: + raise CheckFailure(f'No HugeGraph classes found in shipped {kind} jars') + if kind == 'server': + check_class_imports(path / 'conf/gremlin-server.yaml', available) + print(f'Shipped {kind} classpath checked: {len(owners)} HugeGraph classes, ' + f'{len(artifacts)} project artifacts') + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--root', type=Path, default=Path(__file__).resolve().parents[3]) + parser.add_argument('--source-only', action='store_true') + parser.add_argument('--revision', help='Exact version of the freshly assembled distributions') + parser.add_argument('--maven', default='mvn', help='Maven executable') + args = parser.parse_args() + if not args.source_only and not args.revision: + parser.error('--revision is required for resolved dependency and distribution checks') + root = args.root.resolve() + try: + retired = retired_classes() + owners = check_sources(root, retired) + check_source_imports(root, owners) + if args.source_only: + print('Source-only check passed; dependencies and distributions were NOT checked.') + return 0 + resolve_dependencies(root, args.maven) + server_artifacts = server_artifact_ids(root) + for kind in REQUIRED_ARTIFACTS: + path = root / ('hugegraph-' + kind) / f'apache-hugegraph-{kind}-{args.revision}' + check_distribution(path, kind, retired, args.revision, server_artifacts) + except (CheckFailure, OSError, UnicodeError, subprocess.CalledProcessError) as error: + print(f'Shared foundation check FAILED: {error}', file=sys.stderr) + return 1 + print('Shared foundation ownership, resolved dependencies and shipped classpaths passed.') + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/install-dist/scripts/shared-foundation/retired-core-classes.txt b/install-dist/scripts/shared-foundation/retired-core-classes.txt new file mode 100644 index 0000000000..2aeb3c2ed0 --- /dev/null +++ b/install-dist/scripts/shared-foundation/retired-core-classes.txt @@ -0,0 +1,96 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Shared owners removed from core. Do not reintroduce these FQCNs in core. +org.apache.hugegraph.HugeException +org.apache.hugegraph.analyzer.Analyzer +org.apache.hugegraph.analyzer.AnalyzerFactory +org.apache.hugegraph.analyzer.AnsjAnalyzer +org.apache.hugegraph.analyzer.HanLPAnalyzer +org.apache.hugegraph.analyzer.IKAnalyzer +org.apache.hugegraph.analyzer.JcsegAnalyzer +org.apache.hugegraph.analyzer.JiebaAnalyzer +org.apache.hugegraph.analyzer.MMSeg4JAnalyzer +org.apache.hugegraph.analyzer.SmartCNAnalyzer +org.apache.hugegraph.auth.AuthConstant +org.apache.hugegraph.auth.TokenGenerator +org.apache.hugegraph.backend.BackendException +org.apache.hugegraph.backend.id.EdgeId +org.apache.hugegraph.backend.id.Id +org.apache.hugegraph.backend.id.IdGenerator +org.apache.hugegraph.backend.id.IdUtil +org.apache.hugegraph.backend.id.SplicingIdGenerator +org.apache.hugegraph.backend.query.Aggregate +org.apache.hugegraph.backend.query.BatchConditionQuery +org.apache.hugegraph.backend.query.Condition +org.apache.hugegraph.backend.query.ConditionQuery +org.apache.hugegraph.backend.query.IdPrefixQuery +org.apache.hugegraph.backend.query.IdQuery +org.apache.hugegraph.backend.query.IdRangeQuery +org.apache.hugegraph.backend.query.Query +org.apache.hugegraph.backend.query.serializer.AbstractSerializerAdapter +org.apache.hugegraph.backend.query.serializer.QueryAdapter +org.apache.hugegraph.backend.query.serializer.QueryIdAdapter +org.apache.hugegraph.backend.serializer.BytesBuffer +org.apache.hugegraph.backend.store.BackendEntry$BackendColumn +org.apache.hugegraph.backend.store.Shard +org.apache.hugegraph.backend.tx.GraphIndexTransaction$MatchedIndex +org.apache.hugegraph.exception.ErrorCodeProvider +org.apache.hugegraph.exception.LimitExceedException +org.apache.hugegraph.exception.NotAllowException +org.apache.hugegraph.exception.NotFoundException +org.apache.hugegraph.exception.NotSupportException +org.apache.hugegraph.rpc.RpcServiceConfig4Client +org.apache.hugegraph.rpc.RpcServiceConfig4Server +org.apache.hugegraph.schema.EdgeLabel +org.apache.hugegraph.schema.IndexLabel +org.apache.hugegraph.schema.PropertyKey +org.apache.hugegraph.schema.SchemaElement +org.apache.hugegraph.schema.SchemaLabel +org.apache.hugegraph.schema.Userdata +org.apache.hugegraph.schema.VertexLabel +org.apache.hugegraph.schema.builder.SchemaBuilder +org.apache.hugegraph.structure.GraphType +org.apache.hugegraph.structure.HugeIndex +org.apache.hugegraph.type.HugeType +org.apache.hugegraph.type.Idfiable +org.apache.hugegraph.type.Indexable +org.apache.hugegraph.type.Nameable +org.apache.hugegraph.type.Propertiable +org.apache.hugegraph.type.Typeable +org.apache.hugegraph.type.define.Action +org.apache.hugegraph.type.define.AggregateType +org.apache.hugegraph.type.define.Cardinality +org.apache.hugegraph.type.define.CollectionType +org.apache.hugegraph.type.define.DataType +org.apache.hugegraph.type.define.Directions +org.apache.hugegraph.type.define.EdgeLabelType +org.apache.hugegraph.type.define.Frequency +org.apache.hugegraph.type.define.HugeKeys +org.apache.hugegraph.type.define.IdStrategy +org.apache.hugegraph.type.define.IndexType +org.apache.hugegraph.type.define.SchemaStatus +org.apache.hugegraph.type.define.SerialEnum +org.apache.hugegraph.type.define.WriteType +org.apache.hugegraph.util.Blob +org.apache.hugegraph.util.KryoUtil +org.apache.hugegraph.util.LZ4Util +org.apache.hugegraph.util.StringEncoding +org.apache.hugegraph.util.collection.CollectionFactory +org.apache.hugegraph.util.collection.IdSet +org.apache.hugegraph.util.collection.IntIterator +org.apache.hugegraph.util.collection.IntMap +org.apache.hugegraph.util.collection.IntSet diff --git a/install-dist/scripts/shared-foundation/test_shared_foundation.py b/install-dist/scripts/shared-foundation/test_shared_foundation.py new file mode 100644 index 0000000000..0707f22afc --- /dev/null +++ b/install-dist/scripts/shared-foundation/test_shared_foundation.py @@ -0,0 +1,638 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import io +from pathlib import Path +import tempfile +import unittest +import xml.etree.ElementTree as ET +import zipfile + +import check_shared_foundation as check + + +class FoundationChecksTest(unittest.TestCase): + + def setUp(self): + self.temporary = tempfile.TemporaryDirectory() + self.root = Path(self.temporary.name) + self.addCleanup(self.temporary.cleanup) + + def jar(self, artifact, classes=(), entries=None, version='1.8.0', group=check.GROUP): + buffer = io.BytesIO() + with zipfile.ZipFile(buffer, 'w') as archive: + archive.writestr(f'META-INF/maven/{group}/{artifact}/pom.properties', + f'groupId={group}\nartifactId={artifact}\nversion={version}\n') + for name in classes: + archive.writestr(name, b'class fixture') + for name, value in (entries or {}).items(): + archive.writestr(name, value) + return buffer.getvalue() + + def distribution(self, kind='server', nested=False): + path = self.root / kind + (path / 'lib').mkdir(parents=True) + jars = {} + for artifact in check.REQUIRED_ARTIFACTS[kind]: + name = artifact.replace('-', '_') + jars[artifact] = self.jar(artifact, [f'org/apache/hugegraph/{name}.class']) + if nested: + executable = 'hg-pd-service' if kind == 'pd' else 'hg-store-node' + entries = {f'BOOT-INF/lib/{name}.jar': value for name, value in jars.items() + if name != executable} + data = self.jar(executable, [f'BOOT-INF/classes/org/apache/hugegraph/{executable}.class'], entries) + (path / 'lib' / 'service.jar').write_bytes(data) + else: + for name, value in jars.items(): + (path / 'lib' / (name + '.jar')).write_bytes(value) + if kind == 'server': + (path / 'conf').mkdir() + (path / 'conf/gremlin-server.yaml').write_text( + 'classImports: [org.apache.hugegraph.hugegraph_core]\n') + return path + + def tree(self, artifact, descendants=''): + path = self.root / 'tree.txt' + path.write_text(f'{check.GROUP}:{artifact}:jar:1.8.0\n' + descendants) + return path + + def test_shipped_classpaths_flat_and_boot(self): + for kind in ('server', 'pd', 'store'): + check.check_distribution(self.distribution(kind, nested=kind != 'server'), kind, set()) + + def test_duplicate_class_in_two_shipped_jars_fails(self): + path = self.distribution() + (path / 'lib' / 'copy.jar').write_bytes(self.jar('copy', ['org/apache/hugegraph/hugegraph_struct.class'])) + with self.assertRaisesRegex(check.CheckFailure, 'Duplicate shipped FQCN'): + check.check_distribution(path, 'server', set()) + + def test_duplicate_in_nested_boot_jar_fails(self): + duplicate = 'org/apache/hugegraph/Conflict.class' + jars = {f'BOOT-INF/lib/{name}.jar': self.jar(name, [duplicate]) for name in ('one', 'two')} + path = self.root / 'boot.jar' + path.write_bytes(self.jar('boot', entries=jars)) + with self.assertRaisesRegex(check.CheckFailure, 'Duplicate shipped FQCN'): + check.scan_jar(path, str(path), {}, set(), set(), 'pd') + + def test_multi_release_variants_in_one_jar_are_one_owner(self): + path = self.root / 'mr.jar' + path.write_bytes(self.jar('variant', ['org/apache/hugegraph/Variant.class', + 'META-INF/versions/11/org/apache/hugegraph/Variant.class'])) + owners = {} + check.scan_jar(path, str(path), owners, set(), set(), 'server') + self.assertEqual(list(owners), ['org.apache.hugegraph.Variant']) + + def test_missing_distribution_and_required_artifact_fail_closed(self): + with self.assertRaisesRegex(check.CheckFailure, 'Missing shipped'): + check.check_distribution(self.root / 'absent', 'server', set()) + path = self.distribution() + (path / 'lib' / 'hugegraph-struct.jar').unlink() + with self.assertRaisesRegex(check.CheckFailure, 'Missing expected artifacts'): + check.check_distribution(path, 'server', set()) + + def test_corrupt_jar_is_failure(self): + path = self.distribution() + (path / 'lib' / 'broken.jar').write_text('not a zip') + with self.assertRaisesRegex(check.CheckFailure, 'Invalid shipped jar'): + check.check_distribution(path, 'server', set()) + + def test_nested_core_shipped_with_pd_is_failure(self): + path = self.distribution('pd', nested=True) + (path / 'lib' / 'extra.jar').write_bytes(self.jar('extra', entries={ + 'BOOT-INF/lib/core.jar': self.jar('hugegraph-core', ['org/apache/hugegraph/Core.class']) + })) + with self.assertRaisesRegex(check.CheckFailure, 'Forbidden hugegraph-core shipped'): + check.check_distribution(path, 'pd', set()) + + def test_transitive_forbidden_dependencies_fail(self): + for module, forbidden in (('hugegraph-pd/hg-pd-service', 'hugegraph-core'), + ('hugegraph-store/hg-store-core', 'hugegraph-core'), + ('hugegraph-struct', 'hg-pd-client'), + ('hugegraph-struct', 'hugegraph-core'), + ('hugegraph-commons/hugegraph-common', 'hg-store-client')): + with self.subTest(module=module, forbidden=forbidden): + artifact = module.rsplit('/', 1)[-1] + descendants = (f'+- external:parent:jar:1.0:compile\n' + f'| \\- {check.GROUP}:{forbidden}:jar:1.8.0:compile\n') + with self.assertRaisesRegex(check.CheckFailure, 'Forbidden resolved dependency'): + check.check_tree(self.tree(artifact, descendants), module) + + def test_struct_rejects_all_pd_store_component_dependencies(self): + for name in ('hg-pd-service', 'hg-store-common', 'hugegraph-pd', 'hugegraph-store'): + for prefix in ('', '+- external:parent:jar:1.0:compile\n| '): + with self.subTest(name=name, transitive=bool(prefix)): + descendants = prefix + f'\\- {check.GROUP}:{name}:jar:1.8.0:compile\n' + with self.assertRaisesRegex(check.CheckFailure, 'Forbidden resolved dependency'): + check.check_tree(self.tree('hugegraph-struct', descendants), 'hugegraph-struct') + # The boundary concerns HugeGraph components, not similarly named external artifacts. + tree = self.tree('hugegraph-struct', '\\- external:hg-pd-service:jar:1.0:compile\n') + check.check_tree(tree, 'hugegraph-struct') + + def test_allowed_kryo_dependency_and_classifier(self): + tree = self.tree('hugegraph-struct', '\\- org.apache.tinkerpop:gremlin-shaded:jar:1.0:compile\n' + '+- external:native:jar:linux:1.0:runtime (optional)\n') + check.check_tree(tree, 'hugegraph-struct') + + def test_missing_wrong_or_malformed_tree_fails_closed(self): + with self.assertRaisesRegex(check.CheckFailure, 'Missing resolved'): + check.parse_tree(self.root / 'absent', 'hugegraph-struct') + for value in ('', 'this is a Maven error\n', f'{check.GROUP}:wrong:jar:1.8.0\n', + f'{check.GROUP}:hugegraph-struct:jar:1.8.0\n+- broken:data\n'): + path = self.root / 'bad.txt' + path.write_text(value) + with self.subTest(value=value), self.assertRaises(check.CheckFailure): + check.parse_tree(path, 'hugegraph-struct') + + def sources(self): + self.declare_server_module('hugegraph-core') + for index, module in enumerate(check.SOURCE_MODULES): + path = self.root / module / 'src/main/java/org/apache/hugegraph' / f'Unique{index}.java' + path.parent.mkdir(parents=True) + path.write_text(f'package org.apache.hugegraph;\npublic class Unique{index} {{}}\n') + + def declare_server_module(self, module): + namespace = '{http://maven.apache.org/POM/4.0.0}' + root = self.root / 'hugegraph-server' + root.mkdir(exist_ok=True) + pom = root / 'pom.xml' + if not pom.exists(): + pom.write_text('' + 'hugegraph-server') + tree = ET.parse(pom) + modules = tree.getroot().find(namespace + 'modules') + if module not in [entry.text for entry in modules]: + ET.SubElement(modules, namespace + 'module').text = module + tree.write(pom, encoding='unicode') + child = root / module / 'pom.xml' + child.parent.mkdir(parents=True, exist_ok=True) + if not child.exists(): + child.write_text('' + '' + Path(module).name + '') + return child + + def test_target_reactor_tree_must_exist_exactly_once(self): + lines = ['org.apache.hugegraph:hugegraph: pom:1.8.0'.replace(': ', ':'), + 'org.apache.hugegraph:hugegraph-struct:jar:1.8.0', + '+- external:one:jar:1.0:compile', + 'org.apache.hugegraph:hg-store-core:jar:1.8.0', + '\\- org.apache.hugegraph:hugegraph-struct:jar:1.8.0:compile'] + self.assertEqual(check.select_tree(lines, 'hugegraph-struct'), '\n'.join(lines[1:3]) + '\n') + with self.assertRaisesRegex(check.CheckFailure, 'exactly one'): + check.select_tree(lines, 'missing') + with self.assertRaisesRegex(check.CheckFailure, 'exactly one'): + check.select_tree(lines + lines[1:3], 'hugegraph-struct') + + def test_source_duplicates_and_retired_owner_are_rejected(self): + self.sources() + check.check_sources(self.root, set()) + path = self.root / check.SOURCE_MODULES[1] / 'src/main/java/org/apache/hugegraph/Unique0.java' + path.write_text('package org.apache.hugegraph;\npublic class Unique0 {}\n') + with self.assertRaisesRegex(check.CheckFailure, 'Duplicate source FQCN'): + check.check_sources(self.root, set()) + path.unlink() + with self.assertRaisesRegex(check.CheckFailure, 'Retired shared implementation'): + check.check_sources(self.root, {'org.apache.hugegraph.Unique0'}) + + def test_manual_dev_sources_cannot_duplicate_shared_owners(self): + self.sources() + # Both the shared modules' alternate source roots and hand-maintained + # grpc helpers are production input, unlike generated grpc Java sources. + for module in (check.SOURCE_MODULES[1], 'hugegraph-store/hg-store-grpc'): + with self.subTest(module=module): + path = self.root / module / 'src/main/dev/org/apache/hugegraph/Unique0.java' + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text('package org.apache.hugegraph;\npublic class Unique0 {}\n') + with self.assertRaisesRegex(check.CheckFailure, 'Duplicate source FQCN'): + check.check_sources(self.root, set()) + path.unlink() + + def test_server_api_backend_and_dist_source_duplicates_are_rejected(self): + self.sources() + for module in ('hugegraph-api', 'hugegraph-hstore', 'hugegraph-dist'): + self.declare_server_module(module) + with self.subTest(module=module): + path = (self.root / 'hugegraph-server' / module / + 'src/main/java/org/apache/hugegraph/Unique0.java') + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text('package org.apache.hugegraph;\npublic class Unique0 {}\n') + with self.assertRaisesRegex(check.CheckFailure, 'Duplicate source FQCN'): + check.check_sources(self.root, set()) + path.unlink() + self.declare_server_module('hugegraph-test') + fixture = (self.root / 'hugegraph-server/hugegraph-test/' + 'src/main/java/org/apache/hugegraph/Unique0.java') + fixture.parent.mkdir(parents=True) + fixture.write_text('package org.apache.hugegraph;\npublic class Unique0 {}\n') + check.check_sources(self.root, set()) + + def test_retired_owner_cannot_return_through_core_dev_sources(self): + self.sources() + path = self.root / check.SOURCE_MODULES[0] / 'src/main/dev/org/apache/hugegraph/Retired.java' + path.parent.mkdir(parents=True) + path.write_text('package org.apache.hugegraph;\npublic class Retired {}\n') + with self.assertRaisesRegex(check.CheckFailure, 'Retired shared implementation'): + check.check_sources(self.root, {'org.apache.hugegraph.Retired'}) + + def test_retired_owner_in_core_jar_is_rejected(self): + retired = check.retired_classes() + for name in ('org.apache.hugegraph.backend.id.Id', 'org.apache.hugegraph.backend.store.Shard'): + with self.subTest(name=name): + self.assertIn(name, retired) + path = self.root / 'core.jar' + entry = name.replace('.', '/') + '$Inner.class' + path.write_bytes(self.jar('hugegraph-core', [entry])) + with self.assertRaisesRegex(check.CheckFailure, 'Retired shared class shipped'): + check.scan_jar(path, str(path), {}, set(), retired, 'server') + + def test_canonical_shard_allowed_and_old_core_owner_rejected(self): + self.sources() + retired = check.retired_classes() + relative = 'src/main/java/org/apache/hugegraph/backend/Shard.java' + canonical = self.root / 'hugegraph-struct' / relative + canonical.parent.mkdir(parents=True) + canonical.write_text('package org.apache.hugegraph.backend;\npublic class Shard {}\n') + check.check_sources(self.root, retired) + old = (self.root / check.SOURCE_MODULES[0] / + 'src/main/java/org/apache/hugegraph/backend/store/Shard.java') + old.parent.mkdir(parents=True) + old.write_text('package org.apache.hugegraph.backend.store;\npublic class Shard {}\n') + with self.assertRaisesRegex(check.CheckFailure, 'Retired shared implementation'): + check.check_sources(self.root, retired) + + def test_retired_nested_source_owner_preserves_entry_and_iterators(self): + self.sources() + retired = check.retired_classes() + owner = 'org.apache.hugegraph.backend.store.BackendEntry$BackendColumn' + self.assertIn(owner, retired) + path = (self.root / check.SOURCE_MODULES[0] / + 'src/main/java/org/apache/hugegraph/backend/store/BackendEntry.java') + path.parent.mkdir(parents=True) + source = '''package org.apache.hugegraph.backend.store; +interface BackendEntry { + String text = "class BackendColumn {}"; + // class BackendColumn {} + Class reference = Other.BackendColumn.class; + interface BackendColumnIterator { class EmptyIterator {} } + class Other { class BackendColumn {} } + default void example() { class BackendColumn {} } +} +''' + path.write_text(source) + check.check_sources(self.root, retired) + for declaration in ('class BackendColumn {}', 'interface BackendColumn {}', + 'enum BackendColumn { VALUE }'): + with self.subTest(declaration=declaration): + path.write_text(source.replace('interface BackendEntry {', + 'interface BackendEntry {\n' + declaration)) + with self.assertRaisesRegex(check.CheckFailure, 'Retired shared implementation'): + check.check_sources(self.root, retired) + + def test_retired_nested_jar_owner_preserves_entry_and_iterators(self): + retired = check.retired_classes() + prefix = 'org/apache/hugegraph/backend/store/BackendEntry' + path = self.root / 'core.jar' + allowed = [prefix + suffix + '.class' for suffix in + ('', '$BackendColumnIterator', '$BackendColumnIterator$EmptyIterator', + '$Other$BackendColumn')] + path.write_bytes(self.jar('hugegraph-core', allowed)) + check.scan_jar(path, str(path), {}, set(), retired, 'server') + for suffix in ('$BackendColumn', '$BackendColumn$Child'): + with self.subTest(suffix=suffix): + path.write_bytes(self.jar('hugegraph-core', allowed + [prefix + suffix + '.class'])) + with self.assertRaisesRegex(check.CheckFailure, 'Retired shared class shipped'): + check.scan_jar(path, str(path), {}, set(), retired, 'server') + + def test_retired_index_sources_preserve_transaction_and_shared_models(self): + self.sources() + retired = check.retired_classes() + self.assertIn('org.apache.hugegraph.structure.HugeIndex', retired) + self.assertIn('org.apache.hugegraph.backend.tx.GraphIndexTransaction$MatchedIndex', retired) + for package, name in (('structure', 'Index'), ('query', 'MatchedIndex')): + path = (self.root / 'hugegraph-struct/src/main/java/org/apache/hugegraph' / + package / (name + '.java')) + path.parent.mkdir(parents=True) + path.write_text(f'package org.apache.hugegraph.{package};\npublic class {name} {{}}\n') + transaction = (self.root / check.SOURCE_MODULES[0] / + 'src/main/java/org/apache/hugegraph/backend/tx/GraphIndexTransaction.java') + transaction.parent.mkdir(parents=True) + source = '''package org.apache.hugegraph.backend.tx; +class GraphIndexTransaction { + String text = "class MatchedIndex {}"; + class MatchedIndexIterator {} + class Other { class MatchedIndex {} } +} +''' + transaction.write_text(source) + check.check_sources(self.root, retired) + huge_index = (self.root / check.SOURCE_MODULES[0] / + 'src/main/java/org/apache/hugegraph/structure/HugeIndex.java') + huge_index.parent.mkdir(parents=True) + huge_index.write_text('package org.apache.hugegraph.structure;\nclass HugeIndex {}\n') + with self.assertRaisesRegex(check.CheckFailure, 'Retired shared implementation'): + check.check_sources(self.root, retired) + huge_index.unlink() + transaction.write_text(source.replace('class GraphIndexTransaction {', + 'class GraphIndexTransaction {\nprivate static class MatchedIndex {}')) + with self.assertRaisesRegex(check.CheckFailure, 'Retired shared implementation'): + check.check_sources(self.root, retired) + + def test_retired_index_bytecode_including_children_is_rejected(self): + retired = check.retired_classes() + path = self.root / 'core.jar' + transaction = 'org/apache/hugegraph/backend/tx/GraphIndexTransaction' + allowed = [transaction + suffix + '.class' for suffix in + ('', '$MatchedIndexIterator', '$Other$MatchedIndex')] + path.write_bytes(self.jar('hugegraph-core', allowed)) + check.scan_jar(path, str(path), {}, set(), retired, 'server') + shared = self.root / 'struct.jar' + shared.write_bytes(self.jar('hugegraph-struct', ['org/apache/hugegraph/structure/Index.class', + 'org/apache/hugegraph/query/MatchedIndex.class'])) + check.scan_jar(shared, str(shared), {}, set(), retired, 'server') + for name in ('org/apache/hugegraph/structure/HugeIndex', + 'org/apache/hugegraph/structure/HugeIndex$IdWithExpiredTime', + transaction + '$MatchedIndex', transaction + '$MatchedIndex$Child'): + with self.subTest(name=name): + path.write_bytes(self.jar('hugegraph-core', allowed + [name + '.class'])) + with self.assertRaisesRegex(check.CheckFailure, 'Retired shared class shipped'): + check.scan_jar(path, str(path), {}, set(), retired, 'server') + + def test_rpc_interfaces_owned_by_common_not_core_or_rpc_implementation(self): + self.sources() + retired = check.retired_classes() + for name in ('RpcServiceConfig4Client', 'RpcServiceConfig4Server'): + relative = 'src/main/java/org/apache/hugegraph/rpc/' + name + '.java' + source = f'package org.apache.hugegraph.rpc;\npublic interface {name} {{}}\n' + common = self.root / 'hugegraph-commons/hugegraph-common' / relative + common.parent.mkdir(parents=True, exist_ok=True) + common.write_text(source) + self.assertIn('org.apache.hugegraph.rpc.' + name, retired) + check.check_sources(self.root, retired) + for module, message in ((check.SOURCE_MODULES[0], 'Retired shared implementation'), + ('hugegraph-commons/hugegraph-rpc', 'Duplicate source FQCN')): + with self.subTest(name=name, module=module): + duplicate = self.root / module / relative + duplicate.parent.mkdir(parents=True, exist_ok=True) + duplicate.write_text(source) + with self.assertRaisesRegex(check.CheckFailure, message): + check.check_sources(self.root, retired) + duplicate.unlink() + + def test_all_source_gremlin_configs_resolve_current_shared_class_names(self): + current = 'org.apache.hugegraph.id.IdGenerator' + directions = 'org.apache.hugegraph.type.define.Directions' + for relative in check.SOURCE_IMPORT_CONFIGS: + path = self.root / relative + path.parent.mkdir(parents=True) + path.write_text(f'classImports: [{current}, {directions}, java.lang.Math]\n') + check.check_source_imports(self.root, {current, directions}) + path = self.root / check.SOURCE_IMPORT_CONFIGS[-1] + path.write_text('classImports: [org.apache.hugegraph.backend.id.IdGenerator]\n') + with self.assertRaisesRegex(check.CheckFailure, 'class is unavailable'): + check.check_source_imports(self.root, {current, directions}) + path.unlink() + with self.assertRaisesRegex(check.CheckFailure, 'Missing Gremlin import configuration'): + check.check_source_imports(self.root, {current, directions}) + + def test_gremlin_import_reader_flow_and_block_lists(self): + path = self.root / 'gremlin.yaml' + path.write_text('classImports: [\n "example.One", # first import\n\'example.Two\', java.lang.Math\n]\n') + self.assertEqual(check.class_imports(path), ['example.One', 'example.Two', 'java.lang.Math']) + path.write_text('plugins:\n classImports:\n - "example.One"\n - \'example.Two\'\n' + ' methodImports: [example.One#*]\n') + self.assertEqual(check.class_imports(path), ['example.One', 'example.Two']) + for value in ('classImports: *alias\n', 'classImports: [example.One\n', + 'classImports: [example.*]\n', 'classImports: []\n'): + with self.subTest(value=value): + path.write_text(value) + with self.assertRaises(check.CheckFailure): + check.class_imports(path) + + def test_packaged_gremlin_imports_resolve_shared_and_external_classes(self): + path = self.distribution() + (path / 'lib/hugegraph-struct.jar').write_bytes(self.jar('hugegraph-struct', [ + 'org/apache/hugegraph/id/IdGenerator.class', 'org/apache/hugegraph/type/define/Directions.class' + ])) + (path / 'lib/external.jar').write_bytes(self.jar('external', entries={ + 'BOOT-INF/lib/inner.jar': self.jar('external-inner', ['example/External.class']) + })) + config = path / 'conf/gremlin-server.yaml' + config.write_text('classImports: [org.apache.hugegraph.id.IdGenerator,\n' + 'org.apache.hugegraph.type.define.Directions, example.External, java.lang.Math]\n') + check.check_distribution(path, 'server', check.retired_classes()) + config.write_text('classImports: [org.apache.hugegraph.backend.id.IdGenerator]\n') + with self.assertRaisesRegex(check.CheckFailure, 'class is unavailable'): + check.check_distribution(path, 'server', check.retired_classes()) + config.unlink() + with self.assertRaisesRegex(check.CheckFailure, 'Missing Gremlin import configuration'): + check.check_distribution(path, 'server', check.retired_classes()) + + def test_forbidden_dependencies_are_matched_by_exact_group(self): + for module in ('hugegraph-struct', 'hugegraph-commons/hugegraph-common', + 'hugegraph-commons/hugegraph-rpc', 'hugegraph-pd/hg-pd-service', + 'hugegraph-store/hg-store-core'): + artifact = module.rsplit('/', 1)[-1] + with self.subTest(module=module): + tree = self.tree(artifact, '\\- external:hugegraph-core:jar:1.0:compile\n') + check.check_tree(tree, module) + tree = self.tree(artifact, f'\\- {check.GROUP}:hugegraph-core:jar:1.8.0:compile\n') + with self.assertRaisesRegex(check.CheckFailure, 'Forbidden resolved dependency'): + check.check_tree(tree, module) + + def test_struct_and_rpc_framework_dependency_boundaries(self): + module = 'hugegraph-commons/hugegraph-rpc' + self.assertIn(module, check.DEPENDENCY_MODULES) + targets = [('hugegraph-struct', 'hugegraph-rpc')] + targets.extend((module, name) for name in ('hugegraph-core', 'hugegraph-struct', 'hg-pd-client', + 'hg-store-common', 'hugegraph-pd', 'hugegraph-store')) + for caller, dependency in targets: + artifact = caller.rsplit('/', 1)[-1] + for prefix in ('', '+- external:parent:jar:1.0:compile\n| '): + with self.subTest(caller=caller, dependency=dependency, transitive=bool(prefix)): + tree = self.tree(artifact, prefix + f'\\- {check.GROUP}:{dependency}:jar:1.8.0:compile\n') + with self.assertRaisesRegex(check.CheckFailure, 'Forbidden resolved dependency'): + check.check_tree(tree, caller) + check.check_tree(self.tree('hugegraph-rpc', f'\\- {check.GROUP}:hugegraph-common:jar:1.8.0:compile\n'), module) + + def test_stale_project_versions_in_direct_and_nested_distributions_fail(self): + for kind in ('server', 'pd', 'store'): + with self.subTest(kind=kind): + path = self.distribution(kind, nested=kind != 'server') + check.check_distribution(path, kind, set(), expected_revision='1.8.0') + extra = path / 'lib/extra.jar' + stale = self.jar('stale-helper', ['org/apache/hugegraph/Stale.class'], version='1.7.0') + extra.write_bytes(stale) + with self.assertRaisesRegex(check.CheckFailure, 'Stale shipped artifact'): + check.check_distribution(path, kind, set(), expected_revision='1.8.0') + extra.write_bytes(self.jar('boot-helper', entries={'BOOT-INF/lib/stale.jar': stale})) + with self.assertRaisesRegex(check.CheckFailure, 'Stale shipped artifact'): + check.check_distribution(path, kind, set(), expected_revision='1.8.0') + extra.write_bytes(self.jar('hugegraph-core', ['example/External.class'], + group='external', version='9.0')) + check.check_distribution(path, kind, set(), expected_revision='1.8.0') + + def test_retired_sources_cannot_return_in_server_api_or_backends(self): + self.sources() + retired = check.retired_classes() + # Canonical owners preserve their original FQCNs even though those + # implementations were removed from Server; their imports/aliases stay legal. + for module, package, name in (('hugegraph-struct', 'type', 'HugeType'), + ('hugegraph-commons/hugegraph-common', 'auth', 'TokenGenerator')): + path = self.root / module / 'src/main/java/org/apache/hugegraph' / package / (name + '.java') + path.parent.mkdir(parents=True) + path.write_text(f'package org.apache.hugegraph.{package};\npublic class {name} {{}}\n') + check.check_sources(self.root, retired) + for module in ('hugegraph-api', 'hugegraph-hstore'): + self.declare_server_module(module) + path = (self.root / 'hugegraph-server' / module / + 'src/main/java/org/apache/hugegraph/backend/id/Id.java') + path.parent.mkdir(parents=True) + path.write_text('package org.apache.hugegraph.backend.id;\npublic interface Id {}\n') + with self.subTest(module=module), self.assertRaisesRegex(check.CheckFailure, + 'Retired shared implementation'): + check.check_sources(self.root, retired) + path.unlink() + nested = (self.root / 'hugegraph-server' / module / + 'src/main/java/org/apache/hugegraph/backend/store/BackendEntry.java') + nested.parent.mkdir(parents=True) + nested.write_text('package org.apache.hugegraph.backend.store;\n' + 'interface BackendEntry { class BackendColumn {} }\n') + with self.assertRaisesRegex(check.CheckFailure, 'Retired shared implementation'): + check.check_sources(self.root, retired) + nested.write_text('package org.apache.hugegraph.backend.store;\n' + 'interface BackendEntry { String alias = "class BackendColumn {}"; }\n') + check.check_sources(self.root, retired) + nested.unlink() + self.declare_server_module('hugegraph-test') + fixture = (self.root / 'hugegraph-server/hugegraph-test/' + 'src/main/java/org/apache/hugegraph/backend/id/Id.java') + fixture.parent.mkdir(parents=True) + fixture.write_text('package org.apache.hugegraph.backend.id;\ninterface Id {}\n') + check.check_sources(self.root, retired) + + def test_retired_bytecode_cannot_return_in_any_server_artifact(self): + retired = check.retired_classes() + jar = self.root / 'owner.jar' + for artifact in check.SERVER_ARTIFACTS: + for name in ('org/apache/hugegraph/backend/id/Id.class', + 'org/apache/hugegraph/backend/store/BackendEntry$BackendColumn.class'): + with self.subTest(artifact=artifact, name=name): + jar.write_bytes(self.jar(artifact, [name])) + with self.assertRaisesRegex(check.CheckFailure, 'Retired shared class shipped'): + check.scan_jar(jar, str(jar), {}, set(), retired, 'server') + for artifact, name in (('hugegraph-struct', 'org/apache/hugegraph/type/HugeType.class'), + ('hugegraph-common', 'org/apache/hugegraph/auth/TokenGenerator.class'), + ('hugegraph-test', 'org/apache/hugegraph/backend/id/Id.class')): + jar.write_bytes(self.jar(artifact, [name])) + check.scan_jar(jar, str(jar), {}, set(), retired, 'server') + + def test_new_server_module_artifacts_are_included_in_retirement_policy(self): + self.declare_server_module('new-backend') + ids = check.server_artifact_ids(self.root) + self.assertIn('new-backend', ids) + jar = self.root / 'new.jar' + jar.write_bytes(self.jar('new-backend', ['org/apache/hugegraph/backend/id/Id.class'])) + with self.assertRaisesRegex(check.CheckFailure, 'Retired shared class shipped'): + check.scan_jar(jar, str(jar), {}, set(), check.retired_classes(), 'server', server_artifacts=ids) + + def test_nested_profile_module_sources_and_shipped_artifacts_are_checked(self): + self.sources() + aggregator = self.declare_server_module('backend') + aggregator.write_text('' + 'backend-parentfuture-platform' + 'new-backend') + module = aggregator.parent / 'new-backend' + module.mkdir() + (module / 'pom.xml').write_text('' + 'future-server-backend') + identities = check.server_artifact_ids(self.root) + self.assertIn('future-server-backend', identities) + retired = check.retired_classes() + for kind in ('java', 'dev'): + path = module / 'src/main' / kind / 'org/apache/hugegraph/backend/id/Id.java' + path.parent.mkdir(parents=True) + path.write_text('package org.apache.hugegraph.backend.id;\ninterface Id {}\n') + with self.subTest(kind=kind), self.assertRaisesRegex(check.CheckFailure, + 'Retired shared implementation'): + check.check_sources(self.root, retired) + path.unlink() + alias = module / 'src/main/java/org/apache/hugegraph/backend/NewBackend.java' + alias.write_text('package org.apache.hugegraph.backend;\n' + 'class NewBackend { String legacy = "org.apache.hugegraph.backend.id.Id"; }\n') + check.check_sources(self.root, retired) + jar = self.root / 'nested-backend.jar' + data = self.jar('future-server-backend', ['org/apache/hugegraph/backend/id/Id.class']) + for value in (data, self.jar('boot-wrapper', entries={'BOOT-INF/lib/backend.jar': data})): + jar.write_bytes(value) + with self.assertRaisesRegex(check.CheckFailure, 'Retired shared class shipped'): + check.scan_jar(jar, str(jar), {}, set(), retired, 'server', server_artifacts=identities) + + def test_declared_reactor_failures_are_closed(self): + self.sources() + aggregator = self.declare_server_module('backend') + cases = (('missing-child', 'Missing declared Server POM'), + ('../', 'Cyclic Server module declaration'), + ('../../outside-server', 'escapes its reactor'), + ('${unknown.module}', 'nonliteral Server module declaration'), + ('', 'Empty or nonliteral Server module declaration')) + for value, message in cases: + with self.subTest(module=value): + aggregator.write_text('backend-parent' + '' + value + '') + with self.assertRaisesRegex(check.CheckFailure, message): + check.server_module_inventory(self.root) + aggregator.write_text('backend-parent') + with self.assertRaisesRegex(check.CheckFailure, 'Invalid Server module POM'): + check.server_module_inventory(self.root) + aggregator.unlink() + with self.assertRaisesRegex(check.CheckFailure, 'Missing declared Server POM'): + check.server_module_inventory(self.root) + + def test_reactor_inventory_ignores_unlisted_copied_and_target_modules(self): + self.sources() + for relative in ('target/copied-backend', 'apache-hugegraph-server-1.8.0'): + directory = self.root / 'hugegraph-server' / relative + source = directory / 'src/main/dev/org/apache/hugegraph/backend/id/Id.java' + source.parent.mkdir(parents=True) + source.write_text('package org.apache.hugegraph.backend.id;\ninterface Id {}\n') + (directory / 'pom.xml').write_text('unlisted-copy') + check.check_sources(self.root, check.retired_classes()) + self.assertNotIn('unlisted-copy', check.server_artifact_ids(self.root)) + + def test_profile_redeclarations_deduplicate_and_test_subtree_is_excluded(self): + self.sources() + test = self.declare_server_module('hugegraph-test') + test.write_text('hugegraph-test' + 'fixtures') + child = test.parent / 'fixtures' + child.mkdir() + (child / 'pom.xml').write_text('test-fixtures') + path = child / 'src/main/java/org/apache/hugegraph/backend/id/Id.java' + path.parent.mkdir(parents=True) + path.write_text('package org.apache.hugegraph.backend.id;\ninterface Id {}\n') + root_pom = self.root / 'hugegraph-server/pom.xml' + project = ET.parse(root_pom) + namespace = '{http://maven.apache.org/POM/4.0.0}' + profiles = ET.SubElement(project.getroot(), namespace + 'profiles') + profile = ET.SubElement(profiles, namespace + 'profile') + modules = ET.SubElement(profile, namespace + 'modules') + ET.SubElement(modules, namespace + 'module').text = './hugegraph-core' + project.write(root_pom, encoding='unicode') + check.check_sources(self.root, check.retired_classes()) + identities = check.server_artifact_ids(self.root) + self.assertEqual(identities, {'hugegraph-server', 'hugegraph-core'}) + + +if __name__ == '__main__': + unittest.main() diff --git a/pom.xml b/pom.xml index 4aac2b9515..9c0b36e692 100644 --- a/pom.xml +++ b/pom.xml @@ -338,6 +338,32 @@ + + + org.codehaus.mojo + flatten-maven-plugin + 1.3.0 + + true + resolveCiFriendliesOnly + + + + flatten + process-resources + + flatten + + + + flatten.clean + clean + + clean + + + + org.apache.maven.plugins maven-enforcer-plugin