@Override public Observable<String> getEdgeTypesToTarget( final SearchEdgeType search ) { final Observable<String> edgeTypes = Observable.create( new ObservableIterator<String>( "getEdgeTypesToTarget" ) { @Override protected Iterator<String> getIterator() { return edgeMetadataSerialization.getEdgeTypesToTarget( scope, search ); } } ); return ObservableTimer.time( edgeTypes, getEdgeTypesToTargetTimer ); }
/** * Time the obserable with the specified timer */ public static <T> Observable<T> time( final Observable<T> observable, final Timer timer ) { final ObservableTimer proxy = new ObservableTimer( timer ); //attach to the observable return observable.doOnSubscribe( () -> proxy.start() ).doOnCompleted( () -> proxy.stop() ); } }
@Override public Observable<String> getEdgeTypesFromSource( final SearchEdgeType search ) { final Observable<String> edgeTypes = Observable.create( new ObservableIterator<String>( "getEdgeTypesFromSource" ) { @Override protected Iterator<String> getIterator() { return edgeMetadataSerialization.getEdgeTypesFromSource( scope, search ); } } ); return ObservableTimer.time( edgeTypes, getEdgeTypesFromSourceTimer ); }
@Override public Observable<String> getIdTypesFromSource( final SearchIdType search ) { final Observable<String> edgeTypes = Observable.create( new ObservableIterator<String>( "getIdTypesFromSource" ) { @Override protected Iterator<String> getIterator() { return edgeMetadataSerialization.getIdTypesFromSource( scope, search ); } } ); return ObservableTimer.time( edgeTypes, getIdTypesFromSourceTimer ); }
@Override public Observable<String> getIdTypesToTarget( final SearchIdType search ) { final Observable<String> edgeTypes = Observable.create( new ObservableIterator<String>( "getIdTypesToTarget" ) { @Override protected Iterator<String> getIterator() { return edgeMetadataSerialization.getIdTypesToTarget( scope, search ); } } ); return ObservableTimer.time( edgeTypes, getIdTypesToTargetTimer ); }
@Override public Observable<VersionSet> getLatestVersion( final Collection<Id> entityIds ) { final Observable<VersionSet> observable = Observable.create( new Observable.OnSubscribe<VersionSet>() { @Override public void call( final Subscriber<? super VersionSet> subscriber ) { try { final VersionSet logEntries = mvccLogEntrySerializationStrategy .load( applicationScope, entityIds, UUIDGenerator.newTimeUUID() ); subscriber.onNext( logEntries ); subscriber.onCompleted(); } catch ( Exception e ) { subscriber.onError( e ); } } } ); return ObservableTimer.time( observable, getLatestTimer ); }
@Override public Observable<EntitySet> load( final Collection<Id> entityIds ) { Preconditions.checkNotNull( entityIds, "entityIds cannot be null" ); final Observable<EntitySet> entitySetObservable = Observable.create( new Observable.OnSubscribe<EntitySet>() { @Override public void call( final Subscriber<? super EntitySet> subscriber ) { try { final EntitySet results = entitySerializationStrategy.load( applicationScope, entityIds, UUIDGenerator.newTimeUUID() ); subscriber.onNext( results ); subscriber.onCompleted(); } catch ( Exception e ) { subscriber.onError( e ); } } } ); return ObservableTimer.time( entitySetObservable, loadTimer ); }
@Override public Observable<Id> markNode( final Id node, final long timestamp ) { final Observable<Id> idObservable = Observable.just( node ).map( id -> { //mark the node as deleted final MutationBatch nodeMutation = nodeSerialization.mark( scope, id, timestamp ); if (logger.isTraceEnabled()) { logger.trace("Marking node {} as deleted to node mark", node); } try { nodeMutation.execute(); } catch ( ConnectionException e ) { throw new RuntimeException( "Unable to execute mutation", e ); } return id; } ); return ObservableTimer.time( idObservable, markNodeTimer ); }
@Override public Observable<MarkedEdge> compactNode( final Id inputNode ) { final UUID startTime = UUIDGenerator.newTimeUUID(); final Observable<MarkedEdge> nodeObservable = Observable.just( inputNode ) .map( node -> nodeSerialization.getMaxVersion( scope, node ) ) //.doOnNext(maxTimestamp -> logger.info("compactNode maxTimestamp={}", maxTimestamp.toString())) .takeWhile(maxTimestamp -> maxTimestamp.isPresent() ) //map our delete listener .flatMap( timestamp -> nodeDeleteListener.receive( scope, inputNode, startTime ) ); return ObservableTimer.time( nodeObservable, this.deleteNodeTimer ); }
@Override public Observable<Id> getIdField( final String type, final Field field ) { final List<Field> fields = Collections.singletonList( field ); final Observable<Id> idObservable = Observable.from( fields ).map( field1 -> { final UniqueValueSet set = uniqueValueSerializationStrategy.load( applicationScope, type, fields ); final UniqueValue value = set.getValue( field1.getName() ); return value == null ? null : value.getEntityId(); } ); return ObservableTimer.time( idObservable, fieldIdTimer ); }
@Override public Observable<Id> mark(final Id entityId, String region) { Preconditions.checkNotNull( entityId, "Entity id is required in this stage" ); Preconditions.checkNotNull( entityId.getUuid(), "Entity id is required in this stage" ); Preconditions.checkNotNull( entityId.getType(), "Entity type is required in this stage" ); Observable<Id> o = Observable.just( new CollectionIoEvent<>( applicationScope, entityId, region ) ) .map( markStart ).doOnNext( markCommit ).compose( uniqueCleanup ).map( entityEvent -> entityEvent.getEvent().getId() ); return ObservableTimer.time( o, deleteTimer ); }
@Override public Observable<Entity> load( final Id entityId ) { Preconditions.checkNotNull( entityId, "Entity id required in the load stage" ); Preconditions.checkNotNull( entityId.getUuid(), "Entity id uuid required in load stage" ); Preconditions.checkNotNull( entityId.getType(), "Entity id type required in load stage" ); final Observable<Entity> entityObservable = load( Collections.singleton( entityId ) ).flatMap( entitySet -> { final MvccEntity entity = entitySet.getEntity( entityId ); if ( entity == null || !entity.getEntity().isPresent() ) { return Observable.empty(); } return Observable.just( entity.getEntity().get() ); } ); return ObservableTimer.time( entityObservable, loadTimer ); }
@Override public Observable<MarkedEdge> markEdge( final Edge edge ) { GraphValidation.validateEdge( edge ); final MarkedEdge markedEdge = new SimpleMarkedEdge( edge, true ); final Observable<MarkedEdge> observable = Observable.just( markedEdge ).map( edge1 -> { final UUID timestamp = UUIDGenerator.newTimeUUID(); final MutationBatch edgeMutation = storageEdgeSerialization.writeEdge( scope, edge1, timestamp ); if (logger.isTraceEnabled()) { logger.trace("Marking edge {} as deleted to commit log", edge1); } try { edgeMutation.execute(); } catch ( ConnectionException e ) { throw new RuntimeException( "Unable to execute mutation", e ); } return edge1; } ); return ObservableTimer.time( observable, markEdgeTimer ); }
@Override public Observable<Edge> deleteEdge( final Edge edge ) { GraphValidation.validateEdge( edge ); final UUID startTimestamp = UUIDGenerator.newTimeUUID(); final Observable<Edge> observable = Observable.create( new ObservableIterator<MarkedEdge>( "read edge versions" ) { @Override protected Iterator<MarkedEdge> getIterator() { return storageEdgeSerialization.getEdgeVersions( scope, new SimpleSearchByEdge( edge.getSourceNode(), edge.getType(), edge.getTargetNode(), Long.MAX_VALUE, SearchByEdgeType.Order.DESCENDING, Optional.absent() ) ); } } ).filter( markedEdge -> markedEdge.isDeleted() ).flatMap( marked -> //fire our delete listener and wait for the results edgeDeleteListener.receive( scope, marked, startTimestamp ).doOnNext( //log them count -> logger.trace( "removed {} types for edge {} ", count, edge ) ) //return the marked edge .map( count -> marked ) ); return ObservableTimer.time( observable, deleteEdgeTimer ); }
@Override public Observable<Entity> write(final Entity entity, String region) { //do our input validation Preconditions.checkNotNull( entity, "Entity is required in the new stage of the mvcc write" ); final Id entityId = entity.getId(); ValidationUtils.verifyIdentity( entityId ); // create our observable and start the write final CollectionIoEvent<Entity> writeData = new CollectionIoEvent<Entity>( applicationScope, entity, region ); Observable<CollectionIoEvent<MvccEntity>> observable = stageRunner( writeData, writeStart ); final Observable<Entity> write = observable.map( writeCommit ).map(ioEvent -> { // fire this in the background so we don't block writes Observable.just( ioEvent ).compose( uniqueCleanup ) .subscribeOn( rxTaskScheduler.getAsyncIOScheduler() ).subscribe(); return ioEvent; }) // now extract the ioEvent we need to return and update the version .map( ioEvent -> ioEvent.getEvent().getEntity().get() ); return ObservableTimer.time( write, writeTimer ); }
@Override public Observable<MarkedEdge> loadEdgesToTarget( final SearchByEdgeType search ) { final Observable<MarkedEdge> edges = Observable.create( new ObservableIterator<MarkedEdge>( "loadEdgesToTarget" ) { @Override protected Iterator<MarkedEdge> getIterator() { return storageEdgeSerialization.getEdgesToTarget( scope, search ); } } ).buffer( graphFig.getScanPageSize() ) .compose( new EdgeBufferFilter( search.filterMarked() ) ); return ObservableTimer.time( edges, loadEdgesToTargetTimer ); }
@Override public Observable<MarkedEdge> loadEdgesFromSourceByType( final SearchByIdType search ) { final Observable<MarkedEdge> edges = Observable.create( new ObservableIterator<MarkedEdge>( "loadEdgesFromSourceByType" ) { @Override protected Iterator<MarkedEdge> getIterator() { return storageEdgeSerialization.getEdgesFromSourceByTargetType( scope, search ); } } ).buffer( graphFig.getScanPageSize() ) .compose( new EdgeBufferFilter( search.filterMarked() ) ); return ObservableTimer.time( edges, loadEdgesFromSourceByTypeTimer ); }
@Override public Observable<MarkedEdge> loadEdgeVersions( final SearchByEdge searchByEdge ) { final Observable<MarkedEdge> edges = Observable.create( new ObservableIterator<MarkedEdge>( "getEdgeTypesFromSource" ) { @Override protected Iterator<MarkedEdge> getIterator() { return storageEdgeSerialization.getEdgeVersions( scope, searchByEdge ); } } ).buffer( graphFig.getScanPageSize() ) .compose( new EdgeBufferFilter( searchByEdge.filterMarked() ) ); return ObservableTimer.time( edges, loadEdgesVersionsTimer ); }
}, rxSchedulerFig.getImportConcurrency()); ObservableTimer.time(tuplesObservable, entitiesParallelGetTimer).toBlocking().lastOrDefault(null);
@Override public Observable<MarkedEdge> loadEdgesToTargetByType( final SearchByIdType search ) { final Observable<MarkedEdge> edges = Observable.create( new ObservableIterator<MarkedEdge>( "loadEdgesToTargetByType" ) { @Override protected Iterator<MarkedEdge> getIterator() { return storageEdgeSerialization.getEdgesToTargetBySourceType( scope, search ); } } ).buffer( graphFig.getScanPageSize() ) .compose( new EdgeBufferFilter( search.filterMarked() ) ); return ObservableTimer.time( edges, loadEdgesToTargetByTypeTimer ); }