+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="output" path="bin"/>
-</classpath>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>org.eclipse.tracecompass.statesystem.core.tests</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.ManifestBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.SchemaBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.pde.PluginNature</nature>
- <nature>org.eclipse.jdt.core.javanature</nature>
- <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
- </natures>
-</projectDescription>
+++ /dev/null
-eclipse.preferences.version=1
-encoding/<project>=UTF-8
+++ /dev/null
-eclipse.preferences.version=1
-line.separator=\n
+++ /dev/null
-eclipse.preferences.version=1
-org.eclipse.jdt.core.codeComplete.argumentPrefixes=
-org.eclipse.jdt.core.codeComplete.argumentSuffixes=
-org.eclipse.jdt.core.codeComplete.fieldPrefixes=f
-org.eclipse.jdt.core.codeComplete.fieldSuffixes=
-org.eclipse.jdt.core.codeComplete.localPrefixes=
-org.eclipse.jdt.core.codeComplete.localSuffixes=
-org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
-org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
-org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
-org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
-org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=enabled
-org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
-org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
-org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
-org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
-org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.7
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.doc.comment.support=enabled
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=error
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=error
-org.eclipse.jdt.core.compiler.problem.deadCode=error
-org.eclipse.jdt.core.compiler.problem.deprecation=error
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=error
-org.eclipse.jdt.core.compiler.problem.emptyStatement=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=error
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=error
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=error
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=error
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=error
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error
-org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=error
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=error
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=error
-org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
-org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
-org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
-org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
-org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=error
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
-org.eclipse.jdt.core.compiler.problem.missingDefaultCase=error
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=error
-org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=enabled
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=error
-org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning
-org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
-org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=error
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=error
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
-org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=warning
-org.eclipse.jdt.core.compiler.problem.nullReference=error
-org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=error
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=error
-org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=error
-org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=error
-org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=error
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=error
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
-org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=enabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=error
-org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=error
-org.eclipse.jdt.core.compiler.problem.unclosedCloseable=error
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=error
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=error
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=error
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=disabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=disabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=error
-org.eclipse.jdt.core.compiler.problem.unusedLabel=error
-org.eclipse.jdt.core.compiler.problem.unusedLocal=error
-org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
-org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=error
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error
-org.eclipse.jdt.core.compiler.source=1.7
-org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
-org.eclipse.jdt.core.formatter.alignment_for_assignment=0
-org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
-org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
-org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
-org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
-org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
-org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
-org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
-org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
-org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=0
-org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
-org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
-org.eclipse.jdt.core.formatter.blank_lines_after_package=1
-org.eclipse.jdt.core.formatter.blank_lines_before_field=0
-org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
-org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
-org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
-org.eclipse.jdt.core.formatter.blank_lines_before_method=1
-org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
-org.eclipse.jdt.core.formatter.blank_lines_before_package=0
-org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
-org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
-org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
-org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
-org.eclipse.jdt.core.formatter.comment.format_block_comments=true
-org.eclipse.jdt.core.formatter.comment.format_header=false
-org.eclipse.jdt.core.formatter.comment.format_html=true
-org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
-org.eclipse.jdt.core.formatter.comment.format_line_comments=true
-org.eclipse.jdt.core.formatter.comment.format_source_code=true
-org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
-org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
-org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
-org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
-org.eclipse.jdt.core.formatter.comment.line_length=80
-org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
-org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
-org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
-org.eclipse.jdt.core.formatter.compact_else_if=true
-org.eclipse.jdt.core.formatter.continuation_indentation=2
-org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
-org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
-org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
-org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
-org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
-org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
-org.eclipse.jdt.core.formatter.indent_empty_lines=false
-org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
-org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
-org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
-org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
-org.eclipse.jdt.core.formatter.indentation.size=4
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
-org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
-org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
-org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
-org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
-org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
-org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.join_lines_in_comments=true
-org.eclipse.jdt.core.formatter.join_wrapped_lines=false
-org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
-org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
-org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
-org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
-org.eclipse.jdt.core.formatter.lineSplit=250
-org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
-org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
-org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
-org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
-org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
-org.eclipse.jdt.core.formatter.tabulation.char=space
-org.eclipse.jdt.core.formatter.tabulation.size=4
-org.eclipse.jdt.core.formatter.use_on_off_tags=false
-org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
-org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
-org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
-org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
+++ /dev/null
-eclipse.preferences.version=1
-editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_profile=_tmf-style
-formatter_settings_version=12
-org.eclipse.jdt.ui.exception.name=e
-org.eclipse.jdt.ui.gettersetter.use.is=true
-org.eclipse.jdt.ui.keywordthis=false
-org.eclipse.jdt.ui.overrideannotation=true
-sp_cleanup.add_default_serial_version_id=true
-sp_cleanup.add_generated_serial_version_id=false
-sp_cleanup.add_missing_annotations=false
-sp_cleanup.add_missing_deprecated_annotations=true
-sp_cleanup.add_missing_methods=false
-sp_cleanup.add_missing_nls_tags=false
-sp_cleanup.add_missing_override_annotations=true
-sp_cleanup.add_missing_override_annotations_interface_methods=true
-sp_cleanup.add_serial_version_id=false
-sp_cleanup.always_use_blocks=true
-sp_cleanup.always_use_parentheses_in_expressions=false
-sp_cleanup.always_use_this_for_non_static_field_access=false
-sp_cleanup.always_use_this_for_non_static_method_access=false
-sp_cleanup.convert_to_enhanced_for_loop=false
-sp_cleanup.correct_indentation=false
-sp_cleanup.format_source_code=false
-sp_cleanup.format_source_code_changes_only=false
-sp_cleanup.make_local_variable_final=false
-sp_cleanup.make_parameters_final=false
-sp_cleanup.make_private_fields_final=true
-sp_cleanup.make_type_abstract_if_missing_method=false
-sp_cleanup.make_variable_declarations_final=false
-sp_cleanup.never_use_blocks=false
-sp_cleanup.never_use_parentheses_in_expressions=true
-sp_cleanup.on_save_use_additional_actions=true
-sp_cleanup.organize_imports=false
-sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
-sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
-sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
-sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
-sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
-sp_cleanup.remove_private_constructors=true
-sp_cleanup.remove_trailing_whitespaces=true
-sp_cleanup.remove_trailing_whitespaces_all=true
-sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
-sp_cleanup.remove_unnecessary_casts=false
-sp_cleanup.remove_unnecessary_nls_tags=false
-sp_cleanup.remove_unused_imports=false
-sp_cleanup.remove_unused_local_variables=false
-sp_cleanup.remove_unused_private_fields=true
-sp_cleanup.remove_unused_private_members=false
-sp_cleanup.remove_unused_private_methods=true
-sp_cleanup.remove_unused_private_types=true
-sp_cleanup.sort_members=false
-sp_cleanup.sort_members_all=false
-sp_cleanup.use_blocks=true
-sp_cleanup.use_blocks_only_for_return_and_throw=false
-sp_cleanup.use_parentheses_in_expressions=false
-sp_cleanup.use_this_for_non_static_field_access=false
-sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
-sp_cleanup.use_this_for_non_static_method_access=false
-sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+++ /dev/null
-ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error
-ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
-ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error
-ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Error
-ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
-API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error
-API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error
-API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error
-API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error
-API_USE_SCAN_FIELD_SEVERITY=Error
-API_USE_SCAN_METHOD_SEVERITY=Error
-API_USE_SCAN_TYPE_SEVERITY=Error
-CLASS_ELEMENT_TYPE_ADDED_METHOD=Error
-CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
-CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
-CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
-CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
-CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
-CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
-CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
-CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Error
-CLASS_ELEMENT_TYPE_REMOVED_FIELD=Error
-CLASS_ELEMENT_TYPE_REMOVED_METHOD=Error
-CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Error
-CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
-CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
-CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
-CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
-CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
-CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
-ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
-ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
-ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Error
-ENUM_ELEMENT_TYPE_REMOVED_FIELD=Error
-ENUM_ELEMENT_TYPE_REMOVED_METHOD=Error
-ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
-FIELD_ELEMENT_TYPE_ADDED_VALUE=Error
-FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
-FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Error
-FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
-FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
-FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
-FIELD_ELEMENT_TYPE_CHANGED_TYPE=Error
-FIELD_ELEMENT_TYPE_CHANGED_VALUE=Error
-FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Error
-FIELD_ELEMENT_TYPE_REMOVED_VALUE=Error
-ILLEGAL_EXTEND=Warning
-ILLEGAL_IMPLEMENT=Warning
-ILLEGAL_INSTANTIATE=Warning
-ILLEGAL_OVERRIDE=Warning
-ILLEGAL_REFERENCE=Warning
-INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error
-INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error
-INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
-INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Error
-INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
-INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
-INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
-INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Error
-INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error
-INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
-INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
-INVALID_JAVADOC_TAG=Warning
-INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Warning
-LEAK_EXTEND=Warning
-LEAK_FIELD_DECL=Warning
-LEAK_IMPLEMENT=Warning
-LEAK_METHOD_PARAM=Warning
-LEAK_METHOD_RETURN_TYPE=Warning
-METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
-METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
-METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
-METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
-METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
-METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
-METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
-METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
-METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error
-METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
-MISSING_EE_DESCRIPTIONS=Ignore
-TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
-TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
-TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
-TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
-TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
-TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
-UNUSED_PROBLEM_FILTERS=Warning
-automatically_removed_unused_problem_filters=false
-eclipse.preferences.version=1
-incompatible_api_component_version=Error
-incompatible_api_component_version_include_major_without_breaking_change=Disabled
-incompatible_api_component_version_include_minor_without_api_change=Disabled
-invalid_since_tag_version=Error
-malformed_since_tag=Error
-missing_since_tag=Error
-report_api_breakage_when_major_version_incremented=Disabled
-report_resolution_errors_api_component=Warning
+++ /dev/null
-compilers.f.unresolved-features=1
-compilers.f.unresolved-plugins=1
-compilers.incompatible-environment=1
-compilers.p.build=1
-compilers.p.build.bin.includes=1
-compilers.p.build.encodings=2
-compilers.p.build.java.compiler=2
-compilers.p.build.java.compliance=1
-compilers.p.build.missing.output=2
-compilers.p.build.output.library=1
-compilers.p.build.source.library=1
-compilers.p.build.src.includes=1
-compilers.p.deprecated=1
-compilers.p.discouraged-class=1
-compilers.p.internal=1
-compilers.p.missing-packages=2
-compilers.p.missing-version-export-package=2
-compilers.p.missing-version-import-package=2
-compilers.p.missing-version-require-bundle=2
-compilers.p.no-required-att=0
-compilers.p.not-externalized-att=2
-compilers.p.unknown-attribute=1
-compilers.p.unknown-class=1
-compilers.p.unknown-element=1
-compilers.p.unknown-identifier=1
-compilers.p.unknown-resource=1
-compilers.p.unresolved-ex-points=0
-compilers.p.unresolved-import=0
-compilers.s.create-docs=false
-compilers.s.doc-folder=doc
-compilers.s.open-tags=1
-eclipse.preferences.version=1
+++ /dev/null
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: %Bundle-Name
-Bundle-Vendor: %Bundle-Vendor
-Bundle-Version: 1.0.0.qualifier
-Bundle-Localization: plugin
-Bundle-SymbolicName: org.eclipse.tracecompass.statesystem.core.tests;singleton:=true
-Bundle-ActivationPolicy: lazy
-Bundle-RequiredExecutionEnvironment: JavaSE-1.7
-Require-Bundle: org.junit;bundle-version="4.0.0",
- org.eclipse.core.runtime,
- org.eclipse.core.resources,
- org.eclipse.tracecompass.common.core,
- org.eclipse.tracecompass.statesystem.core
-Export-Package: org.eclipse.tracecompass.statesystem.core.tests
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
-<title>About</title>
-</head>
-<body lang="EN-US">
-<h2>About This Content</h2>
-
-<p>June 5, 2006</p>
-<h3>License</h3>
-
-<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
-indicated below, the Content is provided to you under the terms and conditions of the
-Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
-at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
-For purposes of the EPL, "Program" will mean the Content.</p>
-
-<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
-being redistributed by another party ("Redistributor") and different terms and conditions may
-apply to your use of any object code in the Content. Check the Redistributor's license that was
-provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
-indicated below, the terms and conditions of the EPL still apply to any source code in the Content
-and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
-
-</body>
-</html>
\ No newline at end of file
+++ /dev/null
-###############################################################################
-# Copyright (c) 2014, 2015 Ericsson
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-#
-# Contributors:
-# Ericsson - Initial API and implementation
-###############################################################################
-
-source.. = src/
-output.. = bin/
-bin.includes = META-INF/,\
- .,\
- plugin.properties,\
- about.html
-src.includes = about.html
-additional.bundles = org.eclipse.jdt.annotation
-jars.extra.classpath = platform:/plugin/org.eclipse.jdt.annotation
+++ /dev/null
-###############################################################################
-# Copyright (c) 2014 Ericsson
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-#
-# Contributors:
-# Ericsson - Initial API and implementation
-###############################################################################
-
-Bundle-Vendor = Eclipse Trace Compass
-Bundle-Name = Trace Compass State System Core Tests Plug-in
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (C) 2014, Ericsson
-
- All rights reserved. This program and the accompanying materials
- are made available under the terms of the Eclipse Public License v1.0
- which accompanies this distribution, and is available at
- http://www.eclipse.org/legal/epl-v10.html
--->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <artifactId>org.eclipse.tracecompass</artifactId>
- <groupId>org.eclipse.tracecompass</groupId>
- <version>1.0.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>org.eclipse.tracecompass.statesystem.core.tests</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- <packaging>eclipse-test-plugin</packaging>
-
- <name>Trace Compass State System Core Tests Plug-in</name>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.eclipse.tycho</groupId>
- <artifactId>tycho-surefire-plugin</artifactId>
- <version>${tycho-version}</version>
- <configuration>
- <testSuite>org.eclipse.tracecompass.statesystem.core.tests</testSuite>
- <testClass>org.eclipse.tracecompass.statesystem.core.tests.AllTests</testClass>
- <useUIHarness>false</useUIHarness>
- <useUIThread>false</useUIThread>
- <product>org.eclipse.platform.ide</product>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <groupId>org.eclipse.tracecompass</groupId>
-</project>
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2014, 2015 Ericsson
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- * Patrick Tasse - Enable StateSystemUtils tests
- *******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.tests;
-
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-/**
- * Master test suite
- */
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
- StateSystemPushPopTest.class,
- StateSystemUtilsTest.class,
- org.eclipse.tracecompass.statesystem.core.tests.backend.AllTests.class,
- org.eclipse.tracecompass.statesystem.core.tests.statevalue.AllTests.class
-})
-public class AllTests {
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- * Alexandre Montplaisir - Port to JUnit4
- ******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.tests;
-
-import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-
-import org.eclipse.tracecompass.internal.statesystem.core.StateSystem;
-import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
-import org.eclipse.tracecompass.statesystem.core.StateSystemUtils;
-import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
-import org.eclipse.tracecompass.statesystem.core.backend.StateHistoryBackendFactory;
-import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
-import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
-import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
-import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for stack-attributes in the Generic State System (using
- * pushAttribute() and popAttribute())
- *
- * @author Alexandre Montplaisir
- */
-public class StateSystemPushPopTest {
-
- private ITmfStateSystemBuilder ss;
- private int attribute;
-
- private File testHtFile;
-
- private final static String errMsg = "Caught exception: ";
-
- /* State values that will be used */
- //private final static ITmfStateValue nullValue = TmfStateValue.nullValue();
- private final static ITmfStateValue value1 = TmfStateValue.newValueString("A");
- private final static ITmfStateValue value2 = TmfStateValue.newValueInt(10);
- private final static ITmfStateValue value3 = TmfStateValue.nullValue();
- private final static ITmfStateValue value4 = TmfStateValue.newValueString("D");
- private final static ITmfStateValue value5 = TmfStateValue.newValueLong(Long.MAX_VALUE);
-
- /**
- * Initialization. We run the checks for the return values of
- * .popAttribute() in here, since this is only available when we are
- * building the state history.
- *
- * @throws IOException
- * If we can write the file to the temporary directory.
- * @throws TimeRangeException
- * Fails the test
- * @throws AttributeNotFoundException
- * Fails the test
- * @throws StateValueTypeException
- * Fails the test
- */
- @Before
- public void setUp() throws IOException, TimeRangeException,
- AttributeNotFoundException, StateValueTypeException {
- ITmfStateValue value;
- testHtFile = File.createTempFile("test", ".ht");
-
- IStateHistoryBackend backend = StateHistoryBackendFactory.createHistoryTreeBackendNewFile(
- "push-pop-test", checkNotNull(testHtFile), 0, 0, 0);
- ss = new StateSystem(backend, true);
-
- /* Build the thing */
- final int attrib = ss.getQuarkAbsoluteAndAdd("Test", "stack");
-
- ss.pushAttribute( 2, value1, attrib);
- ss.pushAttribute( 4, value2, attrib);
- ss.pushAttribute( 6, value3, attrib);
- ss.pushAttribute( 8, value4, attrib);
- ss.pushAttribute(10, value5, attrib);
-
- value = ss.popAttribute(11, attrib);
- assertEquals(value5, value);
-
- value = ss.popAttribute(12, attrib);
- assertEquals(value4, value);
-
- value = ss.popAttribute(14, attrib);
- assertEquals(value3, value);
-
- value = ss.popAttribute(16, attrib);
- assertEquals(value2, value);
-
- value = ss.popAttribute(17, attrib);
- assertEquals(value1, value);
-
- value = ss.popAttribute(20, attrib);
- assertEquals(null, value); // Stack should already be empty here.
-
- ss.pushAttribute(21, value1, attrib);
- //ss.pushAttribute(22, value1, attrib); //FIXME pushing twice the same value bugs out atm
- ss.pushAttribute(22, value2, attrib);
-
- value = ss.popAttribute(24, attrib);
- //assertEquals(value1, value);
- assertEquals(value2, value);
-
- value = ss.popAttribute(26, attrib);
- assertEquals(value1, value);
-
- value = ss.popAttribute(28, attrib);
- assertEquals(null, value); // Stack should already be empty here.
-
- ss.closeHistory(30);
- attribute = ss.getQuarkAbsolute("Test", "stack");
- }
-
- /**
- * Clean-up after running a test. Delete the .ht file we created.
- */
- @After
- public void tearDown() {
- testHtFile.delete();
- }
-
- /**
- * Test that the value of the stack-attribute at the start and end of the
- * history are correct.
- */
- @Test
- public void testBeginEnd() {
- try {
- ITmfStateInterval interval = ss.querySingleState(0, attribute);
- assertEquals(0, interval.getStartTime());
- assertEquals(1, interval.getEndTime());
- assertTrue(interval.getStateValue().isNull());
-
- interval = ss.querySingleState(29, attribute);
- assertEquals(26, interval.getStartTime());
- assertEquals(30, interval.getEndTime());
- assertTrue(interval.getStateValue().isNull());
-
- } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException e) {
- fail(errMsg + e.toString());
- }
- }
-
- /**
- * Run single queries on the attribute stacks (with .querySingleState()).
- */
- @Test
- public void testSingleQueries() {
- try {
- final int subAttribute1 = ss.getQuarkRelative(attribute, "1");
- final int subAttribute2 = ss.getQuarkRelative(attribute, "2");
-
- /* Test the stack attributes themselves */
- ITmfStateInterval interval = ss.querySingleState(11, attribute);
- assertEquals(4, interval.getStateValue().unboxInt());
-
- interval = ss.querySingleState(24, attribute);
- assertEquals(1, interval.getStateValue().unboxInt());
-
- /* Go retrieve the user values manually */
- interval = ss.querySingleState(10, subAttribute1);
- assertEquals(value1, interval.getStateValue()); //
-
- interval = ss.querySingleState(22, subAttribute2);
- assertEquals(value2, interval.getStateValue());
-
- interval = ss.querySingleState(25, subAttribute2);
- assertTrue(interval.getStateValue().isNull()); // Stack depth is 1 at that point.
-
- } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException e) {
- fail(errMsg + e.toString());
- }
- }
-
- /**
- * Test the .querySingletStackTop() convenience method.
- */
- @Test
- public void testStackTop() {
- final ITmfStateSystemBuilder ss2 = ss;
- assertNotNull(ss2);
-
- try {
- ITmfStateInterval interval = StateSystemUtils.querySingleStackTop(ss2, 10, attribute);
- assertNotNull(interval);
- assertEquals(value5, interval.getStateValue());
-
- interval = StateSystemUtils.querySingleStackTop(ss2, 9, attribute);
- assertNotNull(interval);
- assertEquals(value4, interval.getStateValue());
-
- interval = StateSystemUtils.querySingleStackTop(ss2, 13, attribute);
- assertNotNull(interval);
- assertEquals(value3, interval.getStateValue());
-
- interval = StateSystemUtils.querySingleStackTop(ss2, 16, attribute);
- assertNotNull(interval);
- assertEquals(value1, interval.getStateValue());
-
- interval = StateSystemUtils.querySingleStackTop(ss2, 25, attribute);
- assertNotNull(interval);
- assertEquals(value1, interval.getStateValue());
-
- } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException e) {
- fail(errMsg + e.toString());
- }
- }
-
- /**
- * Test the places where the stack is empty.
- */
- @Test
- public void testEmptyStack() {
- final ITmfStateSystemBuilder ss2 = ss;
- assertNotNull(ss2);
-
- try {
- /* At the start */
- ITmfStateInterval interval = ss.querySingleState(1, attribute);
- assertTrue(interval.getStateValue().isNull());
- interval = StateSystemUtils.querySingleStackTop(ss2, 1, attribute);
- assertEquals(null, interval);
-
- /* Between the two "stacks" in the state history */
- interval = ss.querySingleState(19, attribute);
- assertTrue(interval.getStateValue().isNull());
- interval = StateSystemUtils.querySingleStackTop(ss2, 19, attribute);
- assertEquals(null, interval);
-
- /* At the end */
- interval = ss.querySingleState(27, attribute);
- assertTrue(interval.getStateValue().isNull());
- interval = StateSystemUtils.querySingleStackTop(ss2, 27, attribute);
- assertEquals(null, interval);
-
- } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException e) {
- fail(errMsg + e.toString());
- }
- }
-
- /**
- * Test full-queries (.queryFullState()) on the attribute stacks.
- */
- @Test
- public void testFullQueries() {
- List<ITmfStateInterval> state;
- try {
- final int subAttrib1 = ss.getQuarkRelative(attribute, "1");
- final int subAttrib2 = ss.getQuarkRelative(attribute, "2");
- final int subAttrib3 = ss.getQuarkRelative(attribute, "3");
- final int subAttrib4 = ss.getQuarkRelative(attribute, "4");
-
- /* Stack depth = 5 */
- state = ss.queryFullState(10);
- assertEquals(5, state.get(attribute).getStateValue().unboxInt());
- assertEquals(value1, state.get(subAttrib1).getStateValue());
- assertEquals(value2, state.get(subAttrib2).getStateValue());
- assertEquals(value3, state.get(subAttrib3).getStateValue());
- assertEquals(value4, state.get(subAttrib4).getStateValue());
-
- /* Stack is empty */
- state = ss.queryFullState(18);
- assertTrue(state.get(attribute).getStateValue().isNull());
- assertTrue(state.get(subAttrib1).getStateValue().isNull());
- assertTrue(state.get(subAttrib2).getStateValue().isNull());
- assertTrue(state.get(subAttrib3).getStateValue().isNull());
- assertTrue(state.get(subAttrib4).getStateValue().isNull());
-
- /* Stack depth = 1 */
- state = ss.queryFullState(21);
- assertEquals(1, state.get(attribute).getStateValue().unboxInt());
- assertEquals(value1, state.get(subAttrib1).getStateValue());
- assertTrue(state.get(subAttrib2).getStateValue().isNull());
- assertTrue(state.get(subAttrib3).getStateValue().isNull());
- assertTrue(state.get(subAttrib4).getStateValue().isNull());
-
- } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException e) {
- fail(errMsg + e.toString());
- }
- }
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2014, 2015 École Polytechnique de Montréal
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Geneviève Bastien - Initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.tests;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
-import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
-import org.eclipse.tracecompass.statesystem.core.StateSystemFactory;
-import org.eclipse.tracecompass.statesystem.core.StateSystemUtils;
-import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
-import org.eclipse.tracecompass.statesystem.core.backend.StateHistoryBackendFactory;
-import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
-import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
-import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
-import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Test the {@link StateSystemUtils} class
- *
- * @author Geneviève Bastien
- */
-public class StateSystemUtilsTest {
-
- private static final long START_TIME = 1000L;
- private static final @NonNull String DUMMY_STRING = "test";
-
- private ITmfStateSystemBuilder fStateSystem;
-
- /**
- * Build a small test state system in memory
- */
- @Before
- public void setupStateSystem() {
- try {
- IStateHistoryBackend backend = StateHistoryBackendFactory.createInMemoryBackend(DUMMY_STRING, START_TIME);
- fStateSystem = StateSystemFactory.newStateSystem(backend);
- int quark = fStateSystem.getQuarkAbsoluteAndAdd(DUMMY_STRING);
-
- fStateSystem.modifyAttribute(1200L, TmfStateValue.newValueInt(10), quark);
- fStateSystem.modifyAttribute(1500L, TmfStateValue.newValueInt(20), quark);
- fStateSystem.closeHistory(2000L);
- } catch (StateValueTypeException | AttributeNotFoundException e) {
- fail(e.getMessage());
- }
- }
-
- /**
- * Clean-up
- */
- @After
- public void tearDown() {
- fStateSystem.dispose();
- }
-
- /**
- * Test the {@link StateSystemUtils#queryUntilNonNullValue} method.
- */
- @Test
- public void testQueryUntilNonNullValue() {
- ITmfStateSystem ss = fStateSystem;
- assertNotNull(ss);
-
- int quark;
- try {
- quark = ss.getQuarkAbsolute(DUMMY_STRING);
-
- /* Should return null if requested range is not within range */
- assertNull(StateSystemUtils.queryUntilNonNullValue(ss, quark, 0, 999L));
- assertNull(StateSystemUtils.queryUntilNonNullValue(ss, quark, 2001L, 5000L));
-
- /*
- * Should return null if request within range, but condition is
- * false
- */
- assertNull(StateSystemUtils.queryUntilNonNullValue(ss, quark, 1000L, 1199L));
-
- /*
- * Should return the right interval if an interval is within range,
- * even if the range starts or ends outside state system range
- */
- ITmfStateInterval interval = StateSystemUtils.queryUntilNonNullValue(ss, quark, 1000L, 1300L);
- assertNotNull(interval);
- assertEquals(ITmfStateValue.Type.INTEGER, interval.getStateValue().getType());
- assertEquals(10, interval.getStateValue().unboxInt());
-
- interval = StateSystemUtils.queryUntilNonNullValue(ss, quark, 800L, 2500L);
- assertNotNull(interval);
- assertEquals(ITmfStateValue.Type.INTEGER, interval.getStateValue().getType());
- assertEquals(10, interval.getStateValue().unboxInt());
-
- interval = StateSystemUtils.queryUntilNonNullValue(ss, quark, 1300L, 1800L);
- assertNotNull(interval);
- assertEquals(ITmfStateValue.Type.INTEGER, interval.getStateValue().getType());
- assertEquals(10, interval.getStateValue().unboxInt());
-
- interval = StateSystemUtils.queryUntilNonNullValue(ss, quark, 1500L, 1800L);
- assertNotNull(interval);
- assertEquals(ITmfStateValue.Type.INTEGER, interval.getStateValue().getType());
- assertEquals(20, interval.getStateValue().unboxInt());
-
- interval = StateSystemUtils.queryUntilNonNullValue(ss, quark, 1800L, 2500L);
- assertNotNull(interval);
- assertEquals(ITmfStateValue.Type.INTEGER, interval.getStateValue().getType());
- assertEquals(20, interval.getStateValue().unboxInt());
-
- } catch (AttributeNotFoundException e) {
- fail(e.getMessage());
- }
-
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2013, 2015 Ericsson
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- ******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.tests.backend;
-
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-/**
- * Test suite for org.eclipse.tracecompass.statesystem.core.backend
- */
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
- InMemoryBackendTest.class
-})
-public class AllTests {
-
-}
\ No newline at end of file
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2013, 2015 Ericsson
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Matthew Khouzam - Initial API and implementation
- ******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.tests.backend;
-
-import static org.junit.Assert.*;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
-import org.eclipse.tracecompass.statesystem.core.backend.StateHistoryBackendFactory;
-import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
-import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
-import org.eclipse.tracecompass.statesystem.core.interval.TmfStateInterval;
-import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-/**
- * Test cases for the in-memory backend
- *
- * @author Matthew Khouzam
- */
-public class InMemoryBackendTest {
-
- private static final int NUMBER_OF_ATTRIBUTES = 10;
- private static IStateHistoryBackend fixture;
-
- /**
- * Test setup. make a state system that is moderately large
- */
- @BeforeClass
- public static void init() {
- fixture = StateHistoryBackendFactory.createInMemoryBackend("test-ss", 0);
- for (int attribute = 0; attribute < NUMBER_OF_ATTRIBUTES; attribute++) {
- for (int timeStart = 0; timeStart < 1000; timeStart++) {
- try {
- final int stateEndTime = (timeStart * 100) + 90 + attribute;
- final int stateStartTime = timeStart * 100 + attribute;
- fixture.insertPastState(stateStartTime, stateEndTime, attribute, TmfStateValue.newValueInt(timeStart % 100));
- if (timeStart != 999) {
- fixture.insertPastState(stateEndTime + 1, stateEndTime + 9, attribute, TmfStateValue.nullValue());
- }
- } catch (TimeRangeException e) {
- /* Should not happen here */
- throw new IllegalStateException();
- }
- }
- }
- }
-
- private static void testInterval(ITmfStateInterval interval, int startTime,
- int endTime, int value) {
- assertNotNull(interval);
- assertEquals(startTime, interval.getStartTime());
- assertEquals(endTime, interval.getEndTime());
- try {
- assertEquals(value, interval.getStateValue().unboxInt());
- } catch (StateValueTypeException e) {
- fail(e.getMessage());
- }
- }
-
-
- /**
- * Test at start time
- */
- @Test
- public void testStartTime() {
- assertEquals(0, fixture.getStartTime());
- }
-
- /**
- * Test at end time
- */
- @Test
- public void testEndTime() {
- assertEquals(99999, fixture.getEndTime());
- }
-
- /**
- * Query the state system
- */
- @Test
- public void testDoQuery() {
- List<ITmfStateInterval> interval = new ArrayList<>(NUMBER_OF_ATTRIBUTES);
- for (int i = 0; i < NUMBER_OF_ATTRIBUTES; i++) {
- interval.add(null);
- }
- try {
- fixture.doQuery(interval, 950);
- } catch (TimeRangeException | StateSystemDisposedException e) {
- fail(e.getMessage());
- }
-
- assertEquals(NUMBER_OF_ATTRIBUTES, interval.size());
- testInterval(interval.get(0), 900, 990, 9);
- testInterval(interval.get(1), 901, 991, 9);
- testInterval(interval.get(2), 902, 992, 9);
- testInterval(interval.get(3), 903, 993, 9);
- testInterval(interval.get(4), 904, 994, 9);
- testInterval(interval.get(5), 905, 995, 9);
- testInterval(interval.get(6), 906, 996, 9);
- testInterval(interval.get(7), 907, 997, 9);
- testInterval(interval.get(8), 908, 998, 9);
- testInterval(interval.get(9), 909, 999, 9);
- }
-
-
- /**
- * Test single attribute then compare it to a full query
- */
- @Test
- public void testQueryAttribute() {
- try {
- ITmfStateInterval interval[] = new TmfStateInterval[10];
- for (int i = 0; i < 10; i++) {
- interval[i] = fixture.doSingularQuery(950, i);
- }
-
- testInterval(interval[0], 900, 990, 9);
- testInterval(interval[1], 901, 991, 9);
- testInterval(interval[2], 902, 992, 9);
- testInterval(interval[3], 903, 993, 9);
- testInterval(interval[4], 904, 994, 9);
- testInterval(interval[5], 905, 995, 9);
- testInterval(interval[6], 906, 996, 9);
- testInterval(interval[7], 907, 997, 9);
- testInterval(interval[8], 908, 998, 9);
- testInterval(interval[9], 909, 999, 9);
-
- List<ITmfStateInterval> intervalQuery = new ArrayList<>(NUMBER_OF_ATTRIBUTES);
- for (int i = 0; i < NUMBER_OF_ATTRIBUTES; i++) {
- intervalQuery.add(null);
- }
-
- fixture.doQuery(intervalQuery, 950);
- ITmfStateInterval ref[] = intervalQuery.toArray(new ITmfStateInterval[0]);
- assertArrayEquals(ref, interval);
-
- } catch (TimeRangeException | AttributeNotFoundException | StateSystemDisposedException e) {
- fail(e.getMessage());
- }
- }
-
- /**
- * Test single attribute that should not exist
- */
- @Test
- public void testQueryAttributeEmpty() {
- try {
- ITmfStateInterval interval = fixture.doSingularQuery(999, 0);
- assertEquals(TmfStateValue.nullValue(), interval.getStateValue());
-
- } catch (TimeRangeException | AttributeNotFoundException | StateSystemDisposedException e) {
- fail(e.getMessage());
- }
- }
-
- /**
- * Test first element in ss
- */
- @Test
- public void testBegin() {
- try {
- ITmfStateInterval interval = fixture.doSingularQuery(0, 0);
- assertEquals(0, interval.getStartTime());
- assertEquals(90, interval.getEndTime());
- assertEquals(0, interval.getStateValue().unboxInt());
-
- } catch (TimeRangeException | AttributeNotFoundException | StateSystemDisposedException e) {
- fail(e.getMessage());
- }
- }
-
- /**
- * Test last element in ss
- */
- @Test
- public void testEnd() {
- try {
- ITmfStateInterval interval = fixture.doSingularQuery(99998, 9);
- testInterval(interval, 99909, 99999, 99);
-
- } catch (TimeRangeException | AttributeNotFoundException | StateSystemDisposedException e) {
- fail(e.getMessage());
- }
- }
-
- /**
- * Test out of range query
- *
- * @throws TimeRangeException
- * Expected
- */
- @Test(expected = TimeRangeException.class)
- public void testOutOfRange_1() throws TimeRangeException {
- try {
- ITmfStateInterval interval = fixture.doSingularQuery(-1, 0);
- assertNull(interval);
-
- } catch (AttributeNotFoundException | StateSystemDisposedException e) {
- fail(e.getMessage());
- }
- }
-
- /**
- * Test out of range query
- *
- * @throws TimeRangeException
- * Expected
- */
- @Test(expected = TimeRangeException.class)
- public void testOutOfRange_2() throws TimeRangeException {
- try {
- ITmfStateInterval interval = fixture.doSingularQuery(100000, 0);
- assertNull(interval);
-
- } catch (AttributeNotFoundException | StateSystemDisposedException e) {
- fail(e.getMessage());
- }
- }
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2014 École Polytechnique de Montréal
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Naser Ezzati - Initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.tests.statevalue;
-
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-/**
- * Test suite for the StateValue package
- */
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
- StateValueCompareToTest.class
-})
-public class AllTests {
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2014 École Polytechnique de Montréal
- *
- * All rights reserved. This program and the accompanying materials are
- * made availabComparisonOperator.LE under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is availabComparisonOperator.LE at
- * http://www.eclipse.org/ComparisonOperator.LEgal/epl-v10.html
- *
- * Contributors:
- * Naser Ezzati - Initial API and implementation
- ******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.tests.statevalue;
-
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
-import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
-import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
-import org.junit.Test;
-
-/**
- * Unit test for the {@link ITmfStateValue#compareTo(ITmfStateValue)} method
- *
- * @author Naser Ezzati
- */
-public class StateValueCompareToTest {
-
- // ------------------------------------------------------------------------
- // Static fields
- // ------------------------------------------------------------------------
-
- /* State values that will be used */
- private static final ITmfStateValue BASE_INT_VALUE = TmfStateValue.newValueInt(10);
- private static final ITmfStateValue BIGGER_INT_VALUE = TmfStateValue.newValueInt(20);
- private static final ITmfStateValue SMALLER_INT_VALUE = TmfStateValue.newValueInt(6);
-
- private static final ITmfStateValue BASE_LONG_VALUE = TmfStateValue.newValueLong(10);
- private static final ITmfStateValue BIGGER_LONG_VALUE = TmfStateValue.newValueLong(20);
- private static final ITmfStateValue SMALLER_LONG_VALUE = TmfStateValue.newValueLong(6);
- private static final ITmfStateValue MIN_LONG_VALUE = TmfStateValue.newValueLong(Long.MIN_VALUE);
- private static final ITmfStateValue MAX_LONG_VALUE = TmfStateValue.newValueLong(Long.MAX_VALUE);
-
- private static final ITmfStateValue BASE_DOUBLE_VALUE = TmfStateValue.newValueDouble(10.00);
- private static final ITmfStateValue BIGGER_DOUBLE_VALUE1 = TmfStateValue.newValueDouble(20.00);
- private static final ITmfStateValue BIGGER_DOUBLE_VALUE2 = TmfStateValue.newValueDouble(10.03);
- private static final ITmfStateValue SMALLER_DOUBLE_VALUE1 = TmfStateValue.newValueDouble(6.00);
- private static final ITmfStateValue SMALLER_DOUBLE_VALUE2 = TmfStateValue.newValueDouble(9.99);
- private static final ITmfStateValue MIN_DOUBLE_VALUE = TmfStateValue.newValueDouble(Double.MIN_VALUE);
- private static final ITmfStateValue MAX_DOUBLE_VALUE = TmfStateValue.newValueDouble(Double.MAX_VALUE);
- private static final ITmfStateValue POSITIVE_INFINITY = TmfStateValue.newValueDouble(Double.POSITIVE_INFINITY);
- private static final ITmfStateValue NEGATIVE_INFINITY = TmfStateValue.newValueDouble(Double.NEGATIVE_INFINITY);
-
- private static final ITmfStateValue BASE_STRING_VALUE = TmfStateValue.newValueString("D");
- private static final ITmfStateValue BIGGER_STRING_VALUE = TmfStateValue.newValueString("Z");
- private static final ITmfStateValue SMALLER_STRING_VALUE = TmfStateValue.newValueString("A");
-
- private static final ITmfStateValue NULL_VALUE = TmfStateValue.nullValue();
-
- // ------------------------------------------------------------------------
- // Comparisons of Integer state values
- // ------------------------------------------------------------------------
-
- /**
- * Compare Integer state values together
- */
- @Test
- public void compareIntWithInt() {
- assertTrue(BASE_INT_VALUE.compareTo(BASE_INT_VALUE) == 0);
- assertTrue(BASE_INT_VALUE.compareTo(BIGGER_INT_VALUE) < 0);
- assertTrue(BASE_INT_VALUE.compareTo(SMALLER_INT_VALUE) > 0);
- }
-
- /**
- * Compare Integer with Long state values
- */
- @Test
- public void compareIntWithLong() {
- assertTrue(BASE_INT_VALUE.compareTo(BASE_LONG_VALUE) == 0);
- assertTrue(BASE_INT_VALUE.compareTo(BIGGER_LONG_VALUE) < 0);
- assertTrue(BASE_INT_VALUE.compareTo(MAX_LONG_VALUE) < 0);
-
- assertTrue(BASE_INT_VALUE.compareTo(SMALLER_LONG_VALUE) > 0);
- assertTrue(BASE_INT_VALUE.compareTo(MIN_LONG_VALUE) > 0);
- }
-
- /**
- * Compare Integer with Double state values
- */
- @Test
- public void compareIntWithDouble() {
- assertTrue(BASE_INT_VALUE.compareTo(BASE_DOUBLE_VALUE) == 0);
- assertTrue(BASE_INT_VALUE.compareTo(BIGGER_DOUBLE_VALUE1) < 0);
- assertTrue(BASE_INT_VALUE.compareTo(BIGGER_DOUBLE_VALUE2) < 0);
- assertTrue(BASE_INT_VALUE.compareTo(MAX_DOUBLE_VALUE) < 0);
- assertTrue(BASE_INT_VALUE.compareTo(POSITIVE_INFINITY) < 0);
- assertTrue(BASE_INT_VALUE.compareTo(SMALLER_DOUBLE_VALUE1) > 0);
- assertTrue(BASE_INT_VALUE.compareTo(SMALLER_DOUBLE_VALUE2) > 0);
- assertTrue(BASE_INT_VALUE.compareTo(MIN_DOUBLE_VALUE) > 0);
- assertTrue(BASE_INT_VALUE.compareTo(NEGATIVE_INFINITY) > 0);
- }
-
- /**
- * Compare Integer with Null state values
- */
- @Test
- public void compareIntWithNull() {
- assertTrue(BASE_INT_VALUE.compareTo(NULL_VALUE) > 0);
- }
-
- /**
- * Compare Integer with String state values (should fail)
- */
- @Test(expected = StateValueTypeException.class)
- public void tcompareIntWithString() {
- BASE_INT_VALUE.compareTo(BASE_STRING_VALUE);
- }
-
- // ------------------------------------------------------------------------
- // Comparisons of Long state values
- // ------------------------------------------------------------------------
-
- /**
- * Compare Long with Integer state values
- */
- @Test
- public void compareLongWithInt() {
- // with Integer
- assertTrue(BASE_LONG_VALUE.compareTo(BASE_INT_VALUE) == 0);
- assertTrue(BASE_LONG_VALUE.compareTo(BIGGER_INT_VALUE) < 0);
- assertTrue(BASE_LONG_VALUE.compareTo(SMALLER_INT_VALUE) > 0);
- }
-
- /**
- * Compare Long state values together
- */
- @Test
- public void compareLongWithLong() {
- assertTrue(BASE_LONG_VALUE.compareTo(BASE_LONG_VALUE) == 0);
- assertTrue(BASE_LONG_VALUE.compareTo(BIGGER_LONG_VALUE) < 0);
- assertTrue(BASE_LONG_VALUE.compareTo(MAX_LONG_VALUE) < 0);
- assertTrue(BASE_LONG_VALUE.compareTo(SMALLER_LONG_VALUE) > 0);
- assertTrue(BASE_LONG_VALUE.compareTo(MIN_LONG_VALUE) > 0);
- }
-
- /**
- * Compare Long with Double state values
- */
- @Test
- public void compareLongWithDouble() {
- assertTrue(BASE_LONG_VALUE.compareTo(BASE_DOUBLE_VALUE) == 0);
- assertTrue(BASE_LONG_VALUE.compareTo(BIGGER_DOUBLE_VALUE1) < 0);
- assertTrue(BASE_LONG_VALUE.compareTo(BIGGER_DOUBLE_VALUE2) < 0);
- assertTrue(BASE_LONG_VALUE.compareTo(MAX_DOUBLE_VALUE) < 0);
- assertTrue(BASE_LONG_VALUE.compareTo(POSITIVE_INFINITY) < 0);
- assertTrue(BASE_LONG_VALUE.compareTo(SMALLER_DOUBLE_VALUE1) > 0);
- assertTrue(BASE_LONG_VALUE.compareTo(SMALLER_DOUBLE_VALUE2) > 0);
- assertTrue(BASE_LONG_VALUE.compareTo(MIN_DOUBLE_VALUE) > 0);
- assertTrue(BASE_LONG_VALUE.compareTo(NEGATIVE_INFINITY) > 0);
- }
-
- /**
- * Compare Long with Null state values
- */
- @Test
- public void compareLongWithNull() {
- assertTrue(BASE_LONG_VALUE.compareTo(NULL_VALUE) > 0);
- }
-
- /**
- * Compare Long with String state values (should fail)
- */
- @Test(expected = StateValueTypeException.class)
- public void compareLongWithString() {
- BASE_LONG_VALUE.compareTo(BASE_STRING_VALUE);
- }
-
- // ------------------------------------------------------------------------
- // Comparisons of Double state values
- // ------------------------------------------------------------------------
-
- /**
- * Compare Double with Integer state values
- */
- @Test
- public void compareDoubleWithInt() {
- assertTrue(BASE_DOUBLE_VALUE.compareTo(BASE_INT_VALUE) == 0);
- assertTrue(BASE_DOUBLE_VALUE.compareTo(BIGGER_INT_VALUE) < 0);
- assertTrue(BASE_DOUBLE_VALUE.compareTo(SMALLER_INT_VALUE) > 0);
- }
-
- /**
- * Compare Double with Long state values
- */
- @Test
- public void compareDoubleWithLong() {
- assertTrue(BASE_DOUBLE_VALUE.compareTo(BASE_LONG_VALUE) == 0);
- assertTrue(BASE_DOUBLE_VALUE.compareTo(BIGGER_LONG_VALUE) < 0);
- assertTrue(SMALLER_DOUBLE_VALUE2.compareTo(BASE_LONG_VALUE) < 0);
- assertTrue(BASE_DOUBLE_VALUE.compareTo(MAX_LONG_VALUE) < 0);
- assertTrue(BIGGER_DOUBLE_VALUE1.compareTo(SMALLER_LONG_VALUE) > 0);
- assertTrue(BIGGER_DOUBLE_VALUE2.compareTo(BASE_LONG_VALUE) > 0);
- assertTrue(BASE_DOUBLE_VALUE.compareTo(MIN_LONG_VALUE) > 0);
- }
-
- /**
- * Compare Double state values together
- */
- @Test
- public void compareDoubleWithDouble() {
- assertTrue(BASE_DOUBLE_VALUE.compareTo(BASE_DOUBLE_VALUE) == 0);
- assertTrue(BASE_DOUBLE_VALUE.compareTo(BIGGER_DOUBLE_VALUE2) < 0);
- assertTrue(BASE_DOUBLE_VALUE.compareTo(MAX_DOUBLE_VALUE) < 0);
- assertTrue(BASE_DOUBLE_VALUE.compareTo(SMALLER_DOUBLE_VALUE2) > 0);
- assertTrue(BASE_DOUBLE_VALUE.compareTo(MIN_DOUBLE_VALUE) > 0);
- }
-
- /**
- * Compare Double with Null state values
- */
- @Test
- public void compareDoubleWithNull() {
- /* NullValue.unboxDouble returns NaN */
- assertTrue(BASE_DOUBLE_VALUE.compareTo(NULL_VALUE) < 0);
- }
-
- /**
- * Compare Double with String state values (should fail)
- */
- @Test(expected = StateValueTypeException.class)
- public void compareDoubleWithString() {
- BASE_DOUBLE_VALUE.compareTo(BASE_STRING_VALUE);
- }
-
- // ------------------------------------------------------------------------
- // Comparisons of String state values
- // ------------------------------------------------------------------------
-
- /**
- * Compare String with Integer state values (should fail)
- */
- @Test(expected = StateValueTypeException.class)
- public void compareStringWithInt() {
- BASE_STRING_VALUE.compareTo(BASE_INT_VALUE);
- }
-
- /**
- * Compare String with Long state values (should fail)
- */
- @Test(expected = StateValueTypeException.class)
- public void compareStringWithLong() {
- BASE_STRING_VALUE.compareTo(BASE_LONG_VALUE);
- }
-
- /**
- * Compare String with Double state values (should fail)
- */
- @Test(expected = StateValueTypeException.class)
- public void compareStringWithDouble() {
- BASE_STRING_VALUE.compareTo(BASE_DOUBLE_VALUE);
- }
-
- /**
- * Compare String state values together
- */
- @Test
- public void compareStringWithString() {
- assertTrue(BASE_STRING_VALUE.compareTo(BASE_STRING_VALUE) == 0);
- assertTrue(BASE_STRING_VALUE.compareTo(SMALLER_STRING_VALUE) > 0);
- assertTrue(BASE_STRING_VALUE.compareTo(BIGGER_STRING_VALUE) < 0);
- }
-
- /**
- * Compare String with Null state values
- */
- @Test
- public void compareStringWithNull() {
- assertTrue(BASE_STRING_VALUE.compareTo(NULL_VALUE) > 0);
- }
-
- // ------------------------------------------------------------------------
- // Comparisons of Null state values
- // ------------------------------------------------------------------------
-
- /**
- * Compare Null with Integer state values
- */
- @Test
- public void compareNullWithInt() {
- assertTrue(NULL_VALUE.compareTo(BASE_INT_VALUE) < 0);
- }
-
- /**
- * Compare Null with Long state values
- */
- @Test
- public void compareNullWithLong() {
- assertTrue(NULL_VALUE.compareTo(BASE_LONG_VALUE) < 0);
- }
-
- /**
- * Compare Null with Double state values
- */
- @Test
- public void compareNullWithDouble() {
- /* NullValue.unboxDouble returns NaN */
- assertTrue(NULL_VALUE.compareTo(BASE_DOUBLE_VALUE) > 0);
- }
-
- /**
- * Compare Null with String state values
- */
- @Test
- public void compareNullWithString() {
- assertTrue(NULL_VALUE.compareTo(BASE_STRING_VALUE) < 0);
- }
-
- /**
- * Compare Null state values together
- */
- @Test
- public void compareNullWithNull() {
- assertTrue(NULL_VALUE.compareTo(NULL_VALUE) == 0);
- }
-
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="output" path="bin"/>
-</classpath>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>org.eclipse.tracecompass.statesystem.core</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.ManifestBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.SchemaBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.pde.PluginNature</nature>
- <nature>org.eclipse.jdt.core.javanature</nature>
- <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
- </natures>
-</projectDescription>
+++ /dev/null
-eclipse.preferences.version=1
-encoding/<project>=UTF-8
+++ /dev/null
-eclipse.preferences.version=1
-line.separator=\n
+++ /dev/null
-eclipse.preferences.version=1
-org.eclipse.jdt.core.codeComplete.argumentPrefixes=
-org.eclipse.jdt.core.codeComplete.argumentSuffixes=
-org.eclipse.jdt.core.codeComplete.fieldPrefixes=f
-org.eclipse.jdt.core.codeComplete.fieldSuffixes=
-org.eclipse.jdt.core.codeComplete.localPrefixes=
-org.eclipse.jdt.core.codeComplete.localSuffixes=
-org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
-org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
-org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
-org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
-org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=enabled
-org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
-org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
-org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
-org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
-org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.7
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.doc.comment.support=enabled
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=error
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=error
-org.eclipse.jdt.core.compiler.problem.deadCode=error
-org.eclipse.jdt.core.compiler.problem.deprecation=error
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=error
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=error
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=error
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=error
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=error
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error
-org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=error
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=error
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=error
-org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
-org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
-org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
-org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
-org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=error
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
-org.eclipse.jdt.core.compiler.problem.missingDefaultCase=error
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=error
-org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=enabled
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=error
-org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning
-org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
-org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=error
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=error
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
-org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
-org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=warning
-org.eclipse.jdt.core.compiler.problem.nullReference=error
-org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=error
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=error
-org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=error
-org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=error
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=error
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
-org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=enabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=error
-org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.unclosedCloseable=error
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=error
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=error
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=disabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=disabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedImport=error
-org.eclipse.jdt.core.compiler.problem.unusedLabel=error
-org.eclipse.jdt.core.compiler.problem.unusedLocal=error
-org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameter=error
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
-org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=error
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=error
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error
-org.eclipse.jdt.core.compiler.source=1.7
-org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
-org.eclipse.jdt.core.formatter.alignment_for_assignment=0
-org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
-org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
-org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
-org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
-org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
-org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
-org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
-org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
-org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=0
-org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
-org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
-org.eclipse.jdt.core.formatter.blank_lines_after_package=1
-org.eclipse.jdt.core.formatter.blank_lines_before_field=0
-org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
-org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
-org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
-org.eclipse.jdt.core.formatter.blank_lines_before_method=1
-org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
-org.eclipse.jdt.core.formatter.blank_lines_before_package=0
-org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
-org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
-org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
-org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
-org.eclipse.jdt.core.formatter.comment.format_block_comments=true
-org.eclipse.jdt.core.formatter.comment.format_header=false
-org.eclipse.jdt.core.formatter.comment.format_html=true
-org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
-org.eclipse.jdt.core.formatter.comment.format_line_comments=true
-org.eclipse.jdt.core.formatter.comment.format_source_code=true
-org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
-org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
-org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
-org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
-org.eclipse.jdt.core.formatter.comment.line_length=80
-org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
-org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
-org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
-org.eclipse.jdt.core.formatter.compact_else_if=true
-org.eclipse.jdt.core.formatter.continuation_indentation=2
-org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
-org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
-org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
-org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
-org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
-org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
-org.eclipse.jdt.core.formatter.indent_empty_lines=false
-org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
-org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
-org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
-org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
-org.eclipse.jdt.core.formatter.indentation.size=4
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
-org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
-org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
-org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
-org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
-org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
-org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.join_lines_in_comments=true
-org.eclipse.jdt.core.formatter.join_wrapped_lines=false
-org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
-org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
-org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
-org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
-org.eclipse.jdt.core.formatter.lineSplit=250
-org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
-org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
-org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
-org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
-org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
-org.eclipse.jdt.core.formatter.tabulation.char=space
-org.eclipse.jdt.core.formatter.tabulation.size=4
-org.eclipse.jdt.core.formatter.use_on_off_tags=false
-org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
-org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
-org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
-org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
+++ /dev/null
-eclipse.preferences.version=1
-editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_profile=_tmf-style
-formatter_settings_version=12
-org.eclipse.jdt.ui.exception.name=e
-org.eclipse.jdt.ui.gettersetter.use.is=true
-org.eclipse.jdt.ui.keywordthis=false
-org.eclipse.jdt.ui.overrideannotation=true
-sp_cleanup.add_default_serial_version_id=true
-sp_cleanup.add_generated_serial_version_id=false
-sp_cleanup.add_missing_annotations=false
-sp_cleanup.add_missing_deprecated_annotations=true
-sp_cleanup.add_missing_methods=false
-sp_cleanup.add_missing_nls_tags=false
-sp_cleanup.add_missing_override_annotations=true
-sp_cleanup.add_missing_override_annotations_interface_methods=true
-sp_cleanup.add_serial_version_id=false
-sp_cleanup.always_use_blocks=true
-sp_cleanup.always_use_parentheses_in_expressions=false
-sp_cleanup.always_use_this_for_non_static_field_access=false
-sp_cleanup.always_use_this_for_non_static_method_access=false
-sp_cleanup.convert_to_enhanced_for_loop=false
-sp_cleanup.correct_indentation=false
-sp_cleanup.format_source_code=false
-sp_cleanup.format_source_code_changes_only=false
-sp_cleanup.make_local_variable_final=false
-sp_cleanup.make_parameters_final=false
-sp_cleanup.make_private_fields_final=true
-sp_cleanup.make_type_abstract_if_missing_method=false
-sp_cleanup.make_variable_declarations_final=false
-sp_cleanup.never_use_blocks=false
-sp_cleanup.never_use_parentheses_in_expressions=true
-sp_cleanup.on_save_use_additional_actions=true
-sp_cleanup.organize_imports=false
-sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
-sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
-sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
-sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
-sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
-sp_cleanup.remove_private_constructors=true
-sp_cleanup.remove_trailing_whitespaces=true
-sp_cleanup.remove_trailing_whitespaces_all=true
-sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
-sp_cleanup.remove_unnecessary_casts=false
-sp_cleanup.remove_unnecessary_nls_tags=false
-sp_cleanup.remove_unused_imports=false
-sp_cleanup.remove_unused_local_variables=false
-sp_cleanup.remove_unused_private_fields=true
-sp_cleanup.remove_unused_private_members=false
-sp_cleanup.remove_unused_private_methods=true
-sp_cleanup.remove_unused_private_types=true
-sp_cleanup.sort_members=false
-sp_cleanup.sort_members_all=false
-sp_cleanup.use_blocks=true
-sp_cleanup.use_blocks_only_for_return_and_throw=false
-sp_cleanup.use_parentheses_in_expressions=false
-sp_cleanup.use_this_for_non_static_field_access=false
-sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
-sp_cleanup.use_this_for_non_static_method_access=false
-sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+++ /dev/null
-ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error
-ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
-ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error
-ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Error
-ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
-API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error
-API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error
-API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error
-API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error
-API_USE_SCAN_FIELD_SEVERITY=Error
-API_USE_SCAN_METHOD_SEVERITY=Error
-API_USE_SCAN_TYPE_SEVERITY=Error
-CLASS_ELEMENT_TYPE_ADDED_METHOD=Error
-CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
-CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
-CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
-CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
-CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
-CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
-CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
-CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Error
-CLASS_ELEMENT_TYPE_REMOVED_FIELD=Error
-CLASS_ELEMENT_TYPE_REMOVED_METHOD=Error
-CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Error
-CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
-CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
-CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
-CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
-CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
-CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
-ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
-ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
-ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Error
-ENUM_ELEMENT_TYPE_REMOVED_FIELD=Error
-ENUM_ELEMENT_TYPE_REMOVED_METHOD=Error
-ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
-FIELD_ELEMENT_TYPE_ADDED_VALUE=Error
-FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
-FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Error
-FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
-FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
-FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
-FIELD_ELEMENT_TYPE_CHANGED_TYPE=Error
-FIELD_ELEMENT_TYPE_CHANGED_VALUE=Error
-FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Error
-FIELD_ELEMENT_TYPE_REMOVED_VALUE=Error
-ILLEGAL_EXTEND=Warning
-ILLEGAL_IMPLEMENT=Warning
-ILLEGAL_INSTANTIATE=Warning
-ILLEGAL_OVERRIDE=Warning
-ILLEGAL_REFERENCE=Warning
-INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error
-INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error
-INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
-INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Error
-INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
-INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
-INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
-INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Error
-INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error
-INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
-INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
-INVALID_JAVADOC_TAG=Warning
-INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Warning
-LEAK_EXTEND=Warning
-LEAK_FIELD_DECL=Warning
-LEAK_IMPLEMENT=Warning
-LEAK_METHOD_PARAM=Warning
-LEAK_METHOD_RETURN_TYPE=Warning
-METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
-METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
-METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
-METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
-METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
-METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
-METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
-METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
-METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error
-METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
-MISSING_EE_DESCRIPTIONS=Ignore
-TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
-TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
-TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
-TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
-TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
-TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
-UNUSED_PROBLEM_FILTERS=Warning
-automatically_removed_unused_problem_filters=false
-eclipse.preferences.version=1
-incompatible_api_component_version=Error
-incompatible_api_component_version_include_major_without_breaking_change=Disabled
-incompatible_api_component_version_include_minor_without_api_change=Disabled
-invalid_since_tag_version=Error
-malformed_since_tag=Error
-missing_since_tag=Error
-report_api_breakage_when_major_version_incremented=Disabled
-report_resolution_errors_api_component=Warning
+++ /dev/null
-compilers.f.unresolved-features=1
-compilers.f.unresolved-plugins=1
-compilers.incompatible-environment=1
-compilers.p.build=1
-compilers.p.build.bin.includes=1
-compilers.p.build.encodings=2
-compilers.p.build.java.compiler=2
-compilers.p.build.java.compliance=1
-compilers.p.build.missing.output=2
-compilers.p.build.output.library=1
-compilers.p.build.source.library=1
-compilers.p.build.src.includes=1
-compilers.p.deprecated=1
-compilers.p.discouraged-class=1
-compilers.p.internal=1
-compilers.p.missing-packages=1
-compilers.p.missing-version-export-package=2
-compilers.p.missing-version-import-package=2
-compilers.p.missing-version-require-bundle=2
-compilers.p.no-required-att=0
-compilers.p.not-externalized-att=1
-compilers.p.unknown-attribute=1
-compilers.p.unknown-class=1
-compilers.p.unknown-element=1
-compilers.p.unknown-identifier=1
-compilers.p.unknown-resource=1
-compilers.p.unresolved-ex-points=0
-compilers.p.unresolved-import=0
-compilers.s.create-docs=false
-compilers.s.doc-folder=doc
-compilers.s.open-tags=1
-eclipse.preferences.version=1
+++ /dev/null
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: %Bundle-Name
-Bundle-Vendor: %Bundle-Vendor
-Bundle-Version: 1.0.0.qualifier
-Bundle-Localization: plugin
-Bundle-SymbolicName: org.eclipse.tracecompass.statesystem.core;singleton:=true
-Bundle-Activator: org.eclipse.tracecompass.internal.statesystem.core.Activator
-Bundle-ActivationPolicy: lazy
-Bundle-RequiredExecutionEnvironment: JavaSE-1.7
-Require-Bundle: org.eclipse.core.runtime,
- org.eclipse.core.resources,
- org.eclipse.tracecompass.common.core
-Export-Package: org.eclipse.tracecompass.internal.statesystem.core;x-friends:="org.eclipse.tracecompass.statesystem.core.tests",
- org.eclipse.tracecompass.internal.statesystem.core.backend;x-internal:=true,
- org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;x-friends:="org.eclipse.tracecompass.statesystem.core.tests",
- org.eclipse.tracecompass.statesystem.core,
- org.eclipse.tracecompass.statesystem.core.backend,
- org.eclipse.tracecompass.statesystem.core.exceptions,
- org.eclipse.tracecompass.statesystem.core.interval,
- org.eclipse.tracecompass.statesystem.core.statevalue
-Import-Package: com.google.common.collect;version="12.0.0"
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
-<title>About</title>
-</head>
-<body lang="EN-US">
-<h2>About This Content</h2>
-
-<p>June 5, 2006</p>
-<h3>License</h3>
-
-<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
-indicated below, the Content is provided to you under the terms and conditions of the
-Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
-at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
-For purposes of the EPL, "Program" will mean the Content.</p>
-
-<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
-being redistributed by another party ("Redistributor") and different terms and conditions may
-apply to your use of any object code in the Content. Check the Redistributor's license that was
-provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
-indicated below, the terms and conditions of the EPL still apply to any source code in the Content
-and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
-
-</body>
-</html>
\ No newline at end of file
+++ /dev/null
-###############################################################################
-# Copyright (c) 2014 Ericsson
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-#
-# Contributors:
-# Ericsson - Initial API and implementation
-###############################################################################
-
-source.. = src/
-output.. = bin/
-bin.includes = META-INF/,\
- plugin.properties,\
- about.html,\
- .
-src.includes = about.html
-additional.bundles = org.eclipse.jdt.annotation
-jars.extra.classpath = platform:/plugin/org.eclipse.jdt.annotation
+++ /dev/null
-###############################################################################
-# Copyright (c) 2014 Ericsson
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-#
-# Contributors:
-# Ericsson - Initial API and implementation
-###############################################################################
-
-Bundle-Vendor = Eclipse Trace Compass
-Bundle-Name = Trace Compass State System Core Plug-in
-
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (C) 2014, Ericsson
-
- All rights reserved. This program and the accompanying materials
- are made available under the terms of the Eclipse Public License v1.0
- which accompanies this distribution, and is available at
- http://www.eclipse.org/legal/epl-v10.html
--->
-<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <artifactId>org.eclipse.tracecompass</artifactId>
- <groupId>org.eclipse.tracecompass</groupId>
- <version>1.0.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>org.eclipse.tracecompass.statesystem.core</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- <packaging>eclipse-plugin</packaging>
-
- <name>Trace Compass State System Core Plug-in</name>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.eclipse.tycho</groupId>
- <artifactId>tycho-source-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
- <groupId>org.eclipse.tracecompass</groupId>
-</project>
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Francois Chouinard - Initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.tracecompass.internal.statesystem.core;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Plugin;
-import org.eclipse.core.runtime.Status;
-import org.osgi.framework.BundleContext;
-
-/**
- * <b><u>Activator</u></b>
- * <p>
- * The activator class controls the plug-in life cycle
- */
-public final class Activator extends Plugin {
-
- // ------------------------------------------------------------------------
- // Attributes
- // ------------------------------------------------------------------------
-
- /**
- * The plug-in ID
- */
- public static final String PLUGIN_ID = "org.eclipse.tracecompass.statesystem.core"; //$NON-NLS-1$
-
- /**
- * The shared instance
- */
- private static Activator plugin;
-
- // ------------------------------------------------------------------------
- // Constructors
- // ------------------------------------------------------------------------
-
- /**
- * The constructor
- */
- public Activator() {
- }
-
- // ------------------------------------------------------------------------
- // Accessors
- // ------------------------------------------------------------------------
-
- /**
- * Returns the shared instance
- *
- * @return the shared instance
- */
- public static Activator getDefault() {
- return plugin;
- }
-
- // ------------------------------------------------------------------------
- // Operators
- // ------------------------------------------------------------------------
-
- @Override
- public void start(BundleContext context) throws Exception {
- super.start(context);
- plugin = this;
- }
-
- @Override
- public void stop(BundleContext context) throws Exception {
- plugin = null;
- super.stop(context);
- }
-
- /**
- * Logs a message with severity INFO in the runtime log of the plug-in.
- *
- * @param message A message to log
- */
- public void logInfo(String message) {
- getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message));
- }
-
- /**
- * Logs a message and exception with severity INFO in the runtime log of the plug-in.
- *
- * @param message A message to log
- * @param exception A exception to log
- */
- public void logInfo(String message, Throwable exception) {
- getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message, exception));
- }
-
- /**
- * Logs a message and exception with severity WARNING in the runtime log of the plug-in.
- *
- * @param message A message to log
- */
- public void logWarning(String message) {
- getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message));
- }
-
- /**
- * Logs a message and exception with severity WARNING in the runtime log of the plug-in.
- *
- * @param message A message to log
- * @param exception A exception to log
- */
- public void logWarning(String message, Throwable exception) {
- getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message, exception));
- }
-
- /**
- * Logs a message and exception with severity ERROR in the runtime log of the plug-in.
- *
- * @param message A message to log
- */
- public void logError(String message) {
- getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message));
- }
-
- /**
- * Logs a message and exception with severity ERROR in the runtime log of the plug-in.
- *
- * @param message A message to log
- * @param exception A exception to log
- */
- public void logError(String message, Throwable exception) {
- getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message, exception));
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson, EfficiOS Inc.
- * Copyright (c) 2010, 2011 École Polytechnique de Montréal
- * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.tracecompass.internal.statesystem.core;
-
-import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
-
-import java.io.PrintWriter;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.Map;
-
-import org.eclipse.jdt.annotation.NonNull;
-
-import com.google.common.collect.ImmutableList;
-
-/**
- * An Attribute is a "node" in the Attribute Tree. It represents a smallest
- * unit of the model which can be in a particular state at a given time.
- *
- * It is abstract, as different implementations can provide different ways to
- * access sub-attributes
- *
- * @author Alexandre Montplaisir
- *
- */
-public final class Attribute {
-
- private final Attribute parent;
- private final @NonNull String name;
- private final int quark;
-
- /** The sub-attributes (<basename, attribute>) of this attribute */
- private final Map<String, Attribute> subAttributes;
-
- /**
- * Constructor
- *
- * @param parent
- * The parent attribute of this one. Can be 'null' to represent
- * this attribute is the root node of the tree.
- * @param name
- * Base name of this attribute
- * @param quark
- * The integer representation of this attribute
- */
- public Attribute(Attribute parent, @NonNull String name, int quark) {
- this.parent = parent;
- this.quark = quark;
- this.name = name;
- this.subAttributes = Collections.synchronizedMap(new LinkedHashMap<String, Attribute>());
- }
-
- // ------------------------------------------------------------------------
- // Accessors
- // ------------------------------------------------------------------------
-
- /**
- * Get the quark (integer representation) of this attribute.
- *
- * @return The quark of this attribute
- */
- public int getQuark() {
- return quark;
- }
-
- /**
- * Get the name of this attribute.
- *
- * @return The name of this attribute
- */
- public @NonNull String getName() {
- return name;
- }
-
- /**
- * Get the list of child attributes below this one.
- *
- * @return The child attributes.
- */
- public Iterable<Attribute> getSubAttributes() {
- return ImmutableList.copyOf(subAttributes.values());
- }
-
- /**
- * Get the matching quark for a given path-of-strings
- *
- * @param path
- * The path we are looking for, *relative to this node*.
- * @return The matching quark, or -1 if that attribute does not exist.
- */
- public int getSubAttributeQuark(String... path) {
- return this.getSubAttributeQuark(path, 0);
- }
-
- /**
- * Other method to search through the attribute tree, but instead of
- * returning the matching quark we return the AttributeTreeNode object
- * itself. It can then be used as new "root node" for faster queries on the
- * tree.
- *
- * @param path
- * The target path, *relative to this node*
- * @return The Node object matching the last element in the path, or "null"
- * if that attribute does not exist.
- */
- public Attribute getSubAttributeNode(String... path) {
- return this.getSubAttributeNode(path, 0);
- }
-
- /**
- * "Inner" part of the previous public method, which is used recursively. To
- * avoid having to copy sub-arrays to pass down, we just track where we are
- * at with the index parameter. It uses getSubAttributeNode(), whose
- * implementation is left to the derived classes.
- */
- private int getSubAttributeQuark(String[] path, int index) {
- Attribute targetNode = this.getSubAttributeNode(path, index);
- if (targetNode == null) {
- return -1;
- }
- return targetNode.getQuark();
- }
-
- /**
- * Get the parent attribute of this attribute
- *
- * @return The parent attribute
- */
- public Attribute getParentAttribute() {
- return this.parent;
- }
-
- /**
- * Get the parent quark of this attribute
- *
- * @return The quark of the parent attribute
- */
- public int getParentAttributeQuark() {
- return this.parent.getQuark();
- }
-
- /* The methods how to access children are left to derived classes */
-
- /**
- * Add a sub-attribute to this attribute
- *
- * @param newSubAttribute The new attribute to add
- */
- public void addSubAttribute(Attribute newSubAttribute) {
- if (newSubAttribute == null) {
- throw new IllegalArgumentException();
- }
- subAttributes.put(newSubAttribute.getName(), newSubAttribute);
- }
-
- /**
- * Get a sub-attribute from this node's sub-attributes
- *
- * @param path
- * The *full* path to the attribute
- * @param index
- * The index in 'path' where this attribute is located
- * (indicating where to start searching).
- * @return The requested attribute
- */
- private Attribute getSubAttributeNode(String[] path, int index) {
- final Attribute nextNode = subAttributes.get(path[index]);
-
- if (nextNode == null) {
- /* We don't have the expected child => the attribute does not exist */
- return null;
- }
- if (index == path.length - 1) {
- /* It's our job to process this request */
- return nextNode;
- }
-
- /* Pass on the rest of the path to the relevant child */
- return nextNode.getSubAttributeNode(path, index + 1);
- }
-
- /**
- * Return a String array composed of the full (absolute) path representing
- * this attribute
- *
- * @return The full attribute path elements
- */
- public @NonNull String[] getFullAttribute() {
- LinkedList<String> list = new LinkedList<>();
- Attribute curNode = this;
-
- /* Add recursive parents to the list, but stop at the root node */
- while (curNode.parent != null) {
- list.addFirst(curNode.getName());
- curNode = curNode.parent;
- }
-
- return checkNotNull(list.toArray(new String[0]));
- }
-
- /**
- * Return the absolute path of this attribute, as a single slash-separated
- * String.
- *
- * @return The full name of this attribute
- */
- public @NonNull String getFullAttributeName() {
- String[] array = this.getFullAttribute();
- StringBuffer buf = new StringBuffer();
-
- for (int i = 0; i < array.length - 1; i++) {
- buf.append(array[i]);
- buf.append('/');
- }
- buf.append(array[array.length - 1]);
- return checkNotNull(buf.toString());
- }
-
- @Override
- public String toString() {
- return getFullAttributeName() + " (" + quark + ')'; //$NON-NLS-1$
- }
-
- private int curDepth;
-
- private void attributeNodeToString(PrintWriter writer, Attribute currentNode) {
- writer.println(currentNode.getName() + " (" + currentNode.quark + ')'); //$NON-NLS-1$
- curDepth++;
-
- for (Attribute nextNode : currentNode.getSubAttributes()) {
- /* Skip printing 'null' entries */
- if (nextNode == null) {
- continue;
- }
- for (int j = 0; j < curDepth - 1; j++) {
- writer.print(" "); //$NON-NLS-1$
- }
- writer.print(" "); //$NON-NLS-1$
- attributeNodeToString(writer, nextNode);
- }
- curDepth--;
- return;
- }
-
- /**
- * Debugging method to print the contents of this attribute
- *
- * @param writer
- * PrintWriter where to write the information
- */
- public void debugPrint(PrintWriter writer) {
- /* Only used for debugging, shouldn't be externalized */
- writer.println("------------------------------"); //$NON-NLS-1$
- writer.println("Attribute tree: (quark)\n"); //$NON-NLS-1$
- curDepth = 0;
- attributeNodeToString(writer, this);
- writer.print('\n');
- }
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson
- * Copyright (c) 2010, 2011 École Polytechnique de Montréal
- * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- * Patrick Tasse - Add message to exceptions
- *******************************************************************************/
-
-package org.eclipse.tracecompass.internal.statesystem.core;
-
-import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.PrintWriter;
-import java.nio.channels.FileChannel;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
-
-/**
- * The Attribute Tree is the /proc-like filesystem used to organize attributes.
- * Each node of this tree is both like a file and a directory in the
- * "file system".
- *
- * @author alexmont
- *
- */
-public final class AttributeTree {
-
- /* "Magic number" for attribute tree files or file sections */
- private static final int ATTRIB_TREE_MAGIC_NUMBER = 0x06EC3671;
-
- private final StateSystem ss;
- private final List<Attribute> attributeList;
- private final Attribute attributeTreeRoot;
-
- /**
- * Standard constructor, create a new empty Attribute Tree
- *
- * @param ss
- * The StateSystem to which this AT is attached
- */
- public AttributeTree(StateSystem ss) {
- this.ss = ss;
- this.attributeList = Collections.synchronizedList(new ArrayList<Attribute>());
- this.attributeTreeRoot = new Attribute(null, "root", -1); //$NON-NLS-1$
- }
-
- /**
- * "Existing file" constructor. Builds an attribute tree from a
- * "mapping file" or mapping section previously saved somewhere.
- *
- * @param ss
- * StateSystem to which this AT is attached
- * @param fis
- * File stream where to read the AT information. Make sure it's
- * sought at the right place!
- * @throws IOException
- * If there is a problem reading from the file stream
- */
- public AttributeTree(StateSystem ss, FileInputStream fis) throws IOException {
- this(ss);
- ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(fis));
-
- /* Read the header of the Attribute Tree file (or file section) */
- int res = ois.readInt(); /* Magic number */
- if (res != ATTRIB_TREE_MAGIC_NUMBER) {
- throw new IOException("The attribute tree file section is either invalid or corrupted."); //$NON-NLS-1$
- }
-
-
- ArrayList<String[]> attribList;
- try {
- @SuppressWarnings("unchecked")
- ArrayList<String[]> list = (ArrayList<String[]>) ois.readObject();
- attribList = list;
- } catch (ClassNotFoundException e) {
- throw new IOException("Unrecognizable attribute list"); //$NON-NLS-1$
- }
-
- /*
- * Now we have 'list', the ArrayList of String arrays representing all
- * the attributes. Simply create attributes the normal way from them.
- */
- for (String[] attrib : attribList) {
- this.getQuarkAndAdd(-1, attrib);
- }
- }
-
- /**
- * Tell the Attribute Tree to write itself somewhere in a file.
- *
- * @param file
- * The file to write to
- * @param pos
- * The position (in bytes) in the file where to write
- */
- public void writeSelf(File file, long pos) {
- try (FileOutputStream fos = new FileOutputStream(file, true);
- FileChannel fc = fos.getChannel();) {
- fc.position(pos);
- try (ObjectOutputStream oos = new ObjectOutputStream(fos)) {
-
- /* Write the almost-magic number */
- oos.writeInt(ATTRIB_TREE_MAGIC_NUMBER);
-
- /* Compute the serialized list of attributes and write it */
- List<String[]> list = new ArrayList<>(attributeList.size());
- for (Attribute entry : this.attributeList) {
- list.add(entry.getFullAttribute());
- }
- oos.writeObject(list);
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- }
-
- /**
- * Return the number of attributes this system as seen so far. Note that
- * this also equals the integer value (quark) the next added attribute will
- * have.
- *
- * @return The current number of attributes in the tree
- */
- public int getNbAttributes() {
- return attributeList.size();
- }
-
- /**
- * Get the quark for a given attribute path. No new attribute will be
- * created : if the specified path does not exist, throw an error.
- *
- * @param startingNodeQuark
- * The quark of the attribute from which relative queries will
- * start. Use '-1' to start at the root node.
- * @param subPath
- * The path to the attribute, relative to the starting node.
- * @return The quark of the specified attribute
- * @throws AttributeNotFoundException
- * If the specified path was not found
- */
- public int getQuarkDontAdd(int startingNodeQuark, String... subPath)
- throws AttributeNotFoundException {
- assert (startingNodeQuark >= -1);
-
- Attribute prevNode;
-
- /* If subPath is empty, simply return the starting quark */
- if (subPath == null || subPath.length == 0) {
- return startingNodeQuark;
- }
-
- /* Get the "starting node" */
- if (startingNodeQuark == -1) {
- prevNode = attributeTreeRoot;
- } else {
- prevNode = attributeList.get(startingNodeQuark);
- }
-
- int knownQuark = prevNode.getSubAttributeQuark(subPath);
- if (knownQuark == -1) {
- /*
- * The attribute doesn't exist, but we have been specified to NOT
- * add any new attributes.
- */
- throw new AttributeNotFoundException(ss.getSSID() + " Quark:" + startingNodeQuark + ", SubPath:" + Arrays.toString(subPath)); //$NON-NLS-1$ //$NON-NLS-2$
- }
- /*
- * The attribute was already existing, return the quark of that
- * attribute
- */
- return knownQuark;
- }
-
- /**
- * Get the quark of a given attribute path. If that specified path does not
- * exist, it will be created (and the quark that was just created will be
- * returned).
- *
- * @param startingNodeQuark
- * The quark of the attribute from which relative queries will
- * start. Use '-1' to start at the root node.
- * @param subPath
- * The path to the attribute, relative to the starting node.
- * @return The quark of the attribute represented by the path
- */
- public synchronized int getQuarkAndAdd(int startingNodeQuark, String... subPath) {
- // FIXME synchronized here is probably quite costly... maybe only locking
- // the "for" would be enough?
- assert (subPath != null && subPath.length > 0);
- assert (startingNodeQuark >= -1);
-
- Attribute nextNode = null;
- Attribute prevNode;
-
- /* Get the "starting node" */
- if (startingNodeQuark == -1) {
- prevNode = attributeTreeRoot;
- } else {
- prevNode = attributeList.get(startingNodeQuark);
- }
-
- int knownQuark = prevNode.getSubAttributeQuark(subPath);
- if (knownQuark == -1) {
- /*
- * The attribute was not in the table previously, and we want to add
- * it
- */
- for (String curDirectory : subPath) {
- nextNode = prevNode.getSubAttributeNode(curDirectory);
- if (nextNode == null) {
- /* This is where we need to start adding */
- nextNode = new Attribute(prevNode, checkNotNull(curDirectory), attributeList.size());
- prevNode.addSubAttribute(nextNode);
- attributeList.add(nextNode);
- ss.addEmptyAttribute();
- }
- prevNode = nextNode;
- }
- return attributeList.size() - 1;
- }
- /*
- * The attribute was already existing, return the quark of that
- * attribute
- */
- return knownQuark;
- }
-
- /**
- * Returns the sub-attributes of the quark passed in parameter
- *
- * @param attributeQuark
- * The quark of the attribute to print the sub-attributes of.
- * @param recursive
- * Should the query be recursive or not? If false, only children
- * one level deep will be returned. If true, all descendants will
- * be returned (depth-first search)
- * @return The list of quarks representing the children attributes
- * @throws AttributeNotFoundException
- * If 'attributeQuark' is invalid, or if there is no attrbiute
- * associated to it.
- */
- public @NonNull List<Integer> getSubAttributes(int attributeQuark, boolean recursive)
- throws AttributeNotFoundException {
- List<Integer> listOfChildren = new ArrayList<>();
- Attribute startingAttribute;
-
- /* Check if the quark is valid */
- if (attributeQuark < -1 || attributeQuark >= attributeList.size()) {
- throw new AttributeNotFoundException(ss.getSSID() + " Quark:" + attributeQuark); //$NON-NLS-1$
- }
-
- /* Set up the node from which we'll start the search */
- if (attributeQuark == -1) {
- startingAttribute = attributeTreeRoot;
- } else {
- startingAttribute = attributeList.get(attributeQuark);
- }
-
- /* Iterate through the sub-attributes and add them to the list */
- addSubAttributes(listOfChildren, startingAttribute, recursive);
-
- return listOfChildren;
- }
-
- /**
- * Returns the parent quark of the attribute. The root attribute has no
- * parent and will return <code>-1</code>
- *
- * @param quark
- * The quark of the attribute
- * @return Quark of the parent attribute or <code>-1</code> for the root
- * attribute
- */
- public int getParentAttributeQuark(int quark) {
- if (quark == -1) {
- return quark;
- }
- return attributeList.get(quark).getParentAttributeQuark();
- }
-
- private void addSubAttributes(List<Integer> list, Attribute curAttribute,
- boolean recursive) {
- for (Attribute childNode : curAttribute.getSubAttributes()) {
- list.add(childNode.getQuark());
- if (recursive) {
- addSubAttributes(list, childNode, true);
- }
- }
- }
-
- /**
- * Get then base name of an attribute specified by a quark.
- *
- * @param quark
- * The quark of the attribute
- * @return The (base) name of the attribute
- */
- public @NonNull String getAttributeName(int quark) {
- return attributeList.get(quark).getName();
- }
-
- /**
- * Get the full path name of an attribute specified by a quark.
- *
- * @param quark
- * The quark of the attribute
- * @return The full path name of the attribute
- */
- public @NonNull String getFullAttributeName(int quark) {
- return attributeList.get(quark).getFullAttributeName();
- }
-
- /**
- * Get the full path name (as an array of path elements) of an attribute
- * specified by a quark.
- *
- * @param quark
- * The quark of the attribute
- * @return The path elements of the full path
- */
- public @NonNull String[] getFullAttributePathArray(int quark) {
- return attributeList.get(quark).getFullAttribute();
- }
-
- /**
- * Debug-print all the attributes in the tree.
- *
- * @param writer
- * The writer where to print the output
- */
- public void debugPrint(PrintWriter writer) {
- attributeTreeRoot.debugPrint(writer);
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson
- * Copyright (c) 2010, 2011 École Polytechnique de Montréal
- * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- * Patrick Tasse - Add message to exceptions
- *******************************************************************************/
-
-package org.eclipse.tracecompass.internal.statesystem.core;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
-import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
-import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
-import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
-import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
-import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue.Type;
-import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
-
-/**
- * This is the core class of the Generic State System. It contains all the
- * methods to build and query a state history. It's exposed externally through
- * the IStateSystemQuerier and IStateSystemBuilder interfaces, depending if the
- * user needs read-only access or read-write access.
- *
- * When building, DON'T FORGET to call .closeHistory() when you are done
- * inserting intervals, or the storage backend will have no way of knowing it
- * can close and write itself to disk, and its thread will keep running.
- *
- * @author alexmont
- *
- */
-public class StateSystem implements ITmfStateSystemBuilder {
-
- /* References to the inner structures */
- private final AttributeTree attributeTree;
- private final TransientState transState;
- private final IStateHistoryBackend backend;
-
- /* Latch tracking if the state history is done building or not */
- private final CountDownLatch finishedLatch = new CountDownLatch(1);
-
- private boolean buildCancelled = false;
- private boolean isDisposed = false;
-
- /**
- * New-file constructor. For when you build a state system with a new file,
- * or if the back-end does not require a file on disk.
- *
- * @param backend
- * Back-end plugin to use
- */
- public StateSystem(@NonNull IStateHistoryBackend backend) {
- this.backend = backend;
- this.transState = new TransientState(backend);
- this.attributeTree = new AttributeTree(this);
- }
-
- /**
- * General constructor
- *
- * @param backend
- * The "state history storage" back-end to use.
- * @param newFile
- * Put true if this is a new history started from scratch. It is
- * used to tell the state system where to get its attribute tree.
- * @throws IOException
- * If there was a problem creating the new history file
- */
- public StateSystem(@NonNull IStateHistoryBackend backend, boolean newFile)
- throws IOException {
- this.backend = backend;
- this.transState = new TransientState(backend);
-
- if (newFile) {
- attributeTree = new AttributeTree(this);
- } else {
- /* We're opening an existing file */
- this.attributeTree = new AttributeTree(this, backend.supplyAttributeTreeReader());
- transState.setInactive();
- finishedLatch.countDown(); /* The history is already built */
- }
- }
-
- @Override
- public String getSSID() {
- return backend.getSSID();
- }
-
- @Override
- public boolean isCancelled() {
- return buildCancelled;
- }
-
- @Override
- public void waitUntilBuilt() {
- try {
- finishedLatch.await();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
-
- @Override
- public boolean waitUntilBuilt(long timeout) {
- boolean ret = false;
- try {
- ret = finishedLatch.await(timeout, TimeUnit.MILLISECONDS);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- return ret;
- }
-
- @Override
- public synchronized void dispose() {
- isDisposed = true;
- if (transState.isActive()) {
- transState.setInactive();
- buildCancelled = true;
- }
- backend.dispose();
- }
-
- //--------------------------------------------------------------------------
- // General methods related to the attribute tree
- //--------------------------------------------------------------------------
-
- /**
- * Get the attribute tree associated with this state system. This should be
- * the only way of accessing it (and if subclasses want to point to a
- * different attribute tree than their own, they should only need to
- * override this).
- *
- * @return The attribute tree
- */
- public AttributeTree getAttributeTree() {
- return attributeTree;
- }
-
- /**
- * Method used by the attribute tree when creating new attributes, to keep
- * the attribute count in the transient state in sync.
- */
- public void addEmptyAttribute() {
- transState.addEmptyEntry();
- }
-
- @Override
- public int getNbAttributes() {
- return getAttributeTree().getNbAttributes();
- }
-
- @Override
- public String getAttributeName(int attributeQuark) {
- return getAttributeTree().getAttributeName(attributeQuark);
- }
-
- @Override
- public String getFullAttributePath(int attributeQuark) {
- return getAttributeTree().getFullAttributeName(attributeQuark);
- }
-
- @Override
- public String[] getFullAttributePathArray(int attributeQuark) {
- return getAttributeTree().getFullAttributePathArray(attributeQuark);
- }
-
- //--------------------------------------------------------------------------
- // Methods related to the storage backend
- //--------------------------------------------------------------------------
-
- @Override
- public long getStartTime() {
- return backend.getStartTime();
- }
-
- @Override
- public long getCurrentEndTime() {
- return backend.getEndTime();
- }
-
- @Override
- public void closeHistory(long endTime) throws TimeRangeException {
- File attributeTreeFile;
- long attributeTreeFilePos;
- long realEndTime = endTime;
-
- if (realEndTime < backend.getEndTime()) {
- /*
- * This can happen (empty nodes pushing the border further, etc.)
- * but shouldn't be too big of a deal.
- */
- realEndTime = backend.getEndTime();
- }
- transState.closeTransientState(realEndTime);
- backend.finishedBuilding(realEndTime);
-
- attributeTreeFile = backend.supplyAttributeTreeWriterFile();
- attributeTreeFilePos = backend.supplyAttributeTreeWriterFilePosition();
- if (attributeTreeFile != null) {
- /*
- * If null was returned, we simply won't save the attribute tree,
- * too bad!
- */
- getAttributeTree().writeSelf(attributeTreeFile, attributeTreeFilePos);
- }
- finishedLatch.countDown(); /* Mark the history as finished building */
- }
-
- //--------------------------------------------------------------------------
- // Quark-retrieving methods
- //--------------------------------------------------------------------------
-
- @Override
- public int getQuarkAbsolute(String... attribute)
- throws AttributeNotFoundException {
- return getAttributeTree().getQuarkDontAdd(-1, attribute);
- }
-
- @Override
- public int getQuarkAbsoluteAndAdd(String... attribute) {
- return getAttributeTree().getQuarkAndAdd(-1, attribute);
- }
-
- @Override
- public int getQuarkRelative(int startingNodeQuark, String... subPath)
- throws AttributeNotFoundException {
- return getAttributeTree().getQuarkDontAdd(startingNodeQuark, subPath);
- }
-
- @Override
- public int getQuarkRelativeAndAdd(int startingNodeQuark, String... subPath) {
- return getAttributeTree().getQuarkAndAdd(startingNodeQuark, subPath);
- }
-
- @Override
- public List<Integer> getSubAttributes(int quark, boolean recursive)
- throws AttributeNotFoundException {
- return getAttributeTree().getSubAttributes(quark, recursive);
- }
-
- @Override
- public List<Integer> getSubAttributes(int quark, boolean recursive, String pattern)
- throws AttributeNotFoundException {
- List<Integer> all = getSubAttributes(quark, recursive);
- List<Integer> ret = new LinkedList<>();
- for (Integer attQuark : all) {
- String name = getAttributeName(attQuark.intValue());
- if (name.matches(pattern)) {
- ret.add(attQuark);
- }
- }
- return ret;
- }
-
- @Override
- public int getParentAttributeQuark(int quark) {
- return getAttributeTree().getParentAttributeQuark(quark);
- }
-
- @Override
- public List<Integer> getQuarks(String... pattern) {
- List<Integer> quarks = new LinkedList<>();
- List<String> prefix = new LinkedList<>();
- List<String> suffix = new LinkedList<>();
- boolean split = false;
- String[] prefixStr;
- String[] suffixStr;
- List<Integer> directChildren;
- int startingAttribute;
-
- /* Fill the "prefix" and "suffix" parts of the pattern around the '*' */
- for (String entry : pattern) {
- if (entry.equals("*")) { //$NON-NLS-1$
- if (split) {
- /*
- * Split was already true? This means there was more than
- * one wildcard. This is not supported, return an empty
- * list.
- */
- return quarks;
- }
- split = true;
- continue;
- }
-
- if (split) {
- suffix.add(entry);
- } else {
- prefix.add(entry);
- }
- }
- prefixStr = prefix.toArray(new String[prefix.size()]);
- suffixStr = suffix.toArray(new String[suffix.size()]);
-
- /*
- * If there was no wildcard, we'll only return the one matching
- * attribute, if there is one.
- */
- if (!split) {
- int quark;
- try {
- quark = getQuarkAbsolute(prefixStr);
- } catch (AttributeNotFoundException e) {
- /* It's fine, we'll just return the empty List */
- return quarks;
- }
- quarks.add(quark);
- return quarks;
- }
-
- try {
- if (prefix.size() == 0) {
- /*
- * If 'prefix' is empty, this means the wildcard was the first
- * element. Look for the root node's sub-attributes.
- */
- startingAttribute = -1;
- } else {
- startingAttribute = getQuarkAbsolute(prefixStr);
- }
- directChildren = getSubAttributes(startingAttribute, false);
- } catch (AttributeNotFoundException e) {
- /* That attribute path did not exist, return the empty array */
- return quarks;
- }
-
- /*
- * Iterate of all the sub-attributes, and only keep those who match the
- * 'suffix' part of the initial pattern.
- */
- for (int childQuark : directChildren) {
- int matchingQuark;
- try {
- matchingQuark = getQuarkRelative(childQuark, suffixStr);
- } catch (AttributeNotFoundException e) {
- continue;
- }
- quarks.add(matchingQuark);
- }
-
- return quarks;
- }
-
- //--------------------------------------------------------------------------
- // Methods related to insertions in the history
- //--------------------------------------------------------------------------
-
- @Override
- public void modifyAttribute(long t, ITmfStateValue value, int attributeQuark)
- throws TimeRangeException, AttributeNotFoundException,
- StateValueTypeException {
- if (value == null) {
- /*
- * TODO Replace with @NonNull parameter (will require fixing all the
- * state providers!)
- */
- throw new IllegalArgumentException();
- }
- transState.processStateChange(t, value, attributeQuark);
- }
-
- @Override
- public void incrementAttribute(long t, int attributeQuark)
- throws StateValueTypeException, TimeRangeException,
- AttributeNotFoundException {
- ITmfStateValue stateValue = queryOngoingState(attributeQuark);
- int prevValue = 0;
- /* if the attribute was previously null, start counting at 0 */
- if (!stateValue.isNull()) {
- prevValue = stateValue.unboxInt();
- }
- modifyAttribute(t, TmfStateValue.newValueInt(prevValue + 1),
- attributeQuark);
- }
-
- @Override
- public void pushAttribute(long t, ITmfStateValue value, int attributeQuark)
- throws TimeRangeException, AttributeNotFoundException,
- StateValueTypeException {
- int stackDepth;
- int subAttributeQuark;
- ITmfStateValue previousSV = transState.getOngoingStateValue(attributeQuark);
-
- if (previousSV.isNull()) {
- /*
- * If the StateValue was null, this means this is the first time we
- * use this attribute. Leave stackDepth at 0.
- */
- stackDepth = 0;
- } else if (previousSV.getType() == Type.INTEGER) {
- /* Previous value was an integer, all is good, use it */
- stackDepth = previousSV.unboxInt();
- } else {
- /* Previous state of this attribute was another type? Not good! */
- throw new StateValueTypeException(getSSID() + " Quark:" + attributeQuark + ", Type:" + previousSV.getType() + ", Expected:" + Type.INTEGER); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
-
- if (stackDepth >= 100000) {
- /*
- * Limit stackDepth to 100000, to avoid having Attribute Trees grow
- * out of control due to buggy insertions
- */
- String message = " Stack limit reached, not pushing"; //$NON-NLS-1$
- throw new AttributeNotFoundException(getSSID() + " Quark:" + attributeQuark + message); //$NON-NLS-1$
- }
-
- stackDepth++;
- subAttributeQuark = getQuarkRelativeAndAdd(attributeQuark, String.valueOf(stackDepth));
-
- modifyAttribute(t, TmfStateValue.newValueInt(stackDepth), attributeQuark);
- modifyAttribute(t, value, subAttributeQuark);
- }
-
- @Override
- public ITmfStateValue popAttribute(long t, int attributeQuark)
- throws AttributeNotFoundException, TimeRangeException,
- StateValueTypeException {
- /* These are the state values of the stack-attribute itself */
- ITmfStateValue previousSV = transState.getOngoingStateValue(attributeQuark);
-
- if (previousSV.isNull()) {
- /*
- * Trying to pop an empty stack. This often happens at the start of
- * traces, for example when we see a syscall_exit, without having
- * the corresponding syscall_entry in the trace. Just ignore
- * silently.
- */
- return null;
- }
- if (previousSV.getType() != Type.INTEGER) {
- /*
- * The existing value was not an integer (which is expected for
- * stack tops), this doesn't look like a valid stack attribute.
- */
- throw new StateValueTypeException(getSSID() + " Quark:" + attributeQuark + ", Type:" + previousSV.getType() + ", Expected:" + Type.INTEGER); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
-
- int stackDepth = previousSV.unboxInt();
-
- if (stackDepth <= 0) {
- /* This on the other hand should not happen... */
- throw new StateValueTypeException(getSSID() + " Quark:" + attributeQuark + ", Stack depth:" + stackDepth); //$NON-NLS-1$//$NON-NLS-2$
- }
-
- /* The attribute should already exist at this point */
- int subAttributeQuark = getQuarkRelative(attributeQuark, String.valueOf(stackDepth));
- ITmfStateValue poppedValue = queryOngoingState(subAttributeQuark);
-
- /* Update the state value of the stack-attribute */
- ITmfStateValue nextSV;
- if (--stackDepth == 0) {
- /* Store a null state value */
- nextSV = TmfStateValue.nullValue();
- } else {
- nextSV = TmfStateValue.newValueInt(stackDepth);
- }
- modifyAttribute(t, nextSV, attributeQuark);
-
- /* Delete the sub-attribute that contained the user's state value */
- removeAttribute(t, subAttributeQuark);
-
- return poppedValue;
- }
-
- @Override
- public void removeAttribute(long t, int attributeQuark)
- throws TimeRangeException, AttributeNotFoundException {
- if (attributeQuark < 0) {
- throw new IllegalArgumentException();
- }
-
- /*
- * Nullify our children first, recursively. We pass 'false' because we
- * handle the recursion ourselves.
- */
- List<Integer> childAttributes = getSubAttributes(attributeQuark, false);
- for (int childNodeQuark : childAttributes) {
- if (attributeQuark == childNodeQuark) {
- /* Something went very wrong when building out attribute tree */
- throw new IllegalStateException();
- }
- removeAttribute(t, childNodeQuark);
- }
- /* Nullify ourselves */
- try {
- transState.processStateChange(t, TmfStateValue.nullValue(), attributeQuark);
- } catch (StateValueTypeException e) {
- /*
- * Will not happen since we're inserting null values only, but poor
- * compiler has no way of knowing this...
- */
- throw new IllegalStateException(e);
- }
- }
-
- //--------------------------------------------------------------------------
- // "Current" query/update methods
- //--------------------------------------------------------------------------
-
- @Override
- public ITmfStateValue queryOngoingState(int attributeQuark)
- throws AttributeNotFoundException {
- return transState.getOngoingStateValue(attributeQuark);
- }
-
- @Override
- public long getOngoingStartTime(int attribute)
- throws AttributeNotFoundException {
- return transState.getOngoingStartTime(attribute);
- }
-
- @Override
- public void updateOngoingState(ITmfStateValue newValue, int attributeQuark)
- throws AttributeNotFoundException {
- transState.changeOngoingStateValue(attributeQuark, newValue);
- }
-
- /**
- * Modify the whole "ongoing state" (state values + start times). This can
- * be used when "seeking" a state system to a different point in the trace
- * (and restoring the known stateInfo at this location). Use with care!
- *
- * @param newStateIntervals
- * The new List of state values to use as ongoing state info
- */
- protected void replaceOngoingState(@NonNull List<ITmfStateInterval> newStateIntervals) {
- transState.replaceOngoingState(newStateIntervals);
- }
-
- //--------------------------------------------------------------------------
- // Regular query methods (sent to the back-end)
- //--------------------------------------------------------------------------
-
- @Override
- public synchronized List<ITmfStateInterval> queryFullState(long t)
- throws TimeRangeException, StateSystemDisposedException {
- if (isDisposed) {
- throw new StateSystemDisposedException();
- }
-
- final int nbAttr = getNbAttributes();
- List<ITmfStateInterval> stateInfo = new ArrayList<>(nbAttr);
-
- /* Bring the size of the array to the current number of attributes */
- for (int i = 0; i < nbAttr; i++) {
- stateInfo.add(null);
- }
-
- /*
- * If we are currently building the history, also query the "ongoing"
- * states for stuff that might not yet be written to the history.
- */
- if (transState.isActive()) {
- transState.doQuery(stateInfo, t);
- }
-
- /* Query the storage backend */
- backend.doQuery(stateInfo, t);
-
- /*
- * We should have previously inserted an interval for every attribute.
- */
- for (ITmfStateInterval interval : stateInfo) {
- if (interval == null) {
- throw new IllegalStateException("Incoherent interval storage"); //$NON-NLS-1$
- }
- }
- return stateInfo;
- }
-
- @Override
- public ITmfStateInterval querySingleState(long t, int attributeQuark)
- throws AttributeNotFoundException, TimeRangeException,
- StateSystemDisposedException {
- if (isDisposed) {
- throw new StateSystemDisposedException();
- }
-
- ITmfStateInterval ret = transState.getIntervalAt(t, attributeQuark);
- if (ret == null) {
- /*
- * The transient state did not have the information, let's look into
- * the backend next.
- */
- ret = backend.doSingularQuery(t, attributeQuark);
- }
-
- if (ret == null) {
- /*
- * If we did our job correctly, there should be intervals for every
- * possible attribute, over all the valid time range.
- */
- throw new IllegalStateException("Incoherent interval storage"); //$NON-NLS-1$
- }
- return ret;
- }
-
- //--------------------------------------------------------------------------
- // Debug methods
- //--------------------------------------------------------------------------
-
- static void logMissingInterval(int attribute, long timestamp) {
- Activator.getDefault().logInfo("No data found in history for attribute " + //$NON-NLS-1$
- attribute + " at time " + timestamp + //$NON-NLS-1$
- ", returning dummy interval"); //$NON-NLS-1$
- }
-
- /**
- * Print out the contents of the inner structures.
- *
- * @param writer
- * The PrintWriter in which to print the output
- */
- public void debugPrint(@NonNull PrintWriter writer) {
- getAttributeTree().debugPrint(writer);
- transState.debugPrint(writer);
- backend.debugPrint(writer);
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson
- * Copyright (c) 2010, 2011 École Polytechnique de Montréal
- * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- * Patrick Tasse - Add message to exceptions
- *******************************************************************************/
-
-package org.eclipse.tracecompass.internal.statesystem.core;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
-import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
-import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
-import org.eclipse.tracecompass.statesystem.core.interval.TmfStateInterval;
-import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
-import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue.Type;
-import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
-
-/**
- * The Transient State is used to build intervals from punctual state changes.
- * It contains a "state info" vector similar to the "current state", except here
- * we also record the start time of every state stored in it.
- *
- * We can then build {@link ITmfStateInterval}'s, to be inserted in a
- * {@link IStateHistoryBackend} when we detect state changes : the "start time"
- * of the interval will be the recorded time we have here, and the "end time"
- * will be the timestamp of the new state-changing event we just read.
- *
- * @author Alexandre Montplaisir
- */
-@NonNullByDefault
-public class TransientState {
-
- /* Indicates where to insert state changes that we generate */
- private final IStateHistoryBackend fBackend;
-
- private final ReentrantReadWriteLock fRWLock = new ReentrantReadWriteLock(false);
-
- private volatile boolean fIsActive;
- private volatile long fLatestTime;
-
- /* A method accessing these arrays will have to go through the lock */
- private List<ITmfStateValue> fOngoingStateInfo;
- private List<Long> fOngoingStateStartTimes;
- private List<Type> fStateValueTypes;
-
- /**
- * Constructor
- *
- * @param backend
- * The back-end in which to insert the generated state intervals
- */
- public TransientState(IStateHistoryBackend backend) {
- fBackend = backend;
- fIsActive = true;
- fOngoingStateInfo = new ArrayList<>();
- fOngoingStateStartTimes = new ArrayList<>();
- fStateValueTypes = new ArrayList<>();
-
- fLatestTime = backend.getStartTime();
- }
-
- /**
- * Get the latest time we have seen so far.
- *
- * @return The latest time seen in the transient state
- */
- public long getLatestTime() {
- return fLatestTime;
- }
-
- /**
- * Retrieve the ongoing state value for a given index (attribute quark).
- *
- * @param quark
- * The quark of the attribute to look for
- * @return The corresponding state value
- * @throws AttributeNotFoundException
- * If the quark is invalid
- */
- public ITmfStateValue getOngoingStateValue(int quark) throws AttributeNotFoundException {
- fRWLock.readLock().lock();
- try {
- checkValidAttribute(quark);
- ITmfStateValue ret = fOngoingStateInfo.get(quark);
- if (ret == null) {
- throw new IllegalStateException("Null interval stored in transient state"); //$NON-NLS-1$
- }
- return ret;
- } finally {
- fRWLock.readLock().unlock();
- }
- }
-
- /**
- * Retrieve the start time of the state in which the given attribute is in.
- *
- * @param quark
- * The quark of the attribute to look for
- * @return The start time of the current state for this attribute
- * @throws AttributeNotFoundException
- * If the quark is invalid
- */
- public long getOngoingStartTime(int quark) throws AttributeNotFoundException {
- fRWLock.readLock().lock();
- try {
- checkValidAttribute(quark);
- return fOngoingStateStartTimes.get(quark);
- } finally {
- fRWLock.readLock().unlock();
- }
- }
-
- /**
- * Modify the current state for a given attribute. This will not update the
- * "ongoing state start time" in any way, so be careful when using this.
- *
- * @param quark
- * The quark of the attribute to modify
- * @param newValue
- * The state value the attribute should have
- * @throws AttributeNotFoundException
- * If the quark is invalid
- */
- public void changeOngoingStateValue(int quark, ITmfStateValue newValue)
- throws AttributeNotFoundException {
- fRWLock.writeLock().lock();
- try {
- checkValidAttribute(quark);
- fOngoingStateInfo.set(quark, newValue);
- } finally {
- fRWLock.writeLock().unlock();
- }
- }
-
- /**
- * Convenience method to return the "ongoing" value for a given attribute as
- * a dummy interval whose end time = the current latest time.
- *
- * @param quark
- * The quark of the attribute
- * @return An interval representing the current state (but whose end time is
- * the current one, and probably not the "final" one)
- * @throws AttributeNotFoundException
- * If the quark is invalid
- */
- public ITmfStateInterval getOngoingInterval(int quark) throws AttributeNotFoundException {
- fRWLock.readLock().lock();
- try {
- checkValidAttribute(quark);
- return new TmfStateInterval(fOngoingStateStartTimes.get(quark), fLatestTime,
- quark, fOngoingStateInfo.get(quark));
- } finally {
- fRWLock.readLock().unlock();
- }
- }
-
- /**
- * Try to get the state interval valid for time/quark, if it is present in
- * this transient state. If it is not (for example, a new value is active
- * since after the specified timestamp) then null will be returned.
- *
- * @param time
- * The timestamp to look for
- * @param quark
- * The quark of the attribute to look for
- * @return The corresponding TmfStateInterval object if we could find it in
- * this transient state, or null if we couldn't.
- */
- public @Nullable ITmfStateInterval getIntervalAt(long time, int quark) {
- fRWLock.readLock().lock();
- try {
- checkValidAttribute(quark);
- if (!isActive() || time < fOngoingStateStartTimes.get(quark)) {
- return null;
- }
- return new TmfStateInterval(fOngoingStateStartTimes.get(quark),
- fLatestTime, quark, fOngoingStateInfo.get(quark));
- } catch (AttributeNotFoundException e) {
- return null;
- } finally {
- fRWLock.readLock().unlock();
- }
- }
-
- private void checkValidAttribute(int quark) throws AttributeNotFoundException {
- if (quark > fOngoingStateInfo.size() - 1 || quark < 0) {
- throw new AttributeNotFoundException(fBackend.getSSID() + " Quark:" + quark); //$NON-NLS-1$
- }
- }
-
- /**
- * More advanced version of {@link #changeOngoingStateValue}. Replaces the
- * complete ongoingStateInfo in one go, and updates the
- * ongoingStateStartTimes and #stateValuesTypes accordingly. BE VERY CAREFUL
- * WITH THIS!
- *
- * @param newStateIntervals
- * The List of intervals that will represent the new
- * "ongoing state". Their end times don't matter, we will only
- * check their value and start times.
- */
- public void replaceOngoingState(List<ITmfStateInterval> newStateIntervals) {
- final int size = newStateIntervals.size();
-
- fRWLock.writeLock().lock();
- try {
- fOngoingStateInfo = new ArrayList<>(size);
- fOngoingStateStartTimes = new ArrayList<>(size);
- fStateValueTypes = new ArrayList<>(size);
-
- for (ITmfStateInterval interval : newStateIntervals) {
- fOngoingStateInfo.add(interval.getStateValue());
- fOngoingStateStartTimes.add(interval.getStartTime());
- fStateValueTypes.add(interval.getStateValue().getType());
- }
- } finally {
- fRWLock.writeLock().unlock();
- }
- }
-
- /**
- * Add an "empty line" to both "ongoing..." vectors. This is needed so the
- * Ongoing... tables can stay in sync with the number of attributes in the
- * attribute tree, namely when we add sub-path attributes.
- */
- public void addEmptyEntry() {
- fRWLock.writeLock().lock();
- try {
- /*
- * Since this is a new attribute, we suppose it was in the
- * "null state" since the beginning (so we can have intervals
- * covering for all timestamps). A null interval will then get added
- * at the first state change.
- */
- fOngoingStateInfo.add(TmfStateValue.nullValue());
- fStateValueTypes.add(Type.NULL);
-
- fOngoingStateStartTimes.add(fBackend.getStartTime());
- } finally {
- fRWLock.writeLock().unlock();
- }
- }
-
- /**
- * Process a state change to be inserted in the history.
- *
- * @param eventTime
- * The timestamp associated with this state change
- * @param value
- * The new StateValue associated to this attribute
- * @param quark
- * The quark of the attribute that is being modified
- * @throws TimeRangeException
- * If 'eventTime' is invalid
- * @throws AttributeNotFoundException
- * IF 'quark' does not represent an existing attribute
- * @throws StateValueTypeException
- * If the state value to be inserted is of a different type of
- * what was inserted so far for this attribute.
- */
- public void processStateChange(long eventTime, ITmfStateValue value, int quark)
- throws TimeRangeException, AttributeNotFoundException, StateValueTypeException {
- if (!this.fIsActive) {
- return;
- }
-
- fRWLock.writeLock().lock();
- try {
- Type expectedSvType = fStateValueTypes.get(quark);
- checkValidAttribute(quark);
-
- /*
- * Make sure the state value type we're inserting is the same as the
- * one registered for this attribute.
- */
- if (expectedSvType == Type.NULL) {
- /*
- * The value hasn't been used yet, set it to the value we're
- * currently inserting (which might be null/-1 again).
- */
- fStateValueTypes.set(quark, value.getType());
- } else if ((value.getType() != Type.NULL) && (value.getType() != expectedSvType)) {
- /*
- * We authorize inserting null values in any type of attribute,
- * but for every other types, it needs to match our
- * expectations!
- */
- throw new StateValueTypeException(fBackend.getSSID() + " Quark:" + quark + ", Type:" + value.getType() + ", Expected:" + expectedSvType); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
-
- if (fOngoingStateInfo.get(quark).equals(value)) {
- /*
- * This is the case where the new value and the one already
- * present in the Builder are the same. We do not need to create
- * an interval, we'll just keep the current one going.
- */
- return;
- }
-
- if (fOngoingStateStartTimes.get(quark) < eventTime) {
- /*
- * These two conditions are necessary to create an interval and
- * update ongoingStateInfo.
- */
- fBackend.insertPastState(fOngoingStateStartTimes.get(quark),
- eventTime - 1, /* End Time */
- quark, /* attribute quark */
- fOngoingStateInfo.get(quark)); /* StateValue */
-
- fOngoingStateStartTimes.set(quark, eventTime);
- }
- fOngoingStateInfo.set(quark, value);
-
- /* Update the Transient State's lastestTime, if needed */
- if (fLatestTime < eventTime) {
- fLatestTime = eventTime;
- }
-
- } finally {
- fRWLock.writeLock().unlock();
- }
- }
-
- /**
- * Run a "get state at time" query on the Transient State only.
- *
- * @param stateInfo
- * The stateInfo object in which we will put our relevant
- * information
- * @param t
- * The requested timestamp
- */
- public void doQuery(List<ITmfStateInterval> stateInfo, long t) {
- fRWLock.readLock().lock();
- try {
- if (!this.fIsActive) {
- return;
- }
- if (stateInfo.size() > fOngoingStateInfo.size()) {
- throw new IllegalArgumentException();
- }
-
- for (int i = 0; i < stateInfo.size(); i++) {
- /*
- * We build a dummy interval whose end time =
- * "current transient state end time" to put in the answer to
- * the query.
- */
- final ITmfStateInterval interval = getIntervalAt(t, i);
- if (interval != null) {
- stateInfo.set(i, interval);
- }
- }
- } finally {
- fRWLock.readLock().unlock();
- }
- }
-
- /**
- * Close off the Transient State, used for example when we are done reading
- * a static trace file. All the information currently contained in it will
- * be converted to intervals and "flushed" to the state history.
- *
- * @param endTime
- * The timestamp to use as end time for the state history (since
- * it may be different than the timestamp of the last state
- * change)
- */
- public void closeTransientState(long endTime) {
- if (!this.fIsActive) {
- return;
- }
-
- fRWLock.writeLock().lock();
- try {
- for (int i = 0; i < fOngoingStateInfo.size(); i++) {
- if (fOngoingStateStartTimes.get(i) > endTime) {
- /*
- * Handle the cases where trace end > timestamp of last
- * state change. This can happen when inserting "future"
- * changes.
- */
- continue;
- }
- try {
- fBackend.insertPastState(fOngoingStateStartTimes.get(i),
- endTime, /* End Time */
- i, /* attribute quark */
- fOngoingStateInfo.get(i)); /* StateValue */
-
- } catch (TimeRangeException e) {
- /*
- * This shouldn't happen, since we control where the
- * interval's start time comes from
- */
- throw new IllegalStateException(e);
- }
- }
-
- fOngoingStateInfo.clear();
- fOngoingStateStartTimes.clear();
- this.fIsActive = false;
-
- } finally {
- fRWLock.writeLock().unlock();
- }
- }
-
- /**
- * Simply returns if this Transient State is currently being used or not
- *
- * @return True if this transient state is active
- */
- public boolean isActive() {
- return this.fIsActive;
- }
-
- /**
- * Mark this transient state as inactive
- */
- public void setInactive() {
- fIsActive = false;
- }
-
- /**
- * Debugging method that prints the contents of the transient state
- *
- * @param writer
- * The writer to which the output should be written
- */
- public void debugPrint(PrintWriter writer) {
- /* Only used for debugging, shouldn't be externalized */
- writer.println("------------------------------"); //$NON-NLS-1$
- writer.println("Info stored in the Builder:"); //$NON-NLS-1$
- if (!this.fIsActive) {
- writer.println("Builder is currently inactive"); //$NON-NLS-1$
- writer.println('\n');
- return;
- }
- writer.println("\nAttribute\tStateValue\tValid since time"); //$NON-NLS-1$
- for (int i = 0; i < fOngoingStateInfo.size(); i++) {
- writer.format("%d\t\t", i); //$NON-NLS-1$
- writer.print(fOngoingStateInfo.get(i).toString() + "\t\t"); //$NON-NLS-1$
- writer.println(fOngoingStateStartTimes.get(i).toString());
- }
- writer.println('\n');
- return;
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2013, 2015 Ericsson
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- * Matthew Khouzam - Modified to use a TreeSet
- * Patrick Tasse - Add message to exceptions
- ******************************************************************************/
-
-package org.eclipse.tracecompass.internal.statesystem.core.backend;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.PrintWriter;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
-import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
-import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
-import org.eclipse.tracecompass.statesystem.core.interval.TmfStateInterval;
-import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
-
-/**
- * State history back-end that stores its intervals in RAM only. It cannot be
- * saved to disk, which means we need to rebuild it every time we re-open a
- * trace. But it's relatively quick to build, so this shouldn't be a problem in
- * most cases.
- *
- * This should only be used with very small state histories (and/or, very small
- * traces). Since it's stored in standard Collections, it's limited to 2^31
- * intervals.
- *
- * @author Alexandre Montplaisir
- */
-public class InMemoryBackend implements IStateHistoryBackend {
-
- /**
- * We need to compare the end time and the attribute, because we can have 2
- * intervals with the same end time (for different attributes). And TreeSet
- * needs a unique "key" per element.
- */
- private static final Comparator<ITmfStateInterval> END_COMPARATOR =
- new Comparator<ITmfStateInterval>() {
- @Override
- public int compare(ITmfStateInterval o1, ITmfStateInterval o2) {
- final long e1 = o1.getEndTime();
- final long e2 = o2.getEndTime();
- final int a1 = o1.getAttribute();
- final int a2 = o2.getAttribute();
- if (e1 < e2) {
- return -1;
- } else if (e1 > e2) {
- return 1;
- } else if (a1 < a2) {
- return -1;
- } else if (a1 > a2) {
- return 1;
- } else {
- return 0;
- }
- }
-
- };
-
- private final @NonNull String ssid;
- private final TreeSet<ITmfStateInterval> intervals;
- private final long startTime;
-
- private volatile long latestTime;
-
- /**
- * Constructor
- *
- * @param ssid
- * The state system's ID
- * @param startTime
- * The start time of this interval store
- */
- public InMemoryBackend(@NonNull String ssid, long startTime) {
- this.ssid = ssid;
- this.startTime = startTime;
- this.latestTime = startTime;
- this.intervals = new TreeSet<>(END_COMPARATOR);
- }
-
- @Override
- public String getSSID() {
- return ssid;
- }
-
- @Override
- public long getStartTime() {
- return startTime;
- }
-
- @Override
- public long getEndTime() {
- return latestTime;
- }
-
- @Override
- public void insertPastState(long stateStartTime, long stateEndTime,
- int quark, ITmfStateValue value) throws TimeRangeException {
- /* Make sure the passed start/end times make sense */
- if (stateStartTime > stateEndTime || stateStartTime < startTime) {
- throw new TimeRangeException(ssid + " Interval Start:" + stateStartTime + ", Interval End:" + stateEndTime + ", Backend Start:" + startTime); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
-
- ITmfStateInterval interval = new TmfStateInterval(stateStartTime, stateEndTime, quark, value);
-
- /* Add the interval into the tree */
- synchronized (intervals) {
- intervals.add(interval);
- }
-
- /* Update the "latest seen time" */
- if (stateEndTime > latestTime) {
- latestTime = stateEndTime;
- }
- }
-
- @Override
- public void doQuery(List<ITmfStateInterval> currentStateInfo, long t)
- throws TimeRangeException {
- if (!checkValidTime(t)) {
- throw new TimeRangeException(ssid + " Time:" + t + ", Start:" + startTime + ", End:" + latestTime); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
-
- /*
- * The intervals are sorted by end time, so we can binary search to get
- * the first possible interval, then only compare their start times.
- */
- synchronized (intervals) {
- Iterator<ITmfStateInterval> iter = serachforEndTime(intervals, t);
- for (int modCount = 0; iter.hasNext() && modCount < currentStateInfo.size();) {
- ITmfStateInterval entry = iter.next();
- final long entryStartTime = entry.getStartTime();
- if (entryStartTime <= t) {
- /* Add this interval to the returned values */
- currentStateInfo.set(entry.getAttribute(), entry);
- modCount++;
- }
- }
- }
- }
-
- @Override
- public ITmfStateInterval doSingularQuery(long t, int attributeQuark)
- throws TimeRangeException, AttributeNotFoundException {
- if (!checkValidTime(t)) {
- throw new TimeRangeException(ssid + " Time:" + t + ", Start:" + startTime + ", End:" + latestTime); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
-
- /*
- * The intervals are sorted by end time, so we can binary search to get
- * the first possible interval, then only compare their start times.
- */
- synchronized (intervals) {
- Iterator<ITmfStateInterval> iter = serachforEndTime(intervals, t);
- while (iter.hasNext()) {
- ITmfStateInterval entry = iter.next();
- final boolean attributeMatches = (entry.getAttribute() == attributeQuark);
- final long entryStartTime = entry.getStartTime();
- if (attributeMatches) {
- if (entryStartTime <= t) {
- /* This is the droid we are looking for */
- return entry;
- }
- }
- }
- }
- throw new AttributeNotFoundException(ssid + " Quark:" + attributeQuark); //$NON-NLS-1$
- }
-
- private boolean checkValidTime(long t) {
- if (t >= startTime && t <= latestTime) {
- return true;
- }
- return false;
- }
-
- @Override
- public void finishedBuilding(long endTime) throws TimeRangeException {
- /* Nothing to do */
- }
-
- @Override
- public FileInputStream supplyAttributeTreeReader() {
- /* Saving to disk not supported */
- return null;
- }
-
- @Override
- public File supplyAttributeTreeWriterFile() {
- /* Saving to disk not supported */
- return null;
- }
-
- @Override
- public long supplyAttributeTreeWriterFilePosition() {
- /* Saving to disk not supported */
- return -1;
- }
-
- @Override
- public void removeFiles() {
- /* Nothing to do */
- }
-
- @Override
- public void dispose() {
- /* Nothing to do */
- }
-
- @Override
- public void debugPrint(PrintWriter writer) {
- synchronized (intervals) {
- writer.println(intervals.toString());
- }
- }
-
- private static Iterator<ITmfStateInterval> serachforEndTime(TreeSet<ITmfStateInterval> tree, long time) {
- ITmfStateInterval dummyInterval = new TmfStateInterval(-1, time, -1, null);
- ITmfStateInterval myInterval = tree.lower(dummyInterval);
- if (myInterval == null) {
- return tree.iterator();
- }
- final SortedSet<ITmfStateInterval> tailSet = tree.tailSet(myInterval);
- Iterator<ITmfStateInterval> retVal = tailSet.iterator();
- retVal.next();
- return retVal;
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2013, 2014 Ericsson
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.tracecompass.internal.statesystem.core.backend;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.PrintWriter;
-import java.util.List;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
-import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
-import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
-
-/**
- * An implement of a state history back-end to simply discards *all* the
- * intervals it receives. Obviously, no queries can be done on it. It is useful
- * for using with a StateSystem on which you will only want to do "ongoing"
- * requests.
- *
- * @author Alexandre Montplaisir
- */
-public class NullBackend implements IStateHistoryBackend {
-
- private final @NonNull String ssid;
-
- /**
- * Constructor
- *
- * @param ssid
- * The state system's id
- */
- public NullBackend(@NonNull String ssid) {
- this.ssid = ssid;
- }
-
- @Override
- public String getSSID() {
- return ssid;
- }
-
- @Override
- public long getStartTime() {
- return 0;
- }
-
- @Override
- public long getEndTime() {
- return 0;
- }
-
- /**
- * The interval will be discarded when using a null backend.
- */
- @Override
- public void insertPastState(long stateStartTime, long stateEndTime,
- int quark, ITmfStateValue value) {
- /* The interval is always discarded. */
- }
-
- @Override
- public void finishedBuilding(long endTime) {
- /* Nothing to do */
- }
-
- @Override
- public FileInputStream supplyAttributeTreeReader() {
- return null;
- }
-
- @Override
- public File supplyAttributeTreeWriterFile() {
- return null;
- }
-
- @Override
- public long supplyAttributeTreeWriterFilePosition() {
- return -1;
- }
-
- @Override
- public void removeFiles() {
- /* Nothing to do */
- }
-
- @Override
- public void dispose() {
- /* Nothing to do */
- }
-
- /**
- * Null back-ends cannot run queries. Nothing will be put in
- * currentStateInfo.
- */
- @Override
- public void doQuery(List<ITmfStateInterval> currentStateInfo, long t) {
- /* Cannot do past queries */
- }
-
- /**
- * Null back-ends cannot run queries. 'null' will be returned.
- *
- * @return Always returns null.
- */
- @Override
- public ITmfStateInterval doSingularQuery(long t, int attributeQuark) {
- /* Cannot do past queries */
- return null;
- }
-
- @Override
- public void debugPrint(PrintWriter writer) {
- writer.println("Null history backend"); //$NON-NLS-1$
- }
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2010, 2014 Ericsson, École Polytechnique de Montréal, and others
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- * Florian Wininger - Add Extension and Leaf Node
- *******************************************************************************/
-
-package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;
-
-import java.nio.ByteBuffer;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-/**
- * A Core node is a first-level node of a History Tree which is not a leaf node.
- *
- * It extends HTNode by adding support for child nodes, and also extensions.
- *
- * @author Alexandre Montplaisir
- */
-public final class CoreNode extends HTNode {
-
- /** Number of bytes in a int */
- private static final int SIZE_INT = 4;
-
- /** Number of bytes in a long */
- private static final int SIZE_LONG = 8;
-
- /** Nb. of children this node has */
- private int nbChildren;
-
- /** Seq. numbers of the children nodes (size = MAX_NB_CHILDREN) */
- private int[] children;
-
- /** Start times of each of the children (size = MAX_NB_CHILDREN) */
- private long[] childStart;
-
- /** Seq number of this node's extension. -1 if none */
- private volatile int extension = -1;
-
- /**
- * Lock used to gate the accesses to the children arrays. Meant to be a
- * different lock from the one in {@link HTNode}.
- */
- private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(false);
-
- /**
- * Initial constructor. Use this to initialize a new EMPTY node.
- *
- * @param config
- * Configuration of the History Tree
- * @param seqNumber
- * The (unique) sequence number assigned to this particular node
- * @param parentSeqNumber
- * The sequence number of this node's parent node
- * @param start
- * The earliest timestamp stored in this node
- */
- public CoreNode(HTConfig config, int seqNumber, int parentSeqNumber,
- long start) {
- super(config, seqNumber, parentSeqNumber, start);
- this.nbChildren = 0;
- int size = config.getMaxChildren();
-
- /*
- * We instantiate the two following arrays at full size right away,
- * since we want to reserve that space in the node's header.
- * "this.nbChildren" will tell us how many relevant entries there are in
- * those tables.
- */
- this.children = new int[size];
- this.childStart = new long[size];
- }
-
- @Override
- protected void readSpecificHeader(ByteBuffer buffer) {
- int size = getConfig().getMaxChildren();
-
- extension = buffer.getInt();
- nbChildren = buffer.getInt();
-
- children = new int[size];
- for (int i = 0; i < nbChildren; i++) {
- children[i] = buffer.getInt();
- }
- for (int i = nbChildren; i < size; i++) {
- buffer.getInt();
- }
-
- this.childStart = new long[size];
- for (int i = 0; i < nbChildren; i++) {
- childStart[i] = buffer.getLong();
- }
- for (int i = nbChildren; i < size; i++) {
- buffer.getLong();
- }
- }
-
- @Override
- protected void writeSpecificHeader(ByteBuffer buffer) {
- int size = getConfig().getMaxChildren();
-
- buffer.putInt(extension);
- buffer.putInt(nbChildren);
-
- /* Write the "children's seq number" array */
- for (int i = 0; i < nbChildren; i++) {
- buffer.putInt(children[i]);
- }
- for (int i = nbChildren; i < size; i++) {
- buffer.putInt(0);
- }
-
- /* Write the "children's start times" array */
- for (int i = 0; i < nbChildren; i++) {
- buffer.putLong(childStart[i]);
- }
- for (int i = nbChildren; i < size; i++) {
- buffer.putLong(0);
- }
- }
-
- /**
- * Return the number of child nodes this node has.
- *
- * @return The number of child nodes
- */
- public int getNbChildren() {
- rwl.readLock().lock();
- int ret = nbChildren;
- rwl.readLock().unlock();
- return ret;
- }
-
- /**
- * Get the child node corresponding to the specified index
- *
- * @param index The index of the child to lookup
- * @return The child node
- */
- public int getChild(int index) {
- rwl.readLock().lock();
- try {
- return children[index];
- } finally {
- rwl.readLock().unlock();
- }
- }
-
- /**
- * Get the latest (right-most) child node of this node.
- *
- * @return The latest child node
- */
- public int getLatestChild() {
- rwl.readLock().lock();
- try {
- return children[nbChildren - 1];
- } finally {
- rwl.readLock().unlock();
- }
- }
-
- /**
- * Get the start time of the specified child node.
- *
- * @param index
- * The index of the child node
- * @return The start time of the that child node.
- */
- public long getChildStart(int index) {
- rwl.readLock().lock();
- try {
- return childStart[index];
- } finally {
- rwl.readLock().unlock();
- }
- }
-
- /**
- * Get the start time of the latest (right-most) child node.
- *
- * @return The start time of the latest child
- */
- public long getLatestChildStart() {
- rwl.readLock().lock();
- try {
- return childStart[nbChildren - 1];
- } finally {
- rwl.readLock().unlock();
- }
- }
-
- /**
- * Get the sequence number of the extension to this node (if there is one).
- *
- * @return The sequence number of the extended node. '-1' is returned if
- * there is no extension node.
- */
- public int getExtensionSequenceNumber() {
- return extension;
- }
-
- /**
- * Tell this node that it has a new child (Congrats!)
- *
- * @param childNode
- * The SHTNode object of the new child
- */
- public void linkNewChild(HTNode childNode) {
- rwl.writeLock().lock();
- try {
- assert (nbChildren < getConfig().getMaxChildren());
-
- children[nbChildren] = childNode.getSequenceNumber();
- childStart[nbChildren] = childNode.getNodeStart();
- nbChildren++;
-
- } finally {
- rwl.writeLock().unlock();
- }
- }
-
- @Override
- public NodeType getNodeType() {
- return NodeType.CORE;
- }
-
- @Override
- protected int getSpecificHeaderSize() {
- int maxChildren = getConfig().getMaxChildren();
- int specificSize =
- SIZE_INT /* 1x int (extension node) */
- + SIZE_INT /* 1x int (nbChildren) */
-
- /* MAX_NB * int ('children' table) */
- + SIZE_INT * maxChildren
-
- /* MAX_NB * Timevalue ('childStart' table) */
- + SIZE_LONG * maxChildren;
-
- return specificSize;
- }
-
- @Override
- public String toStringSpecific() {
- /* Only used for debugging, shouldn't be externalized */
- return "Core Node, " + nbChildren + " children, "; //$NON-NLS-1$ //$NON-NLS-2$
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2014 Ericsson
- * Copyright (c) 2010, 2011 École Polytechnique de Montréal
- * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- *******************************************************************************/
-
-package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;
-
-import java.io.File;
-
-/**
- * Configuration object for the {@link HistoryTree}.
- *
- * @author Alexandre Montplaisir
- */
-public final class HTConfig {
-
- private static final int DEFAULT_BLOCKSIZE = 64 * 1024;
- private static final int DEFAULT_MAXCHILDREN = 50;
-
- private final File stateFile;
- private final int blockSize;
- private final int maxChildren;
- private final int providerVersion;
- private final long treeStart;
-
- /**
- * Full constructor.
- *
- * @param newStateFile
- * The name of the history file
- * @param blockSize
- * The size of each "block" on disk. One node will always fit in
- * one block.
- * @param maxChildren
- * The maximum number of children allowed per core (non-leaf)
- * node.
- * @param providerVersion
- * The version of the state provider. If a file already exists,
- * and their versions match, the history file will not be rebuilt
- * uselessly.
- * @param startTime
- * The start time of the history
- */
- public HTConfig(File newStateFile, int blockSize, int maxChildren,
- int providerVersion, long startTime) {
- this.stateFile = newStateFile;
- this.blockSize = blockSize;
- this.maxChildren = maxChildren;
- this.providerVersion = providerVersion;
- this.treeStart = startTime;
- }
-
- /**
- * Version of the constructor using default values for 'blockSize' and
- * 'maxChildren'.
- *
- * @param newStateFile
- * The name of the history file
- * @param providerVersion
- * The version of the state provider. If a file already exists,
- * and their versions match, the history file will not be rebuilt
- * uselessly.
- * @param startTime
- * The start time of the history
- */
- public HTConfig(File newStateFile, int providerVersion, long startTime) {
- this(newStateFile, DEFAULT_BLOCKSIZE, DEFAULT_MAXCHILDREN, providerVersion, startTime);
- }
-
- // ------------------------------------------------------------------------
- // Getters
- // ------------------------------------------------------------------------
-
- /**
- * Get the history file.
- *
- * @return The history file
- */
- public File getStateFile() {
- return stateFile;
- }
-
- /**
- * Get the configure block size.
- *
- * @return The block size
- */
- public int getBlockSize() {
- return blockSize;
- }
-
- /**
- * Get the maximum amount of children allowed.
- *
- * @return The maximum amount of children
- */
- public int getMaxChildren() {
- return maxChildren;
- }
-
- /**
- * Get the state provider's version.
- *
- * @return The state provider's version
- */
- public int getProviderVersion() {
- return providerVersion;
- }
-
- /**
- * Get the start time of the history
- *
- * @return The start time
- */
- public long getTreeStart() {
- return treeStart;
- }
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson, École Polytechnique de Montréal
- * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- * Florian Wininger - Allow to change the size of a interval
- * Patrick Tasse - Add message to exceptions
- *******************************************************************************/
-
-package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
-import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
-import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
-import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
-
-/**
- * The interval component, which will be contained in a node of the History
- * Tree.
- *
- * @author Alexandre Montplaisir
- */
-public final class HTInterval implements ITmfStateInterval, Comparable<HTInterval> {
-
- private static final String errMsg = "Invalid interval data. Maybe your file is corrupt?"; //$NON-NLS-1$
-
- /**
- * Size of an entry in the data section.
- *
- * <pre>
- * 16 2 x Timevalue/long (interval start + end)
- * + 4 int (key)
- * + 1 byte (type)
- * + 4 int (valueOffset)
- * </pre>
- */
- private static final int DATA_ENTRY_SIZE = 25;
-
- /* 'Byte' equivalent for state values types */
- private static final byte TYPE_NULL = -1;
- private static final byte TYPE_INTEGER = 0;
- private static final byte TYPE_STRING = 1;
- private static final byte TYPE_LONG = 2;
- private static final byte TYPE_DOUBLE = 3;
-
- /* String entry sizes of different state values */
- private static final int NO_ENTRY_SIZE = 0;
- private static final int LONG_ENTRY_SIZE = 8;
- private static final int DOUBLE_ENTRY_SIZE = 8;
- // sizes of string values depend on the string itself
-
- private final long start;
- private final long end;
- private final int attribute;
- private final TmfStateValue sv;
-
- /*
- * Size of the strings section entry used by this interval (= 0 if not used)
- */
- private final int stringsEntrySize;
-
- /**
- * Standard constructor
- *
- * @param intervalStart
- * Start time of the interval
- * @param intervalEnd
- * End time of the interval
- * @param attribute
- * Attribute (quark) to which the state represented by this
- * interval belongs
- * @param value
- * State value represented by this interval
- * @throws TimeRangeException
- * If the start time or end time are invalid
- */
- public HTInterval(long intervalStart, long intervalEnd, int attribute,
- TmfStateValue value) throws TimeRangeException {
- if (intervalStart > intervalEnd) {
- throw new TimeRangeException("Start:" + intervalStart + ", End:" + intervalEnd); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- this.start = intervalStart;
- this.end = intervalEnd;
- this.attribute = attribute;
- this.sv = value;
- this.stringsEntrySize = computeStringsEntrySize();
- }
-
- /**
- * "Faster" constructor for inner use only. When we build an interval when
- * reading it from disk (with {@link #readFrom}), we already know the size
- * of the strings entry, so there is no need to call
- * {@link #computeStringsEntrySize()} and do an extra copy.
- */
- private HTInterval(long intervalStart, long intervalEnd, int attribute,
- TmfStateValue value, int size) throws TimeRangeException {
- if (intervalStart > intervalEnd) {
- throw new TimeRangeException("Start:" + intervalStart + ", End:" + intervalEnd); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- this.start = intervalStart;
- this.end = intervalEnd;
- this.attribute = attribute;
- this.sv = value;
- this.stringsEntrySize = size;
- }
-
- /**
- * Reader factory method. Builds the interval using an already-allocated
- * ByteBuffer, which normally comes from a NIO FileChannel.
- *
- * @param buffer
- * The ByteBuffer from which to read the information
- * @return The interval object
- * @throws IOException
- * If there was an error reading from the buffer
- */
- public static final HTInterval readFrom(ByteBuffer buffer) throws IOException {
- HTInterval interval;
- long intervalStart, intervalEnd;
- int attribute;
- TmfStateValue value;
- int valueOrOffset, valueSize, res;
- byte valueType;
- byte array[];
-
- /* Read the Data Section entry */
- intervalStart = buffer.getLong();
- intervalEnd = buffer.getLong();
- attribute = buffer.getInt();
-
- /* Read the 'type' of the value, then react accordingly */
- valueType = buffer.get();
- valueOrOffset = buffer.getInt();
- switch (valueType) {
-
- case TYPE_NULL:
- value = TmfStateValue.nullValue();
- valueSize = NO_ENTRY_SIZE;
- break;
-
- case TYPE_INTEGER:
- /* "ValueOrOffset" is the straight value */
- value = TmfStateValue.newValueInt(valueOrOffset);
- valueSize = NO_ENTRY_SIZE;
- break;
-
- case TYPE_STRING:
- /* Go read the matching entry in the Strings section of the block */
- buffer.mark();
- buffer.position(valueOrOffset);
-
- /* the first byte = the size to read */
- valueSize = buffer.get();
-
- /*
- * Careful though, 'valueSize' is the total size of the entry,
- * including the 'size' byte at the start and end (0'ed) byte at the
- * end. Here we want 'array' to only contain the real payload of the
- * value.
- */
- array = new byte[valueSize - 2];
- buffer.get(array);
- value = TmfStateValue.newValueString(new String(array));
-
- /* Confirm the 0'ed byte at the end */
- res = buffer.get();
- if (res != 0) {
- throw new IOException(errMsg);
- }
-
- /*
- * Restore the file pointer's position (so we can read the next
- * interval)
- */
- buffer.reset();
- break;
-
- case TYPE_LONG:
- /* Go read the matching entry in the Strings section of the block */
- buffer.mark();
- buffer.position(valueOrOffset);
- value = TmfStateValue.newValueLong(buffer.getLong());
- valueSize = LONG_ENTRY_SIZE;
-
- /*
- * Restore the file pointer's position (so we can read the next
- * interval)
- */
- buffer.reset();
- break;
-
- case TYPE_DOUBLE:
- /* Go read the matching entry in the Strings section of the block */
- buffer.mark();
- buffer.position(valueOrOffset);
- value = TmfStateValue.newValueDouble(buffer.getDouble());
- valueSize = DOUBLE_ENTRY_SIZE;
-
- /*
- * Restore the file pointer's position (so we can read the next
- * interval)
- */
- buffer.reset();
- break;
-
- default:
- /* Unknown data, better to not make anything up... */
- throw new IOException(errMsg);
- }
-
- try {
- interval = new HTInterval(intervalStart, intervalEnd, attribute, value, valueSize);
- } catch (TimeRangeException e) {
- throw new IOException(errMsg);
- }
- return interval;
- }
-
- /**
- * Antagonist of the previous constructor, write the Data entry
- * corresponding to this interval in a ByteBuffer (mapped to a block in the
- * history-file, hopefully)
- *
- * @param buffer
- * The already-allocated ByteBuffer corresponding to a SHT Node
- * @param endPosOfStringEntry
- * The initial (before calling this function for this interval)
- * position of the Strings Entry for this node. This will change
- * from one call to the other if we're writing String
- * StateValues.
- * @return The size of the Strings Entry that was written, if any.
- */
- public int writeInterval(ByteBuffer buffer, int endPosOfStringEntry) {
- buffer.putLong(start);
- buffer.putLong(end);
- buffer.putInt(attribute);
- buffer.put(getByteFromType(sv.getType()));
-
- switch (getByteFromType(sv.getType())) {
-
- case TYPE_NULL:
- case TYPE_INTEGER:
- /* We write the 'valueOffset' field as a straight value. */
- try {
- buffer.putInt(sv.unboxInt());
- } catch (StateValueTypeException e) {
- /*
- * This should not happen, since the value told us it was of
- * type Null or Integer (corrupted value?)
- */
- e.printStackTrace();
- }
- break;
-
- case TYPE_STRING:
- byte[] byteArrayToWrite;
- try {
- byteArrayToWrite = sv.unboxStr().getBytes();
- } catch (StateValueTypeException e1) {
- /* Should not happen, we're in a switch/case for string type */
- throw new RuntimeException();
- }
-
- /* we use the valueOffset as an offset. */
- buffer.putInt(endPosOfStringEntry - stringsEntrySize);
- buffer.mark();
- buffer.position(endPosOfStringEntry - stringsEntrySize);
-
- /*
- * write the Strings entry (1st byte = size, then the bytes, then the 0)
- */
- buffer.put((byte) stringsEntrySize);
- buffer.put(byteArrayToWrite);
- buffer.put((byte) 0);
- assert (buffer.position() == endPosOfStringEntry);
- buffer.reset();
- break;
-
- case TYPE_LONG:
- /* we use the valueOffset as an offset. */
- buffer.putInt(endPosOfStringEntry - stringsEntrySize);
- buffer.mark();
- buffer.position(endPosOfStringEntry - stringsEntrySize);
-
- /*
- * write the Long in the Strings section
- */
- try {
- buffer.putLong(sv.unboxLong());
- } catch (StateValueTypeException e) {
- /*
- * This should not happen, since the value told us it was of
- * type Long (corrupted value?)
- */
- e.printStackTrace();
- }
- assert (buffer.position() == endPosOfStringEntry);
- buffer.reset();
- break;
-
- case TYPE_DOUBLE:
- /* we use the valueOffset as an offset. */
- buffer.putInt(endPosOfStringEntry - stringsEntrySize);
- buffer.mark();
- buffer.position(endPosOfStringEntry - stringsEntrySize);
-
- /* Write the Double in the Strings section */
- try {
- buffer.putDouble(sv.unboxDouble());
- } catch (StateValueTypeException e) {
- /*
- * This should not happen, since the value told us it was of
- * type Double (corrupted value?)
- */
- e.printStackTrace();
- }
- if (buffer.position() != endPosOfStringEntry) {
- throw new IllegalStateException();
- }
- buffer.reset();
- break;
-
- default:
- break;
- }
- return stringsEntrySize;
- }
-
- @Override
- public long getStartTime() {
- return start;
- }
-
- @Override
- public long getEndTime() {
- return end;
- }
-
- @Override
- public long getViewerEndTime() {
- return end + 1;
- }
-
- @Override
- public int getAttribute() {
- return attribute;
- }
-
- @Override
- public ITmfStateValue getStateValue() {
- return sv;
- }
-
- @Override
- public boolean intersects(long timestamp) {
- if (start <= timestamp) {
- if (end >= timestamp) {
- return true;
- }
- }
- return false;
- }
-
- int getStringsEntrySize() {
- return stringsEntrySize;
- }
-
- /**
- * Total serialized size of this interval
- *
- * @return The interval size
- */
- public int getIntervalSize() {
- return stringsEntrySize + DATA_ENTRY_SIZE;
- }
-
- private int computeStringsEntrySize() {
- switch(sv.getType()) {
- case NULL:
- case INTEGER:
- /* Those don't use the strings section at all */
- return NO_ENTRY_SIZE;
- case LONG:
- /* The value's bytes are written directly into the strings section */
- return LONG_ENTRY_SIZE;
- case DOUBLE:
- /* The value is also written directly into the strings section */
- return DOUBLE_ENTRY_SIZE;
- case STRING:
- try {
- /* String's length + 2 (1 byte for size, 1 byte for \0 at the end */
- return sv.unboxStr().getBytes().length + 2;
- } catch (StateValueTypeException e) {
- /* We're inside a switch/case for the string type, can't happen */
- throw new IllegalStateException(e);
- }
- default:
- /* It's very important that we know how to write the state value in
- * the file!! */
- throw new IllegalStateException();
- }
- }
-
- /**
- * Compare the END TIMES of different intervals. This is used to sort the
- * intervals when we close down a node.
- */
- @Override
- public int compareTo(HTInterval other) {
- if (this.end < other.end) {
- return -1;
- } else if (this.end > other.end) {
- return 1;
- } else {
- return 0;
- }
- }
-
- @Override
- public boolean equals(Object other) {
- if (other instanceof HTInterval &&
- this.compareTo((HTInterval) other) == 0) {
- return true;
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return super.hashCode();
- }
-
- @Override
- public String toString() {
- /* Only for debug, should not be externalized */
- StringBuilder sb = new StringBuilder();
- sb.append('[');
- sb.append(start);
- sb.append(", "); //$NON-NLS-1$
- sb.append(end);
- sb.append(']');
-
- sb.append(", attribute = "); //$NON-NLS-1$
- sb.append(attribute);
-
- sb.append(", value = "); //$NON-NLS-1$
- sb.append(sv.toString());
-
- return sb.toString();
- }
-
- /**
- * Here we determine how state values "types" are written in the 8-bit
- * field that indicates the value type in the file.
- */
- private static byte getByteFromType(ITmfStateValue.Type type) {
- switch(type) {
- case NULL:
- return TYPE_NULL;
- case INTEGER:
- return TYPE_INTEGER;
- case STRING:
- return TYPE_STRING;
- case LONG:
- return TYPE_LONG;
- case DOUBLE:
- return TYPE_DOUBLE;
- default:
- /* Should not happen if the switch is fully covered */
- throw new IllegalStateException();
- }
- }
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2010, 2015 Ericsson, École Polytechnique de Montréal, and others
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- * Florian Wininger - Add Extension and Leaf Node
- * Patrick Tasse - Keep interval list sorted on insert
- *******************************************************************************/
-
-package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.channels.FileChannel;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
-import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
-import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
-
-/**
- * The base class for all the types of nodes that go in the History Tree.
- *
- * @author Alexandre Montplaisir
- */
-public abstract class HTNode {
-
- // ------------------------------------------------------------------------
- // Class fields
- // ------------------------------------------------------------------------
-
- /**
- * The type of node
- */
- public static enum NodeType {
- /**
- * Core node, which is a "front" node, at any level of the tree except
- * the bottom-most one. It has children, and may have extensions.
- */
- CORE,
- /**
- * Leaf node, which is a node at the last bottom level of the tree. It
- * cannot have any children or extensions.
- */
- LEAF;
-
- /**
- * Determine a node type by reading a serialized byte.
- *
- * @param rep
- * The byte representation of the node type
- * @return The corresponding NodeType
- * @throws IOException
- * If the NodeType is unrecognized
- */
- public static NodeType fromByte(byte rep) throws IOException {
- switch (rep) {
- case 1:
- return CORE;
- case 2:
- return LEAF;
- default:
- throw new IOException();
- }
- }
-
- /**
- * Get the byte representation of this node type. It can then be read
- * with {@link #fromByte}.
- *
- * @return The byte matching this node type
- */
- public byte toByte() {
- switch (this) {
- case CORE:
- return 1;
- case LEAF:
- return 2;
- default:
- throw new IllegalStateException();
- }
- }
- }
-
- // ------------------------------------------------------------------------
- // Attributes
- // ------------------------------------------------------------------------
-
- /* Configuration of the History Tree to which belongs this node */
- private final HTConfig config;
-
- /* Time range of this node */
- private final long nodeStart;
- private long nodeEnd;
-
- /* Sequence number = position in the node section of the file */
- private final int sequenceNumber;
- private int parentSequenceNumber; /* = -1 if this node is the root node */
-
- /* Where the Strings section begins (from the start of the node */
- private int stringSectionOffset;
-
- /* Sum of bytes of all intervals in the node */
- private int sizeOfIntervalSection;
-
- /* True if this node was read from disk (meaning its end time is now fixed) */
- private volatile boolean isOnDisk;
-
- /* Vector containing all the intervals contained in this node */
- private final List<HTInterval> intervals;
-
- /* Lock used to protect the accesses to intervals, nodeEnd and such */
- private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(false);
-
- /**
- * Constructor
- *
- * @param config
- * Configuration of the History Tree
- * @param seqNumber
- * The (unique) sequence number assigned to this particular node
- * @param parentSeqNumber
- * The sequence number of this node's parent node
- * @param start
- * The earliest timestamp stored in this node
- */
- protected HTNode(HTConfig config, int seqNumber, int parentSeqNumber, long start) {
- this.config = config;
- this.nodeStart = start;
- this.sequenceNumber = seqNumber;
- this.parentSequenceNumber = parentSeqNumber;
-
- this.stringSectionOffset = config.getBlockSize();
- this.sizeOfIntervalSection = 0;
- this.isOnDisk = false;
- this.intervals = new ArrayList<>();
- }
-
- /**
- * Reader factory method. Build a Node object (of the right type) by reading
- * a block in the file.
- *
- * @param config
- * Configuration of the History Tree
- * @param fc
- * FileChannel to the history file, ALREADY SEEKED at the start
- * of the node.
- * @return The node object
- * @throws IOException
- * If there was an error reading from the file channel
- */
- public static final HTNode readNode(HTConfig config, FileChannel fc)
- throws IOException {
- HTNode newNode = null;
- int res, i;
-
- ByteBuffer buffer = ByteBuffer.allocate(config.getBlockSize());
- buffer.order(ByteOrder.LITTLE_ENDIAN);
- buffer.clear();
- res = fc.read(buffer);
- assert (res == config.getBlockSize());
- buffer.flip();
-
- /* Read the common header part */
- byte typeByte = buffer.get();
- NodeType type = NodeType.fromByte(typeByte);
- long start = buffer.getLong();
- long end = buffer.getLong();
- int seqNb = buffer.getInt();
- int parentSeqNb = buffer.getInt();
- int intervalCount = buffer.getInt();
- int stringSectionOffset = buffer.getInt();
- buffer.get(); // TODO Used to be "isDone", to be removed from the header
-
- /* Now the rest of the header depends on the node type */
- switch (type) {
- case CORE:
- /* Core nodes */
- newNode = new CoreNode(config, seqNb, parentSeqNb, start);
- newNode.readSpecificHeader(buffer);
- break;
-
- case LEAF:
- /* Leaf nodes */
- newNode = new LeafNode(config, seqNb, parentSeqNb, start);
- newNode.readSpecificHeader(buffer);
- break;
-
- default:
- /* Unrecognized node type */
- throw new IOException();
- }
-
- /*
- * At this point, we should be done reading the header and 'buffer'
- * should only have the intervals left
- */
- for (i = 0; i < intervalCount; i++) {
- newNode.intervals.add(HTInterval.readFrom(buffer));
- }
-
- /* Assign the node's other information we have read previously */
- newNode.nodeEnd = end;
- newNode.stringSectionOffset = stringSectionOffset;
- newNode.isOnDisk = true;
-
- return newNode;
- }
-
- /**
- * Write this node to the given file channel.
- *
- * @param fc
- * The file channel to write to (should be sought to be correct
- * position)
- * @throws IOException
- * If there was an error writing
- */
- public final void writeSelf(FileChannel fc) throws IOException {
- /*
- * Yes, we are taking the *read* lock here, because we are reading the
- * information in the node to write it to disk.
- */
- rwl.readLock().lock();
- try {
- final int blockSize = config.getBlockSize();
- int curStringsEntryEndPos = blockSize;
-
- ByteBuffer buffer = ByteBuffer.allocate(blockSize);
- buffer.order(ByteOrder.LITTLE_ENDIAN);
- buffer.clear();
-
- /* Write the common header part */
- buffer.put(this.getNodeType().toByte());
- buffer.putLong(nodeStart);
- buffer.putLong(nodeEnd);
- buffer.putInt(sequenceNumber);
- buffer.putInt(parentSequenceNumber);
- buffer.putInt(intervals.size());
- buffer.putInt(stringSectionOffset);
- buffer.put((byte) 1); // TODO Used to be "isDone", to be removed from header
-
- /* Now call the inner method to write the specific header part */
- this.writeSpecificHeader(buffer);
-
- /* Back to us, we write the intervals */
- for (HTInterval interval : intervals) {
- int size = interval.writeInterval(buffer, curStringsEntryEndPos);
- curStringsEntryEndPos -= size;
- }
-
- /*
- * Write padding between the end of the Data section and the start
- * of the Strings section (needed to fill the node in case there is
- * no Strings section)
- */
- while (buffer.position() < stringSectionOffset) {
- buffer.put((byte) 0);
- }
-
- /*
- * If the offsets were right, the size of the Strings section should
- * be == to the expected size
- */
- assert (curStringsEntryEndPos == stringSectionOffset);
-
- /* Finally, write everything in the Buffer to disk */
-
- // if we don't do this, flip() will lose what's after.
- buffer.position(blockSize);
-
- buffer.flip();
- int res = fc.write(buffer);
- assert (res == blockSize);
-
- } finally {
- rwl.readLock().unlock();
- }
- isOnDisk = true;
- }
-
- // ------------------------------------------------------------------------
- // Accessors
- // ------------------------------------------------------------------------
-
- /**
- * Retrieve the history tree configuration used for this node.
- *
- * @return The history tree config
- */
- protected HTConfig getConfig() {
- return config;
- }
-
- /**
- * Get the start time of this node.
- *
- * @return The start time of this node
- */
- public long getNodeStart() {
- return nodeStart;
- }
-
- /**
- * Get the end time of this node.
- *
- * @return The end time of this node
- */
- public long getNodeEnd() {
- if (this.isOnDisk) {
- return nodeEnd;
- }
- return 0;
- }
-
- /**
- * Get the sequence number of this node.
- *
- * @return The sequence number of this node
- */
- public int getSequenceNumber() {
- return sequenceNumber;
- }
-
- /**
- * Get the sequence number of this node's parent.
- *
- * @return The parent sequence number
- */
- public int getParentSequenceNumber() {
- return parentSequenceNumber;
- }
-
- /**
- * Change this node's parent. Used when we create a new root node for
- * example.
- *
- * @param newParent
- * The sequence number of the node that is the new parent
- */
- public void setParentSequenceNumber(int newParent) {
- parentSequenceNumber = newParent;
- }
-
- /**
- * Return if this node is "done" (full and written to disk).
- *
- * @return If this node is done or not
- */
- public boolean isOnDisk() {
- return isOnDisk;
- }
-
- /**
- * Add an interval to this node
- *
- * @param newInterval
- * Interval to add to this node
- */
- public void addInterval(HTInterval newInterval) {
- rwl.writeLock().lock();
- try {
- /* Just in case, should be checked before even calling this function */
- assert (newInterval.getIntervalSize() <= this.getNodeFreeSpace());
-
- /* Find the insert position to keep the list sorted */
- int index = intervals.size();
- while (index > 0 && newInterval.compareTo(intervals.get(index - 1)) < 0) {
- index--;
- }
-
- intervals.add(index, newInterval);
- sizeOfIntervalSection += newInterval.getIntervalSize();
-
- /* Update the in-node offset "pointer" */
- stringSectionOffset -= (newInterval.getStringsEntrySize());
- } finally {
- rwl.writeLock().unlock();
- }
- }
-
- /**
- * We've received word from the containerTree that newest nodes now exist to
- * our right. (Puts isDone = true and sets the endtime)
- *
- * @param endtime
- * The nodeEnd time that the node will have
- */
- public void closeThisNode(long endtime) {
- rwl.writeLock().lock();
- try {
- assert (endtime >= this.nodeStart);
-
- if (!intervals.isEmpty()) {
- /*
- * Make sure there are no intervals in this node with their
- * EndTime > the one requested. Only need to check the last one
- * since they are sorted
- */
- assert (endtime >= intervals.get(intervals.size() - 1).getEndTime());
- }
-
- this.nodeEnd = endtime;
- } finally {
- rwl.writeLock().unlock();
- }
- }
-
- /**
- * The method to fill up the stateInfo (passed on from the Current State
- * Tree when it does a query on the SHT). We'll replace the data in that
- * vector with whatever relevant we can find from this node
- *
- * @param stateInfo
- * The same stateInfo that comes from SHT's doQuery()
- * @param t
- * The timestamp for which the query is for. Only return
- * intervals that intersect t.
- * @throws TimeRangeException
- * If 't' is invalid
- */
- public void writeInfoFromNode(List<ITmfStateInterval> stateInfo, long t)
- throws TimeRangeException {
- /* This is from a state system query, we are "reading" this node */
- rwl.readLock().lock();
- try {
- for (int i = getStartIndexFor(t); i < intervals.size(); i++) {
- /*
- * Now we only have to compare the Start times, since we now the
- * End times necessarily fit.
- *
- * Second condition is to ignore new attributes that might have
- * been created after stateInfo was instantiated (they would be
- * null anyway).
- */
- ITmfStateInterval interval = intervals.get(i);
- if (interval.getStartTime() <= t &&
- interval.getAttribute() < stateInfo.size()) {
- stateInfo.set(interval.getAttribute(), interval);
- }
- }
- } finally {
- rwl.readLock().unlock();
- }
- }
-
- /**
- * Get a single Interval from the information in this node If the
- * key/timestamp pair cannot be found, we return null.
- *
- * @param key
- * The attribute quark to look for
- * @param t
- * The timestamp
- * @return The Interval containing the information we want, or null if it
- * wasn't found
- * @throws TimeRangeException
- * If 't' is invalid
- */
- public HTInterval getRelevantInterval(int key, long t) throws TimeRangeException {
- rwl.readLock().lock();
- try {
- for (int i = getStartIndexFor(t); i < intervals.size(); i++) {
- HTInterval curInterval = intervals.get(i);
- if (curInterval.getAttribute() == key
- && curInterval.getStartTime() <= t
- && curInterval.getEndTime() >= t) {
- return curInterval;
- }
- }
-
- /* We didn't find the relevant information in this node */
- return null;
-
- } finally {
- rwl.readLock().unlock();
- }
- }
-
- private int getStartIndexFor(long t) throws TimeRangeException {
- /* Should only be called by methods with the readLock taken */
-
- if (intervals.isEmpty()) {
- return 0;
- }
- /*
- * Since the intervals are sorted by end time, we can skip all the ones
- * at the beginning whose end times are smaller than 't'. Java does
- * provides a .binarySearch method, but its API is quite weird...
- */
- HTInterval dummy = new HTInterval(0, t, 0, TmfStateValue.nullValue());
- int index = Collections.binarySearch(intervals, dummy);
-
- if (index < 0) {
- /*
- * .binarySearch returns a negative number if the exact value was
- * not found. Here we just want to know where to start searching, we
- * don't care if the value is exact or not.
- */
- index = -index - 1;
-
- }
-
- /* Sometimes binarySearch yields weird stuff... */
- if (index < 0) {
- index = 0;
- }
- if (index >= intervals.size()) {
- index = intervals.size() - 1;
- }
-
- /*
- * Another API quirkiness, the returned index is the one of the *last*
- * element of a series of equal endtimes, which happens sometimes. We
- * want the *first* element of such a series, to read through them
- * again.
- */
- while (index > 0
- && intervals.get(index - 1).compareTo(intervals.get(index)) == 0) {
- index--;
- }
-
- return index;
- }
-
- /**
- * <pre>
- * 1 - byte (type)
- * 16 - 2x long (start time, end time)
- * 16 - 4x int (seq number, parent seq number, intervalcount,
- * strings section pos.)
- * 1 - byte (done or not)
- * </pre>
- */
- private static final int COMMON_HEADER_SIZE = 34;
-
- /**
- * Return the total header size of this node (will depend on the node type).
- *
- * @return The total header size
- */
- public final int getTotalHeaderSize() {
- return COMMON_HEADER_SIZE + getSpecificHeaderSize();
- }
-
- /**
- * @return The offset, within the node, where the Data section ends
- */
- private int getDataSectionEndOffset() {
- return this.getTotalHeaderSize() + sizeOfIntervalSection;
- }
-
- /**
- * Returns the free space in the node, which is simply put, the
- * stringSectionOffset - dataSectionOffset
- *
- * @return The amount of free space in the node (in bytes)
- */
- public int getNodeFreeSpace() {
- rwl.readLock().lock();
- int ret = stringSectionOffset - this.getDataSectionEndOffset();
- rwl.readLock().unlock();
-
- return ret;
- }
-
- /**
- * Returns the current space utilization of this node, as a percentage.
- * (used space / total usable space, which excludes the header)
- *
- * @return The percentage (value between 0 and 100) of space utilization in
- * in this node.
- */
- public long getNodeUsagePercent() {
- rwl.readLock().lock();
- try {
- final int blockSize = config.getBlockSize();
- float freePercent = (float) this.getNodeFreeSpace()
- / (float) (blockSize - this.getTotalHeaderSize())
- * 100F;
- return (long) (100L - freePercent);
-
- } finally {
- rwl.readLock().unlock();
- }
- }
-
- /**
- * @name Debugging functions
- */
-
- @SuppressWarnings("nls")
- @Override
- public String toString() {
- /* Only used for debugging, shouldn't be externalized */
- StringBuffer buf = new StringBuffer("Node #" + sequenceNumber + ", ");
- buf.append(this.toStringSpecific());
- buf.append(intervals.size() + " intervals (" + this.getNodeUsagePercent()
- + "% used), ");
-
- buf.append("[" + this.nodeStart + " - ");
- if (this.isOnDisk) {
- buf = buf.append("" + this.nodeEnd + "]");
- } else {
- buf = buf.append("...]");
- }
- return buf.toString();
- }
-
- /**
- * Debugging function that prints out the contents of this node
- *
- * @param writer
- * PrintWriter in which we will print the debug output
- */
- @SuppressWarnings("nls")
- public void debugPrintIntervals(PrintWriter writer) {
- /* Only used for debugging, shouldn't be externalized */
- writer.println("Node #" + sequenceNumber + ":");
-
- /* Array of children */
- if (this.getNodeType() == NodeType.CORE) { /* Only Core Nodes can have children */
- CoreNode thisNode = (CoreNode) this;
- writer.print(" " + thisNode.getNbChildren() + " children");
- if (thisNode.getNbChildren() >= 1) {
- writer.print(": [ " + thisNode.getChild(0));
- for (int i = 1; i < thisNode.getNbChildren(); i++) {
- writer.print(", " + thisNode.getChild(i));
- }
- writer.print(']');
- }
- writer.print('\n');
- }
-
- /* List of intervals in the node */
- writer.println(" Intervals contained:");
- for (int i = 0; i < intervals.size(); i++) {
- writer.println(intervals.get(i).toString());
- }
- writer.println('\n');
- }
-
- // ------------------------------------------------------------------------
- // Abstract methods
- // ------------------------------------------------------------------------
-
- /**
- * Get the byte value representing the node type.
- *
- * @return The node type
- */
- public abstract NodeType getNodeType();
-
- /**
- * Return the specific header size of this node. This means the size
- * occupied by the type-specific section of the header (not counting the
- * common part).
- *
- * @return The specific header size
- */
- protected abstract int getSpecificHeaderSize();
-
- /**
- * Read the type-specific part of the node header from a byte buffer.
- *
- * @param buffer
- * The byte buffer to read from. It should be already positioned
- * correctly.
- */
- protected abstract void readSpecificHeader(ByteBuffer buffer);
-
- /**
- * Write the type-specific part of the header in a byte buffer.
- *
- * @param buffer
- * The buffer to write to. It should already be at the correct
- * position.
- */
- protected abstract void writeSpecificHeader(ByteBuffer buffer);
-
- /**
- * Node-type-specific toString method. Used for debugging.
- *
- * @return A string representing the node
- */
- protected abstract String toStringSpecific();
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2014 Ericsson
- * Copyright (c) 2010, 2011 École Polytechnique de Montréal
- * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- *******************************************************************************/
-
-package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.FileChannel;
-
-import org.eclipse.tracecompass.internal.statesystem.core.Activator;
-
-/**
- * This class abstracts inputs/outputs of the HistoryTree nodes.
- *
- * It contains all the methods and descriptors to handle reading/writing nodes
- * to the tree-file on disk and all the caching mechanisms.
- *
- * This abstraction is mainly for code isolation/clarification purposes. Every
- * HistoryTree must contain 1 and only 1 HT_IO element.
- *
- * @author Alexandre Montplaisir
- *
- */
-class HT_IO {
- /* Configuration of the History Tree */
- private final HTConfig fConfig;
-
- /* Fields related to the file I/O */
- private final FileInputStream fis;
- private final FileOutputStream fos;
- private final FileChannel fcIn;
- private final FileChannel fcOut;
-
- // TODO test/benchmark optimal cache size
- private static final int CACHE_SIZE = 256;
- private final HTNode fNodeCache[] = new HTNode[CACHE_SIZE];
-
- /**
- * Standard constructor
- *
- * @param config
- * The configuration object for the StateHistoryTree
- * @param newFile
- * Flag indicating that the file must be created from scratch
- *
- * @throws IOException
- * An exception can be thrown when file cannot be accessed
- */
- public HT_IO(HTConfig config, boolean newFile) throws IOException {
- fConfig = config;
-
- File historyTreeFile = config.getStateFile();
- if (newFile) {
- boolean success1 = true;
- /* Create a new empty History Tree file */
- if (historyTreeFile.exists()) {
- success1 = historyTreeFile.delete();
- }
- boolean success2 = historyTreeFile.createNewFile();
- if (!(success1 && success2)) {
- /* It seems we do not have permission to create the new file */
- throw new IOException("Cannot create new file at " + //$NON-NLS-1$
- historyTreeFile.getName());
- }
- fis = new FileInputStream(historyTreeFile);
- fos = new FileOutputStream(historyTreeFile, false);
- } else {
- /*
- * We want to open an existing file, make sure we don't squash the
- * existing content when opening the fos!
- */
- this.fis = new FileInputStream(historyTreeFile);
- this.fos = new FileOutputStream(historyTreeFile, true);
- }
- this.fcIn = fis.getChannel();
- this.fcOut = fos.getChannel();
- }
-
- /**
- * Read a node from the file on disk.
- *
- * @param seqNumber
- * The sequence number of the node to read.
- * @return The object representing the node
- * @throws ClosedChannelException
- * Usually happens because the file was closed while we were
- * reading. Instead of using a big reader-writer lock, we'll
- * just catch this exception.
- */
- public synchronized HTNode readNode(int seqNumber) throws ClosedChannelException {
- /* Do a cache lookup */
- int offset = seqNumber & (CACHE_SIZE - 1);
- HTNode readNode = fNodeCache[offset];
- if (readNode != null && readNode.getSequenceNumber() == seqNumber) {
- return readNode;
- }
-
- /* Lookup on disk */
- try {
- seekFCToNodePos(fcIn, seqNumber);
- readNode = HTNode.readNode(fConfig, fcIn);
-
- /* Put the node in the cache. */
- fNodeCache[offset] = readNode;
- return readNode;
- } catch (ClosedChannelException e) {
- throw e;
- } catch (IOException e) {
- /* Other types of IOExceptions shouldn't happen at this point though */
- Activator.getDefault().logError(e.getMessage(), e);
- return null;
- }
- }
-
- public synchronized void writeNode(HTNode node) {
- try {
- /* Insert the node into the cache. */
- int seqNumber = node.getSequenceNumber();
- int offset = seqNumber & (CACHE_SIZE - 1);
- fNodeCache[offset] = node;
-
- /* Position ourselves at the start of the node and write it */
- seekFCToNodePos(fcOut, seqNumber);
- node.writeSelf(fcOut);
- } catch (IOException e) {
- /* If we were able to open the file, we should be fine now... */
- Activator.getDefault().logError(e.getMessage(), e);
- }
- }
-
- public FileChannel getFcOut() {
- return this.fcOut;
- }
-
- public FileInputStream supplyATReader(int nodeOffset) {
- try {
- /*
- * Position ourselves at the start of the Mapping section in the
- * file (which is right after the Blocks)
- */
- seekFCToNodePos(fcIn, nodeOffset);
- } catch (IOException e) {
- Activator.getDefault().logError(e.getMessage(), e);
- }
- return fis;
- }
-
- public synchronized void closeFile() {
- try {
- fis.close();
- fos.close();
- } catch (IOException e) {
- Activator.getDefault().logError(e.getMessage(), e);
- }
- }
-
- public synchronized void deleteFile() {
- closeFile();
-
- File historyTreeFile = fConfig.getStateFile();
- if (!historyTreeFile.delete()) {
- /* We didn't succeed in deleting the file */
- Activator.getDefault().logError("Failed to delete" + historyTreeFile.getName()); //$NON-NLS-1$
- }
- }
-
- /**
- * Seek the given FileChannel to the position corresponding to the node that
- * has seqNumber
- *
- * @param fc
- * the channel to seek
- * @param seqNumber
- * the node sequence number to seek the channel to
- * @throws IOException
- * If some other I/O error occurs
- */
- private void seekFCToNodePos(FileChannel fc, int seqNumber)
- throws IOException {
- /*
- * Cast to (long) is needed to make sure the result is a long too and
- * doesn't get truncated
- */
- fc.position(HistoryTree.TREE_HEADER_SIZE
- + ((long) seqNumber) * fConfig.getBlockSize());
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2010, 2015 Ericsson, École Polytechnique de Montréal, and others
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- * Florian Wininger - Add Extension and Leaf Node
- * Patrick Tasse - Add message to exceptions
- *******************************************************************************/
-
-package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.FileChannel;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.eclipse.tracecompass.internal.statesystem.core.Activator;
-import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
-import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
-
-/**
- * Meta-container for the History Tree. This structure contains all the
- * high-level data relevant to the tree.
- *
- * @author Alexandre Montplaisir
- */
-public class HistoryTree {
-
- /**
- * Size of the "tree header" in the tree-file The nodes will use this offset
- * to know where they should be in the file. This should always be a
- * multiple of 4K.
- */
- public static final int TREE_HEADER_SIZE = 4096;
-
- private static final int HISTORY_FILE_MAGIC_NUMBER = 0x05FFA900;
-
- /** File format version. Increment when breaking compatibility. */
- private static final int FILE_VERSION = 5;
-
- // ------------------------------------------------------------------------
- // Tree-specific configuration
- // ------------------------------------------------------------------------
-
- /** Container for all the configuration constants */
- private final HTConfig config;
-
- /** Reader/writer object */
- private final HT_IO treeIO;
-
- // ------------------------------------------------------------------------
- // Variable Fields (will change throughout the existence of the SHT)
- // ------------------------------------------------------------------------
-
- /** Latest timestamp found in the tree (at any given moment) */
- private long treeEnd;
-
- /** The total number of nodes that exists in this tree */
- private int nodeCount;
-
- /** "Cache" to keep the active nodes in memory */
- private final List<HTNode> latestBranch;
-
- // ------------------------------------------------------------------------
- // Constructors/"Destructors"
- // ------------------------------------------------------------------------
-
- /**
- * Create a new State History from scratch, using a {@link HTConfig} object
- * for configuration.
- *
- * @param conf
- * The config to use for this History Tree.
- * @throws IOException
- * If an error happens trying to open/write to the file
- * specified in the config
- */
- public HistoryTree(HTConfig conf) throws IOException {
- /*
- * Simple check to make sure we have enough place in the 0th block for
- * the tree configuration
- */
- if (conf.getBlockSize() < TREE_HEADER_SIZE) {
- throw new IllegalArgumentException();
- }
-
- config = conf;
- treeEnd = conf.getTreeStart();
- nodeCount = 0;
- latestBranch = Collections.synchronizedList(new ArrayList<HTNode>());
-
- /* Prepare the IO object */
- treeIO = new HT_IO(config, true);
-
- /* Add the first node to the tree */
- LeafNode firstNode = initNewLeafNode(-1, conf.getTreeStart());
- latestBranch.add(firstNode);
- }
-
- /**
- * "Reader" constructor : instantiate a SHTree from an existing tree file on
- * disk
- *
- * @param existingStateFile
- * Path/filename of the history-file we are to open
- * @param expProviderVersion
- * The expected version of the state provider
- * @throws IOException
- * If an error happens reading the file
- */
- public HistoryTree(File existingStateFile, int expProviderVersion) throws IOException {
- /*
- * Open the file ourselves, get the tree header information we need,
- * then pass on the descriptor to the TreeIO object.
- */
- int rootNodeSeqNb, res;
- int bs, maxc;
- long startTime;
-
- /* Java I/O mumbo jumbo... */
- if (!existingStateFile.exists()) {
- throw new IOException("Selected state file does not exist"); //$NON-NLS-1$
- }
- if (existingStateFile.length() <= 0) {
- throw new IOException("Empty target file"); //$NON-NLS-1$
- }
-
- try (FileInputStream fis = new FileInputStream(existingStateFile);
- FileChannel fc = fis.getChannel();) {
-
- ByteBuffer buffer = ByteBuffer.allocate(TREE_HEADER_SIZE);
-
- buffer.order(ByteOrder.LITTLE_ENDIAN);
- buffer.clear();
- fc.read(buffer);
- buffer.flip();
-
- /*
- * Check the magic number to make sure we're opening the right type
- * of file
- */
- res = buffer.getInt();
- if (res != HISTORY_FILE_MAGIC_NUMBER) {
- throw new IOException("Wrong magic number"); //$NON-NLS-1$
- }
-
- res = buffer.getInt(); /* File format version number */
- if (res != FILE_VERSION) {
- throw new IOException("Mismatching History Tree file format versions"); //$NON-NLS-1$
- }
-
- res = buffer.getInt(); /* Event handler's version number */
- if (res != expProviderVersion &&
- expProviderVersion != ITmfStateSystemBuilder.IGNORE_PROVIDER_VERSION) {
- /*
- * The existing history was built using an event handler that
- * doesn't match the current one in the framework.
- *
- * Information could be all wrong. Instead of keeping an
- * incorrect history file, a rebuild is done.
- */
- throw new IOException("Mismatching event handler versions"); //$NON-NLS-1$
- }
-
- bs = buffer.getInt(); /* Block Size */
- maxc = buffer.getInt(); /* Max nb of children per node */
-
- this.nodeCount = buffer.getInt();
- rootNodeSeqNb = buffer.getInt();
- startTime = buffer.getLong();
-
- this.config = new HTConfig(existingStateFile, bs, maxc, expProviderVersion, startTime);
- }
-
- /*
- * FIXME We close fis here and the TreeIO will then reopen the same
- * file, not extremely elegant. But how to pass the information here to
- * the SHT otherwise?
- */
- this.treeIO = new HT_IO(config, false);
-
- this.latestBranch = buildLatestBranch(rootNodeSeqNb);
- this.treeEnd = getRootNode().getNodeEnd();
-
- /*
- * Make sure the history start time we read previously is consistent
- * with was is actually in the root node.
- */
- if (startTime != getRootNode().getNodeStart()) {
- throw new IOException("Inconsistent start times in the" + //$NON-NLS-1$
- "history file, it might be corrupted."); //$NON-NLS-1$
- }
- }
-
- /**
- * Rebuild the latestBranch "cache" object by reading the nodes from disk
- * (When we are opening an existing file on disk and want to append to it,
- * for example).
- *
- * @param rootNodeSeqNb
- * The sequence number of the root node, so we know where to
- * start
- * @throws ClosedChannelException
- */
- private List<HTNode> buildLatestBranch(int rootNodeSeqNb) throws ClosedChannelException {
- List<HTNode> list = new ArrayList<>();
-
- HTNode nextChildNode = treeIO.readNode(rootNodeSeqNb);
- list.add(nextChildNode);
-
- /* Follow the last branch up to the leaf */
- while (nextChildNode.getNodeType() == HTNode.NodeType.CORE) {
- nextChildNode = treeIO.readNode(((CoreNode) nextChildNode).getLatestChild());
- list.add(nextChildNode);
- }
- return Collections.synchronizedList(list);
- }
-
- /**
- * "Save" the tree to disk. This method will cause the treeIO object to
- * commit all nodes to disk and then return the RandomAccessFile descriptor
- * so the Tree object can save its configuration into the header of the
- * file.
- *
- * @param requestedEndTime
- * The greatest timestamp present in the history tree
- */
- public void closeTree(long requestedEndTime) {
- /* This is an important operation, queries can wait */
- synchronized (latestBranch) {
- /*
- * Work-around the "empty branches" that get created when the root
- * node becomes full. Overwrite the tree's end time with the
- * original wanted end-time, to ensure no queries are sent into
- * those empty nodes.
- *
- * This won't be needed once extended nodes are implemented.
- */
- this.treeEnd = requestedEndTime;
-
- /* Close off the latest branch of the tree */
- for (int i = 0; i < latestBranch.size(); i++) {
- latestBranch.get(i).closeThisNode(treeEnd);
- treeIO.writeNode(latestBranch.get(i));
- }
-
- try (FileChannel fc = treeIO.getFcOut();) {
- ByteBuffer buffer = ByteBuffer.allocate(TREE_HEADER_SIZE);
- buffer.order(ByteOrder.LITTLE_ENDIAN);
- buffer.clear();
-
- /* Save the config of the tree to the header of the file */
- fc.position(0);
-
- buffer.putInt(HISTORY_FILE_MAGIC_NUMBER);
-
- buffer.putInt(FILE_VERSION);
- buffer.putInt(config.getProviderVersion());
-
- buffer.putInt(config.getBlockSize());
- buffer.putInt(config.getMaxChildren());
-
- buffer.putInt(nodeCount);
-
- /* root node seq. nb */
- buffer.putInt(latestBranch.get(0).getSequenceNumber());
-
- /* start time of this history */
- buffer.putLong(latestBranch.get(0).getNodeStart());
-
- buffer.flip();
- int res = fc.write(buffer);
- assert (res <= TREE_HEADER_SIZE);
- /* done writing the file header */
-
- } catch (IOException e) {
- /*
- * If we were able to write so far, there should not be any
- * problem at this point...
- */
- throw new RuntimeException("State system write error"); //$NON-NLS-1$
- }
- }
- }
-
- // ------------------------------------------------------------------------
- // Accessors
- // ------------------------------------------------------------------------
-
- /**
- * Get the start time of this tree.
- *
- * @return The start time
- */
- public long getTreeStart() {
- return config.getTreeStart();
- }
-
- /**
- * Get the current end time of this tree.
- *
- * @return The end time
- */
- public long getTreeEnd() {
- return treeEnd;
- }
-
- /**
- * Get the number of nodes in this tree.
- *
- * @return The number of nodes
- */
- public int getNodeCount() {
- return nodeCount;
- }
-
- /**
- * Get the current root node of this tree
- *
- * @return The root node
- */
- public HTNode getRootNode() {
- return latestBranch.get(0);
- }
-
- // ------------------------------------------------------------------------
- // HT_IO interface
- // ------------------------------------------------------------------------
-
- /**
- * Return the FileInputStream reader with which we will read an attribute
- * tree (it will be sought to the correct position).
- *
- * @return The FileInputStream indicating the file and position from which
- * the attribute tree can be read.
- */
- public FileInputStream supplyATReader() {
- return treeIO.supplyATReader(getNodeCount());
- }
-
- /**
- * Return the file to which we will write the attribute tree.
- *
- * @return The file to which we will write the attribute tree
- */
- public File supplyATWriterFile() {
- return config.getStateFile();
- }
-
- /**
- * Return the position in the file (given by {@link #supplyATWriterFile})
- * where to start writing the attribute tree.
- *
- * @return The position in the file where to start writing
- */
- public long supplyATWriterFilePos() {
- return HistoryTree.TREE_HEADER_SIZE
- + ((long) getNodeCount() * config.getBlockSize());
- }
-
- /**
- * Read a node from the tree.
- *
- * @param seqNumber
- * The sequence number of the node to read
- * @return The node
- * @throws ClosedChannelException
- * If the tree IO is unavailable
- */
- public HTNode readNode(int seqNumber) throws ClosedChannelException {
- /* Try to read the node from memory */
- synchronized (latestBranch) {
- for (HTNode node : latestBranch) {
- if (node.getSequenceNumber() == seqNumber) {
- return node;
- }
- }
- }
-
- /* Read the node from disk */
- return treeIO.readNode(seqNumber);
- }
-
- /**
- * Write a node object to the history file.
- *
- * @param node
- * The node to write to disk
- */
- public void writeNode(HTNode node) {
- treeIO.writeNode(node);
- }
-
- /**
- * Close the history file.
- */
- public void closeFile() {
- treeIO.closeFile();
- }
-
- /**
- * Delete the history file.
- */
- public void deleteFile() {
- treeIO.deleteFile();
- }
-
- // ------------------------------------------------------------------------
- // Operations
- // ------------------------------------------------------------------------
-
- /**
- * Insert an interval in the tree.
- *
- * @param interval
- * The interval to be inserted
- * @throws TimeRangeException
- * If the start of end time of the interval are invalid
- */
- public void insertInterval(HTInterval interval) throws TimeRangeException {
- if (interval.getStartTime() < config.getTreeStart()) {
- throw new TimeRangeException("Interval Start:" + interval.getStartTime() + ", Config Start:" + config.getTreeStart()); //$NON-NLS-1$ //$NON-NLS-2$
- }
- tryInsertAtNode(interval, latestBranch.size() - 1);
- }
-
- /**
- * Inner method to find in which node we should add the interval.
- *
- * @param interval
- * The interval to add to the tree
- * @param indexOfNode
- * The index *in the latestBranch* where we are trying the
- * insertion
- */
- private void tryInsertAtNode(HTInterval interval, int indexOfNode) {
- HTNode targetNode = latestBranch.get(indexOfNode);
-
- /* Verify if there is enough room in this node to store this interval */
- if (interval.getIntervalSize() > targetNode.getNodeFreeSpace()) {
- /* Nope, not enough room. Insert in a new sibling instead. */
- addSiblingNode(indexOfNode);
- tryInsertAtNode(interval, latestBranch.size() - 1);
- return;
- }
-
- /* Make sure the interval time range fits this node */
- if (interval.getStartTime() < targetNode.getNodeStart()) {
- /*
- * No, this interval starts before the startTime of this node. We
- * need to check recursively in parents if it can fit.
- */
- assert (indexOfNode >= 1);
- tryInsertAtNode(interval, indexOfNode - 1);
- return;
- }
-
- /*
- * Ok, there is room, and the interval fits in this time slot. Let's add
- * it.
- */
- targetNode.addInterval(interval);
-
- /* Update treeEnd if needed */
- if (interval.getEndTime() > this.treeEnd) {
- this.treeEnd = interval.getEndTime();
- }
- }
-
- /**
- * Method to add a sibling to any node in the latest branch. This will add
- * children back down to the leaf level, if needed.
- *
- * @param indexOfNode
- * The index in latestBranch where we start adding
- */
- private void addSiblingNode(int indexOfNode) {
- synchronized (latestBranch) {
- final long splitTime = treeEnd;
-
- if (indexOfNode >= latestBranch.size()) {
- /*
- * We need to make sure (indexOfNode - 1) doesn't get the last
- * node in the branch, because that one is a Leaf Node.
- */
- throw new IllegalStateException();
- }
-
- /* Check if we need to add a new root node */
- if (indexOfNode == 0) {
- addNewRootNode();
- return;
- }
-
- /* Check if we can indeed add a child to the target parent */
- if (((CoreNode) latestBranch.get(indexOfNode - 1)).getNbChildren() == config.getMaxChildren()) {
- /* If not, add a branch starting one level higher instead */
- addSiblingNode(indexOfNode - 1);
- return;
- }
-
- /* Split off the new branch from the old one */
- for (int i = indexOfNode; i < latestBranch.size(); i++) {
- latestBranch.get(i).closeThisNode(splitTime);
- treeIO.writeNode(latestBranch.get(i));
-
- CoreNode prevNode = (CoreNode) latestBranch.get(i - 1);
- HTNode newNode;
-
- switch (latestBranch.get(i).getNodeType()) {
- case CORE:
- newNode = initNewCoreNode(prevNode.getSequenceNumber(), splitTime + 1);
- break;
- case LEAF:
- newNode = initNewLeafNode(prevNode.getSequenceNumber(), splitTime + 1);
- break;
- default:
- throw new IllegalStateException();
- }
-
- prevNode.linkNewChild(newNode);
- latestBranch.set(i, newNode);
- }
- }
- }
-
- /**
- * Similar to the previous method, except here we rebuild a completely new
- * latestBranch
- */
- private void addNewRootNode() {
- final long splitTime = this.treeEnd;
-
- HTNode oldRootNode = latestBranch.get(0);
- CoreNode newRootNode = initNewCoreNode(-1, config.getTreeStart());
-
- /* Tell the old root node that it isn't root anymore */
- oldRootNode.setParentSequenceNumber(newRootNode.getSequenceNumber());
-
- /* Close off the whole current latestBranch */
-
- for (int i = 0; i < latestBranch.size(); i++) {
- latestBranch.get(i).closeThisNode(splitTime);
- treeIO.writeNode(latestBranch.get(i));
- }
-
- /* Link the new root to its first child (the previous root node) */
- newRootNode.linkNewChild(oldRootNode);
-
- /* Rebuild a new latestBranch */
- int depth = latestBranch.size();
- latestBranch.clear();
- latestBranch.add(newRootNode);
-
- // Create new coreNode
- for (int i = 1; i < depth + 1; i++) {
- CoreNode prevNode = (CoreNode) latestBranch.get(i - 1);
- CoreNode newNode = initNewCoreNode(prevNode.getParentSequenceNumber(),
- splitTime + 1);
- prevNode.linkNewChild(newNode);
- latestBranch.add(newNode);
- }
-
- // Create the new leafNode
- CoreNode prevNode = (CoreNode) latestBranch.get(depth);
- LeafNode newNode = initNewLeafNode(prevNode.getParentSequenceNumber(), splitTime + 1);
- prevNode.linkNewChild(newNode);
- latestBranch.add(newNode);
- }
-
- /**
- * Add a new empty core node to the tree.
- *
- * @param parentSeqNumber
- * Sequence number of this node's parent
- * @param startTime
- * Start time of the new node
- * @return The newly created node
- */
- private CoreNode initNewCoreNode(int parentSeqNumber, long startTime) {
- CoreNode newNode = new CoreNode(config, this.nodeCount, parentSeqNumber,
- startTime);
- this.nodeCount++;
-
- /* Update the treeEnd if needed */
- if (startTime >= this.treeEnd) {
- this.treeEnd = startTime + 1;
- }
- return newNode;
- }
-
- /**
- * Add a new empty leaf node to the tree.
- *
- * @param parentSeqNumber
- * Sequence number of this node's parent
- * @param startTime
- * Start time of the new node
- * @return The newly created node
- */
- private LeafNode initNewLeafNode(int parentSeqNumber, long startTime) {
- LeafNode newNode = new LeafNode(config, this.nodeCount, parentSeqNumber,
- startTime);
- this.nodeCount++;
-
- /* Update the treeEnd if needed */
- if (startTime >= this.treeEnd) {
- this.treeEnd = startTime + 1;
- }
- return newNode;
- }
-
- /**
- * Inner method to select the next child of the current node intersecting
- * the given timestamp. Useful for moving down the tree following one
- * branch.
- *
- * @param currentNode
- * The node on which the request is made
- * @param t
- * The timestamp to choose which child is the next one
- * @return The child node intersecting t
- * @throws ClosedChannelException
- * If the file channel was closed while we were reading the tree
- */
- public HTNode selectNextChild(CoreNode currentNode, long t) throws ClosedChannelException {
- assert (currentNode.getNbChildren() > 0);
- int potentialNextSeqNb = currentNode.getSequenceNumber();
-
- for (int i = 0; i < currentNode.getNbChildren(); i++) {
- if (t >= currentNode.getChildStart(i)) {
- potentialNextSeqNb = currentNode.getChild(i);
- } else {
- break;
- }
- }
-
- /*
- * Once we exit this loop, we should have found a children to follow. If
- * we didn't, there's a problem.
- */
- assert (potentialNextSeqNb != currentNode.getSequenceNumber());
-
- /*
- * Since this code path is quite performance-critical, avoid iterating
- * through the whole latestBranch array if we know for sure the next
- * node has to be on disk
- */
- if (currentNode.isOnDisk()) {
- return treeIO.readNode(potentialNextSeqNb);
- }
- return readNode(potentialNextSeqNb);
- }
-
- /**
- * Get the current size of the history file.
- *
- * @return The history file size
- */
- public long getFileSize() {
- return config.getStateFile().length();
- }
-
- // ------------------------------------------------------------------------
- // Test/debugging methods
- // ------------------------------------------------------------------------
-
- /**
- * Debugging method to make sure all intervals contained in the given node
- * have valid start and end times.
- *
- * @param zenode
- * The node to check
- * @return True if everything is fine, false if there is at least one
- * invalid timestamp (end time < start time, time outside of the
- * range of the node, etc.)
- */
- @SuppressWarnings("nls")
- public boolean checkNodeIntegrity(HTNode zenode) {
- /* Only used for debugging, shouldn't be externalized */
- HTNode otherNode;
- CoreNode node;
- StringBuffer buf = new StringBuffer();
- boolean ret = true;
-
- // FIXME /* Only testing Core Nodes for now */
- if (!(zenode instanceof CoreNode)) {
- return true;
- }
-
- node = (CoreNode) zenode;
-
- try {
- /*
- * Test that this node's start and end times match the start of the
- * first child and the end of the last child, respectively
- */
- if (node.getNbChildren() > 0) {
- otherNode = treeIO.readNode(node.getChild(0));
- if (node.getNodeStart() != otherNode.getNodeStart()) {
- buf.append("Start time of node (" + node.getNodeStart() + ") "
- + "does not match start time of first child " + "("
- + otherNode.getNodeStart() + "), " + "node #"
- + otherNode.getSequenceNumber() + ")\n");
- ret = false;
- }
- if (node.isOnDisk()) {
- otherNode = treeIO.readNode(node.getLatestChild());
- if (node.getNodeEnd() != otherNode.getNodeEnd()) {
- buf.append("End time of node (" + node.getNodeEnd()
- + ") does not match end time of last child ("
- + otherNode.getNodeEnd() + ", node #"
- + otherNode.getSequenceNumber() + ")\n");
- ret = false;
- }
- }
- }
-
- /*
- * Test that the childStartTimes[] array matches the real nodes'
- * start times
- */
- for (int i = 0; i < node.getNbChildren(); i++) {
- otherNode = treeIO.readNode(node.getChild(i));
- if (otherNode.getNodeStart() != node.getChildStart(i)) {
- buf.append(" Expected start time of child node #"
- + node.getChild(i) + ": " + node.getChildStart(i)
- + "\n" + " Actual start time of node #"
- + otherNode.getSequenceNumber() + ": "
- + otherNode.getNodeStart() + "\n");
- ret = false;
- }
- }
-
- } catch (ClosedChannelException e) {
- e.printStackTrace();
- }
-
- if (!ret) {
- System.out.println("");
- System.out.println("SHT: Integrity check failed for node #"
- + node.getSequenceNumber() + ":");
- System.out.println(buf.toString());
- }
- return ret;
- }
-
- /**
- * Check the integrity of all the nodes in the tree. Calls
- * {@link #checkNodeIntegrity} for every node in the tree.
- */
- public void checkIntegrity() {
- try {
- for (int i = 0; i < nodeCount; i++) {
- checkNodeIntegrity(treeIO.readNode(i));
- }
- } catch (ClosedChannelException e) {
- }
- }
-
- /* Only used for debugging, shouldn't be externalized */
- @SuppressWarnings("nls")
- @Override
- public String toString() {
- return "Information on the current tree:\n\n" + "Blocksize: "
- + config.getBlockSize() + "\n" + "Max nb. of children per node: "
- + config.getMaxChildren() + "\n" + "Number of nodes: " + nodeCount
- + "\n" + "Depth of the tree: " + latestBranch.size() + "\n"
- + "Size of the treefile: " + this.getFileSize() + "\n"
- + "Root node has sequence number: "
- + latestBranch.get(0).getSequenceNumber() + "\n"
- + "'Latest leaf' has sequence number: "
- + latestBranch.get(latestBranch.size() - 1).getSequenceNumber();
- }
-
- /**
- * Start at currentNode and print the contents of all its children, in
- * pre-order. Give the root node in parameter to visit the whole tree, and
- * have a nice overview.
- */
- /* Only used for debugging, shouldn't be externalized */
- @SuppressWarnings("nls")
- private void preOrderPrint(PrintWriter writer, boolean printIntervals,
- HTNode currentNode, int curDepth) {
-
- writer.println(currentNode.toString());
- if (printIntervals) {
- currentNode.debugPrintIntervals(writer);
- }
-
- switch (currentNode.getNodeType()) {
- case LEAF:
- /* Stop if it's the leaf node */
- return;
-
- case CORE:
- try {
- final CoreNode node = (CoreNode) currentNode;
- /* Print the extensions, if any */
- int extension = node.getExtensionSequenceNumber();
- while (extension != -1) {
- HTNode nextNode = treeIO.readNode(extension);
- preOrderPrint(writer, printIntervals, nextNode, curDepth);
- }
-
- /* Print the child nodes */
- for (int i = 0; i < node.getNbChildren(); i++) {
- HTNode nextNode = treeIO.readNode(node.getChild(i));
- for (int j = 0; j < curDepth; j++) {
- writer.print(" ");
- }
- writer.print("+-");
- preOrderPrint(writer, printIntervals, nextNode, curDepth + 1);
- }
- } catch (ClosedChannelException e) {
- Activator.getDefault().logError(e.getMessage());
- }
- break;
-
- default:
- break;
- }
- }
-
- /**
- * Print out the full tree for debugging purposes
- *
- * @param writer
- * PrintWriter in which to write the output
- * @param printIntervals
- * Flag to enable full output of the interval information
- */
- public void debugPrintFullTree(PrintWriter writer, boolean printIntervals) {
- /* Only used for debugging, shouldn't be externalized */
-
- this.preOrderPrint(writer, false, latestBranch.get(0), 0);
-
- if (printIntervals) {
- writer.println("\nDetails of intervals:"); //$NON-NLS-1$
- this.preOrderPrint(writer, true, latestBranch.get(0), 0);
- }
- writer.println('\n');
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson
- * Copyright (c) 2010, 2011 École Polytechnique de Montréal
- * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- * Patrick Tasse - Add message to exceptions
- *******************************************************************************/
-
-package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.channels.ClosedChannelException;
-import java.util.List;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.CoreNode;
-import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTConfig;
-import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTInterval;
-import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTNode;
-import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HistoryTree;
-import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
-import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
-import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
-import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
-
-/**
- * History Tree backend for storing a state history. This is the basic version
- * that runs in the same thread as the class creating it.
- *
- * @author Alexandre Montplaisir
- */
-public class HistoryTreeBackend implements IStateHistoryBackend {
-
- private final @NonNull String ssid;
-
- /**
- * The history tree that sits underneath.
- */
- private final HistoryTree sht;
-
- /** Indicates if the history tree construction is done */
- private volatile boolean fFinishedBuilding = false;
-
- /**
- * Indicates if the history tree construction is done
- *
- * @return if the history tree construction is done
- */
- protected boolean isFinishedBuilding() {
- return fFinishedBuilding;
- }
-
- /**
- * Sets if the history tree is finished building
- *
- * @param isFinishedBuilding
- * is the history tree finished building
- */
- protected void setFinishedBuilding(boolean isFinishedBuilding) {
- this.fFinishedBuilding = isFinishedBuilding;
- }
-
- /**
- * Constructor for new history files. Use this when creating a new history
- * from scratch.
- *
- * @param ssid
- * The state system's ID
- * @param newStateFile
- * The filename/location where to store the state history (Should
- * end in .ht)
- * @param providerVersion
- * Version of of the state provider. We will only try to reopen
- * existing files if this version matches the one in the
- * framework.
- * @param startTime
- * The earliest time stamp that will be stored in the history
- * @param blockSize
- * The size of the blocks in the history file. This should be a
- * multiple of 4096.
- * @param maxChildren
- * The maximum number of children each core node can have
- * @throws IOException
- * Thrown if we can't create the file for some reason
- */
- public HistoryTreeBackend(@NonNull String ssid,
- File newStateFile,
- int providerVersion,
- long startTime,
- int blockSize,
- int maxChildren) throws IOException {
- this.ssid = ssid;
- final HTConfig conf = new HTConfig(newStateFile, blockSize, maxChildren,
- providerVersion, startTime);
- sht = new HistoryTree(conf);
- }
-
- /**
- * Constructor for new history files. Use this when creating a new history
- * from scratch. This version supplies sane defaults for the configuration
- * parameters.
- *
- * @param ssid
- * The state system's id
- * @param newStateFile
- * The filename/location where to store the state history (Should
- * end in .ht)
- * @param providerVersion
- * Version of of the state provider. We will only try to reopen
- * existing files if this version matches the one in the
- * framework.
- * @param startTime
- * The earliest time stamp that will be stored in the history
- * @throws IOException
- * Thrown if we can't create the file for some reason
- * @since 1.0
- */
- public HistoryTreeBackend(@NonNull String ssid, File newStateFile, int providerVersion, long startTime)
- throws IOException {
- this(ssid, newStateFile, providerVersion, startTime, 64 * 1024, 50);
- }
-
- /**
- * Existing history constructor. Use this to open an existing state-file.
- *
- * @param ssid
- * The state system's id
- * @param existingStateFile
- * Filename/location of the history we want to load
- * @param providerVersion
- * Expected version of of the state provider plugin.
- * @throws IOException
- * If we can't read the file, if it doesn't exist, is not
- * recognized, or if the version of the file does not match the
- * expected providerVersion.
- */
- public HistoryTreeBackend(@NonNull String ssid, File existingStateFile, int providerVersion)
- throws IOException {
- this.ssid = ssid;
- sht = new HistoryTree(existingStateFile, providerVersion);
- fFinishedBuilding = true;
- }
-
- /**
- * Get the History Tree built by this backend.
- *
- * @return The history tree
- */
- protected HistoryTree getSHT() {
- return sht;
- }
-
- @Override
- public String getSSID() {
- return ssid;
- }
-
- @Override
- public long getStartTime() {
- return sht.getTreeStart();
- }
-
- @Override
- public long getEndTime() {
- return sht.getTreeEnd();
- }
-
- @Override
- public void insertPastState(long stateStartTime, long stateEndTime,
- int quark, ITmfStateValue value) throws TimeRangeException {
- HTInterval interval = new HTInterval(stateStartTime, stateEndTime,
- quark, (TmfStateValue) value);
-
- /* Start insertions at the "latest leaf" */
- sht.insertInterval(interval);
- }
-
- @Override
- public void finishedBuilding(long endTime) {
- sht.closeTree(endTime);
- fFinishedBuilding = true;
- }
-
- @Override
- public FileInputStream supplyAttributeTreeReader() {
- return sht.supplyATReader();
- }
-
- @Override
- public File supplyAttributeTreeWriterFile() {
- return sht.supplyATWriterFile();
- }
-
- @Override
- public long supplyAttributeTreeWriterFilePosition() {
- return sht.supplyATWriterFilePos();
- }
-
- @Override
- public void removeFiles() {
- sht.deleteFile();
- }
-
- @Override
- public void dispose() {
- if (fFinishedBuilding) {
- sht.closeFile();
- } else {
- /*
- * The build is being interrupted, delete the file we partially
- * built since it won't be complete, so shouldn't be re-used in the
- * future (.deleteFile() will close the file first)
- */
- sht.deleteFile();
- }
- }
-
- @Override
- public void doQuery(List<ITmfStateInterval> stateInfo, long t)
- throws TimeRangeException, StateSystemDisposedException {
- checkValidTime(t);
-
- /* We start by reading the information in the root node */
- HTNode currentNode = sht.getRootNode();
- currentNode.writeInfoFromNode(stateInfo, t);
-
- /* Then we follow the branch down in the relevant children */
- try {
- while (currentNode.getNodeType() == HTNode.NodeType.CORE) {
- currentNode = sht.selectNextChild((CoreNode) currentNode, t);
- currentNode.writeInfoFromNode(stateInfo, t);
- }
- } catch (ClosedChannelException e) {
- throw new StateSystemDisposedException(e);
- }
-
- /*
- * The stateInfo should now be filled with everything needed, we pass
- * the control back to the State System.
- */
- return;
- }
-
- @Override
- public ITmfStateInterval doSingularQuery(long t, int attributeQuark)
- throws TimeRangeException, StateSystemDisposedException {
- return getRelevantInterval(t, attributeQuark);
- }
-
- private void checkValidTime(long t) {
- long treeStart = sht.getTreeStart();
- long treeEnd = sht.getTreeEnd();
- if (t < treeStart || t > treeEnd) {
- throw new TimeRangeException(ssid + " Time:" + t + ", Start:" + treeStart + ", End:" + treeEnd); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
- }
-
- /**
- * Inner method to find the interval in the tree containing the requested
- * key/timestamp pair, wherever in which node it is.
- *
- * @param t
- * @param key
- * @return The node containing the information we want
- */
- private HTInterval getRelevantInterval(long t, int key)
- throws TimeRangeException, StateSystemDisposedException {
- checkValidTime(t);
-
- HTNode currentNode = sht.getRootNode();
- HTInterval interval = currentNode.getRelevantInterval(key, t);
-
- try {
- while (interval == null && currentNode.getNodeType() == HTNode.NodeType.CORE) {
- currentNode = sht.selectNextChild((CoreNode) currentNode, t);
- interval = currentNode.getRelevantInterval(key, t);
- }
- } catch (ClosedChannelException e) {
- throw new StateSystemDisposedException(e);
- }
- return interval;
- }
-
- /**
- * Return the size of the tree history file
- *
- * @return The current size of the history file in bytes
- */
- public long getFileSize() {
- return sht.getFileSize();
- }
-
- /**
- * Return the average node usage as a percentage (between 0 and 100)
- *
- * @return Average node usage %
- */
- public int getAverageNodeUsage() {
- HTNode node;
- long total = 0;
- long ret;
-
- try {
- for (int seq = 0; seq < sht.getNodeCount(); seq++) {
- node = sht.readNode(seq);
- total += node.getNodeUsagePercent();
- }
- } catch (ClosedChannelException e) {
- e.printStackTrace();
- }
-
- ret = total / sht.getNodeCount();
- assert (ret >= 0 && ret <= 100);
- return (int) ret;
- }
-
- @Override
- public void debugPrint(PrintWriter writer) {
- /* By default don't print out all the intervals */
- this.debugPrint(writer, false);
- }
-
- /**
- * The basic debugPrint method will print the tree structure, but not their
- * contents.
- *
- * This method here print the contents (the intervals) as well.
- *
- * @param writer
- * The PrintWriter to which the debug info will be written
- * @param printIntervals
- * Should we also print every contained interval individually?
- */
- public void debugPrint(PrintWriter writer, boolean printIntervals) {
- /* Only used for debugging, shouldn't be externalized */
- writer.println("------------------------------"); //$NON-NLS-1$
- writer.println("State History Tree:\n"); //$NON-NLS-1$
- writer.println(sht.toString());
- writer.println("Average node utilization: " //$NON-NLS-1$
- + this.getAverageNodeUsage());
- writer.println(""); //$NON-NLS-1$
-
- sht.debugPrintFullTree(writer, printIntervals);
- }
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2014 École Polytechnique de Montréal
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Florian Wininger - Initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;
-
-import java.nio.ByteBuffer;
-
-/**
- * A Leaf node is a last-level node of a History Tree.
- *
- * A leaf node cannot have children, so it extends HTNode without adding
- * anything in particular.
- *
- * @author Florian Wininger
- */
-public final class LeafNode extends HTNode {
-
- /**
- * Initial constructor. Use this to initialize a new EMPTY node.
- *
- * @param config
- * Configuration of the History Tree
- * @param seqNumber
- * The (unique) sequence number assigned to this particular node
- * @param parentSeqNumber
- * The sequence number of this node's parent node
- * @param start
- * The earliest timestamp stored in this node
- */
- public LeafNode(HTConfig config, int seqNumber, int parentSeqNumber,
- long start) {
- super(config, seqNumber, parentSeqNumber, start);
- }
-
- @Override
- protected void readSpecificHeader(ByteBuffer buffer) {
- /* No specific header part */
- }
-
- @Override
- protected void writeSpecificHeader(ByteBuffer buffer) {
- /* No specific header part */
- }
-
- @Override
- public NodeType getNodeType() {
- return NodeType.LEAF;
- }
-
- @Override
- protected int getSpecificHeaderSize() {
- /* Empty */
- return 0;
- }
-
- @Override
- public String toStringSpecific() {
- /* Only used for debugging, shouldn't be externalized */
- return "Leaf Node, "; //$NON-NLS-1$;
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson
- * Copyright (c) 2010, 2011 École Polytechnique de Montréal
- * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.tracecompass.common.core.collect.BufferedBlockingQueue;
-import org.eclipse.tracecompass.internal.statesystem.core.Activator;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
-import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
-import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
-import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
-
-/**
- * Variant of the HistoryTreeBackend which runs all the interval-insertion logic
- * in a separate thread.
- *
- * @author Alexandre Montplaisir
- */
-public final class ThreadedHistoryTreeBackend extends HistoryTreeBackend
- implements Runnable {
-
- private static final int CHUNK_SIZE = 127;
- private final @NonNull BufferedBlockingQueue<HTInterval> intervalQueue;
- private final @NonNull Thread shtThread;
-
- /**
- * New state history constructor
- *
- * Note that it usually doesn't make sense to use a Threaded HT if you're
- * opening an existing state-file, but you know what you're doing...
- *
- * @param ssid
- * The state system's id
- * @param newStateFile
- * The name of the history file that will be created. Should end
- * in ".ht"
- * @param providerVersion
- * Version of of the state provider. We will only try to reopen
- * existing files if this version matches the one in the
- * framework.
- * @param startTime
- * The earliest timestamp stored in the history
- * @param queueSize
- * The size of the interval insertion queue. 2000 - 10000 usually
- * works well
- * @param blockSize
- * The size of the blocks in the file
- * @param maxChildren
- * The maximum number of children allowed for each core node
- * @throws IOException
- * If there was a problem opening the history file for writing
- */
- public ThreadedHistoryTreeBackend(@NonNull String ssid,
- File newStateFile,
- int providerVersion,
- long startTime,
- int queueSize,
- int blockSize,
- int maxChildren)
- throws IOException {
- super(ssid, newStateFile, providerVersion, startTime, blockSize, maxChildren);
-
- intervalQueue = new BufferedBlockingQueue<>(queueSize / CHUNK_SIZE, CHUNK_SIZE);
- shtThread = new Thread(this, "History Tree Thread"); //$NON-NLS-1$
- shtThread.start();
- }
-
- /**
- * New State History constructor. This version provides default values for
- * blockSize and maxChildren.
- *
- * @param ssid
- * The state system's id
- * @param newStateFile
- * The name of the history file that will be created. Should end
- * in ".ht"
- * @param providerVersion
- * Version of of the state provider. We will only try to reopen
- * existing files if this version matches the one in the
- * framework.
- * @param startTime
- * The earliest timestamp stored in the history
- * @param queueSize
- * The size of the interval insertion queue. 2000 - 10000 usually
- * works well
- * @throws IOException
- * If there was a problem opening the history file for writing
- */
- public ThreadedHistoryTreeBackend(@NonNull String ssid,
- File newStateFile,
- int providerVersion,
- long startTime,
- int queueSize)
- throws IOException {
- super(ssid, newStateFile, providerVersion, startTime);
-
- intervalQueue = new BufferedBlockingQueue<>(queueSize / CHUNK_SIZE, CHUNK_SIZE);
- shtThread = new Thread(this, "History Tree Thread"); //$NON-NLS-1$
- shtThread.start();
- }
-
- /*
- * The Threaded version does not specify an "existing file" constructor,
- * since the history is already built (and we only use the other thread
- * during building). Just use a plain HistoryTreeProvider in this case.
- *
- * TODO but what about streaming??
- */
-
- @Override
- public void insertPastState(long stateStartTime, long stateEndTime,
- int quark, ITmfStateValue value) throws TimeRangeException {
- /*
- * Here, instead of directly inserting the elements in the History Tree
- * underneath, we'll put them in the Queue. They will then be taken and
- * processed by the other thread executing the run() method.
- */
- HTInterval interval = new HTInterval(stateStartTime, stateEndTime,
- quark, (TmfStateValue) value);
- intervalQueue.put(interval);
- }
-
- @Override
- public void finishedBuilding(long endTime) {
- /*
- * We need to commit everything in the History Tree and stop the
- * standalone thread before returning to the StateHistorySystem. (SHS
- * will then write the Attribute Tree to the file, that must not happen
- * at the same time we are writing the last nodes!)
- */
-
- stopRunningThread(endTime);
- setFinishedBuilding(true);
- return;
- }
-
- @Override
- public void dispose() {
- if (!isFinishedBuilding()) {
- stopRunningThread(Long.MAX_VALUE);
- }
- /*
- * isFinishedBuilding remains false, so the superclass will ask the
- * back-end to delete the file.
- */
- super.dispose();
- }
-
- private void stopRunningThread(long endTime) {
- if (!shtThread.isAlive()) {
- return;
- }
-
- /*
- * Send a "poison pill" in the queue, then wait for the HT to finish its
- * closeTree()
- */
- try {
- HTInterval pill = new HTInterval(-1, endTime, -1, TmfStateValue.nullValue());
- intervalQueue.put(pill);
- intervalQueue.flushInputBuffer();
- shtThread.join();
- } catch (TimeRangeException e) {
- Activator.getDefault().logError("Error closing state system", e); //$NON-NLS-1$
- } catch (InterruptedException e) {
- Activator.getDefault().logError("State system interrupted", e); //$NON-NLS-1$
- }
- }
-
- @Override
- public void run() {
- HTInterval currentInterval;
- try {
- currentInterval = intervalQueue.take();
- while (currentInterval.getStartTime() != -1) {
- /* Send the interval to the History Tree */
- getSHT().insertInterval(currentInterval);
- currentInterval = intervalQueue.take();
- }
- if (currentInterval.getAttribute() != -1) {
- /* Make sure this is the "poison pill" we are waiting for */
- throw new IllegalStateException();
- }
- /*
- * We've been told we're done, let's write down everything and quit.
- * The end time of this "signal interval" is actually correct.
- */
- getSHT().closeTree(currentInterval.getEndTime());
- return;
- } catch (TimeRangeException e) {
- /* This should not happen */
- Activator.getDefault().logError("Error starting the state system", e); //$NON-NLS-1$
- }
- }
-
- // ------------------------------------------------------------------------
- // Query methods
- // ------------------------------------------------------------------------
-
- @Override
- public void doQuery(List<ITmfStateInterval> currentStateInfo, long t)
- throws TimeRangeException, StateSystemDisposedException {
- super.doQuery(currentStateInfo, t);
-
- if (isFinishedBuilding()) {
- /*
- * The history tree is the only place to look for intervals once
- * construction is finished.
- */
- return;
- }
-
- /*
- * It is possible we may have missed some intervals due to them being in
- * the queue while the query was ongoing. Go over the results to see if
- * we missed any.
- */
- for (int i = 0; i < currentStateInfo.size(); i++) {
- if (currentStateInfo.get(i) == null) {
- /* Query the missing interval via "unicast" */
- ITmfStateInterval interval = doSingularQuery(t, i);
- currentStateInfo.set(i, interval);
- }
- }
- }
-
- @Override
- public ITmfStateInterval doSingularQuery(long t, int attributeQuark)
- throws TimeRangeException, StateSystemDisposedException {
- ITmfStateInterval ret = super.doSingularQuery(t, attributeQuark);
- if (ret != null) {
- return ret;
- }
-
- /*
- * We couldn't find the interval in the history tree. It's possible that
- * it is currently in the intervalQueue. Look for it there. Note that
- * BufferedBlockingQueue's iterator() is thread-safe (no need to lock
- * the queue).
- */
- for (ITmfStateInterval interval : intervalQueue) {
- if (interval.getAttribute() == attributeQuark && interval.intersects(t)) {
- return interval;
- }
- }
-
- /*
- * If we missed it again, it's because it got inserted in the tree
- * *while we were iterating* on the queue. One last pass in the tree
- * should find it.
- *
- * This case is really rare, which is why we do a second pass at the end
- * if needed, instead of systematically checking in the queue first
- * (which is slow).
- */
- return super.doSingularQuery(t, attributeQuark);
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson and others.
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API
- ******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core;
-
-import java.util.List;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
-import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
-import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
-
-
-/**
- * This is the read-only interface to the generic state system. It contains all
- * the read-only quark-getting methods, as well as the history-querying ones.
- *
- * @author Alexandre Montplaisir
- * @noimplement Only the internal StateSystem class should implement this
- * interface.
- */
-public interface ITmfStateSystem {
-
- /**
- * Get the ID of this state system.
- *
- * @return The state system's ID
- */
- String getSSID();
-
- /**
- * Return the start time of this history. It usually matches the start time
- * of the original trace.
- *
- * @return The history's registered start time
- */
- long getStartTime();
-
- /**
- * Return the current end time of the history.
- *
- * @return The current end time of this state history
- */
- long getCurrentEndTime();
-
- /**
- * Check if the construction of this state system was cancelled or not. If
- * false is returned, it can mean that the building was finished
- * successfully, or that it is still ongoing. You can check independently
- * with {@link #waitUntilBuilt()} if it is finished or not.
- *
- * @return If the construction was cancelled or not. In true is returned, no
- * queries should be run afterwards.
- */
- boolean isCancelled();
-
- /**
- * While it's possible to query a state history that is being built,
- * sometimes we might want to wait until the construction is finished before
- * we start doing queries.
- *
- * This method blocks the calling thread until the history back-end is done
- * building. If it's already built (ie, opening a pre-existing file) this
- * should return immediately.
- *
- * You should always check with {@link #isCancelled()} if it is safe to
- * query this state system before doing queries.
- */
- void waitUntilBuilt();
-
- /**
- * Wait until the state system construction is finished. Similar to
- * {@link #waitUntilBuilt()}, but we also specify a timeout. If the timeout
- * elapses before the construction is finished, the method will return.
- *
- * The return value determines if the return was due to the construction
- * finishing (true), or the timeout elapsing (false).
- *
- * This can be useful, for example, for a component doing queries
- * periodically to the system while it is being built.
- *
- * @param timeout
- * Timeout value in milliseconds
- * @return True if the return was due to the construction finishing, false
- * if it was because the timeout elapsed. Same logic as
- * {@link java.util.concurrent.CountDownLatch#await(long, java.util.concurrent.TimeUnit)}
- */
- boolean waitUntilBuilt(long timeout);
-
- /**
- * Notify the state system that the trace is being closed, so it should
- * clean up, close its files, etc.
- */
- void dispose();
-
- // ------------------------------------------------------------------------
- // Read-only quark-getting methods
- // ------------------------------------------------------------------------
-
- /**
- * Return the current total amount of attributes in the system. This is also
- * equal to the quark that will be assigned to the next attribute that's
- * created.
- *
- * @return The current number of attributes in the system
- */
- int getNbAttributes();
-
- /**
- * Basic quark-retrieving method. Pass an attribute in parameter as an array
- * of strings, the matching quark will be returned.
- *
- * This version will NOT create any new attributes. If an invalid attribute
- * is requested, an exception will be thrown.
- *
- * @param attribute
- * Attribute given as its full path in the Attribute Tree
- * @return The quark of the requested attribute, if it existed.
- * @throws AttributeNotFoundException
- * This exception is thrown if the requested attribute simply
- * did not exist in the system.
- */
- int getQuarkAbsolute(String... attribute)
- throws AttributeNotFoundException;
-
- /**
- * "Relative path" quark-getting method. Instead of specifying a full path,
- * if you know the path is relative to another attribute for which you
- * already have the quark, use this for better performance.
- *
- * This is useful for cases where a lot of modifications or queries will
- * originate from the same branch of the attribute tree : the common part of
- * the path won't have to be re-hashed for every access.
- *
- * This version will NOT create any new attributes. If an invalid attribute
- * is requested, an exception will be thrown.
- *
- * @param startingNodeQuark
- * The quark of the attribute from which 'subPath' originates.
- * @param subPath
- * "Rest" of the path to get to the final attribute
- * @return The matching quark, if it existed
- * @throws IndexOutOfBoundsException
- * If the starting node quark is out of range
- * @throws AttributeNotFoundException
- * If the sub-attribute does not exist
- */
- int getQuarkRelative(int startingNodeQuark, String... subPath)
- throws AttributeNotFoundException;
-
- /**
- * Return the sub-attributes of the target attribute, as a List of quarks.
- *
- * @param quark
- * The attribute of which you want to sub-attributes. You can use
- * "-1" here to specify the root node.
- * @param recursive
- * True if you want all recursive sub-attributes, false if you
- * only want the first level.
- * @return A List of integers, matching the quarks of the sub-attributes.
- * @throws AttributeNotFoundException
- * If the quark was not existing or invalid.
- */
- @NonNull List<Integer> getSubAttributes(int quark, boolean recursive)
- throws AttributeNotFoundException;
-
- /**
- * Return the sub-attributes of the target attribute, as a List of quarks,
- * similarly to {@link #getSubAttributes(int, boolean)}, but with an added
- * regex pattern to filter on the return attributes.
- *
- * @param quark
- * The attribute of which you want to sub-attributes. You can use
- * "-1" here to specify the root node.
- * @param recursive
- * True if you want all recursive sub-attributes, false if you
- * only want the first level. Note that the returned value will
- * be flattened.
- * @param pattern
- * The regular expression to match the attribute base name.
- * @return A List of integers, matching the quarks of the sub-attributes
- * that match the regex. An empty list is returned if there is no
- * matching attribute.
- * @throws AttributeNotFoundException
- * If the 'quark' was not existing or invalid.
- */
- List<Integer> getSubAttributes(int quark, boolean recursive, String pattern)
- throws AttributeNotFoundException;
-
- /**
- * Batch quark-retrieving method. This method allows you to specify a path
- * pattern which includes a wildcard "*" somewhere. It will check all the
- * existing attributes in the attribute tree and return those who match the
- * pattern.
- *
- * For example, passing ("Threads", "*", "Exec_mode") will return the list
- * of quarks for attributes "Threads/1000/Exec_mode",
- * "Threads/1500/Exec_mode", and so on, depending on what exists at this
- * time in the attribute tree.
- *
- * If no wildcard is specified, the behavior is the same as
- * getQuarkAbsolute() (except it will return a List with one entry). This
- * method will never create new attributes.
- *
- * Only one wildcard "*" is supported at this time.
- *
- * @param pattern
- * The array of strings representing the pattern to look for. It
- * should ideally contain one entry that is only a "*".
- * @return A List of attribute quarks, representing attributes that matched
- * the pattern. If no attribute matched, the list will be empty (but
- * not null).
- */
- List<Integer> getQuarks(String... pattern);
-
- /**
- * Return the name assigned to this quark. This returns only the "basename",
- * not the complete path to this attribute.
- *
- * @param attributeQuark
- * The quark for which we want the name
- * @return The name of the quark
- * @throws IndexOutOfBoundsException
- * If the attribute quark is out of range
- */
- @NonNull String getAttributeName(int attributeQuark);
-
- /**
- * This returns the slash-separated path of an attribute by providing its
- * quark
- *
- * @param attributeQuark
- * The quark of the attribute we want
- * @return One single string separated with '/', like a filesystem path
- * @throws IndexOutOfBoundsException
- * If the attribute quark is out of range
- */
- @NonNull String getFullAttributePath(int attributeQuark);
-
- /**
- * Return the full attribute path, as an array of strings representing each
- * element.
- *
- * @param attributeQuark
- * The quark of the attribute we want.
- * @return The array of path elements
- * @throws IndexOutOfBoundsException
- * If the attribute quark is out of range
- * @since 1.0
- */
- @NonNull String[] getFullAttributePathArray(int attributeQuark);
-
- /**
- * Returns the parent quark of the attribute.
- *
- * @param attributeQuark
- * The quark of the attribute
- * @return Quark of the parent attribute or <code>-1</code> if root quark or
- * no parent.
- * @throws IndexOutOfBoundsException
- * If the attribute quark is out of range
- */
- int getParentAttributeQuark(int attributeQuark);
-
- // ------------------------------------------------------------------------
- // Query methods
- // ------------------------------------------------------------------------
-
- /**
- * Returns the current state value we have (in the Transient State) for the
- * given attribute.
- *
- * This is useful even for a StateHistorySystem, as we are guaranteed it
- * will only do a memory access and not go look on disk (and we don't even
- * have to provide a timestamp!)
- *
- * @param attributeQuark
- * For which attribute we want the current state
- * @return The State value that's "current" for this attribute
- * @throws AttributeNotFoundException
- * If the requested attribute is invalid
- */
- ITmfStateValue queryOngoingState(int attributeQuark)
- throws AttributeNotFoundException;
-
- /**
- * Get the start time of the current ongoing state, for the specified
- * attribute.
- *
- * @param attribute
- * Quark of the attribute
- * @return The current start time of the ongoing state
- * @throws AttributeNotFoundException
- * If the attribute is invalid
- */
- long getOngoingStartTime(int attribute)
- throws AttributeNotFoundException;
-
- /**
- * Load the complete state information at time 't' into the returned List.
- * You can then get the intervals for single attributes by using
- * List.get(n), where 'n' is the quark of the attribute.
- *
- * On average if you need around 10 or more queries for the same timestamps,
- * use this method. If you need less than 10 (for example, running many
- * queries for the same attributes but at different timestamps), you might
- * be better using the querySingleState() methods instead.
- *
- * @param t
- * We will recreate the state information to what it was at time
- * t.
- * @return The List of intervals, where the offset = the quark
- * @throws TimeRangeException
- * If the 't' parameter is outside of the range of the state
- * history.
- * @throws StateSystemDisposedException
- * If the query is sent after the state system has been disposed
- */
- @NonNull List<ITmfStateInterval> queryFullState(long t)
- throws StateSystemDisposedException;
-
- /**
- * Singular query method. This one does not update the whole stateInfo
- * vector, like queryFullState() does. It only searches for one specific
- * entry in the state history.
- *
- * It should be used when you only want very few entries, instead of the
- * whole state (or many entries, but all at different timestamps). If you do
- * request many entries all at the same time, you should use the
- * conventional queryFullState() + List.get() method.
- *
- * @param t
- * The timestamp at which we want the state
- * @param attributeQuark
- * Which attribute we want to get the state of
- * @return The StateInterval representing the state
- * @throws TimeRangeException
- * If 't' is invalid
- * @throws AttributeNotFoundException
- * If the requested quark does not exist in the model
- * @throws StateSystemDisposedException
- * If the query is sent after the state system has been disposed
- */
- @NonNull ITmfStateInterval querySingleState(long t, int attributeQuark)
- throws AttributeNotFoundException, StateSystemDisposedException;
-}
\ No newline at end of file
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2014 Ericsson
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API
- ******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
-import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
-
-/**
- * This is the external interface to build or modify an existing state history.
- *
- * It extends ITmfStateSystem, so you can still use it for reading the history,
- * but it also provides write-access to it with the quark-creating and
- * state-change insertion methods.
- *
- * This should only be used by classes that need to build or modify the state
- * history. Views, etc. (who will only be reading from it) should use the
- * ITmfStateSystem interface instead.
- *
- * @author Alexandre Montplaisir
- * @noimplement Only the internal StateSystem class should implement this
- * interface.
- */
-public interface ITmfStateSystemBuilder extends ITmfStateSystem {
-
- /**
- * Special state provider version number that will tell the backend to
- * ignore the version check and open an existing file even if the versions
- * don't match.
- */
- int IGNORE_PROVIDER_VERSION = -42;
-
- /**
- * @name Read/write quark-getting methods
- */
-
- /**
- * Basic quark-retrieving method. Pass an attribute in parameter as an array
- * of strings, the matching quark will be returned.
- *
- * This version WILL create new attributes: if the attribute passed in
- * parameter is new in the system, it will be added and its new quark will
- * be returned.
- *
- * @param attribute
- * Attribute given as its full path in the Attribute Tree
- * @return The quark of the attribute (which either existed or just got
- * created)
- */
- int getQuarkAbsoluteAndAdd(String... attribute);
-
- /**
- * "Relative path" quark-getting method. Instead of specifying a full path,
- * if you know the path is relative to another attribute for which you
- * already have the quark, use this for better performance.
- *
- * This is useful for cases where a lot of modifications or queries will
- * originate from the same branch of the attribute tree : the common part of
- * the path won't have to be re-hashed for every access.
- *
- * This version WILL create new attributes: if the attribute passed in
- * parameter is new in the system, it will be added and its new quark will
- * be returned.
- *
- * @param startingNodeQuark
- * The quark of the attribute from which 'subPath' originates.
- * @param subPath
- * "Rest" of the path to get to the final attribute
- * @return The matching quark, either if it's new of just got created.
- */
- int getQuarkRelativeAndAdd(int startingNodeQuark, String... subPath);
-
- /**
- * @name State-changing methods
- */
-
- /**
- * Modify a current "ongoing" state (instead of inserting a state change,
- * like modifyAttribute() and others).
- *
- * This can be used to update the value of a previous state change, for
- * example when we get information at the end of the state and not at the
- * beginning. (return values of system calls, etc.)
- *
- * Note that past states can only be modified while they are still in
- * memory, so only the "current state" can be updated. Once they get
- * committed to disk (by inserting a new state change) it becomes too late.
- *
- * @param newValue
- * The new value that will overwrite the "current" one.
- * @param attributeQuark
- * For which attribute in the system
- * @throws AttributeNotFoundException
- * If the requested attribute is invalid
- */
- void updateOngoingState(@NonNull ITmfStateValue newValue, int attributeQuark)
- throws AttributeNotFoundException;
-
- /**
- * Basic attribute modification method, we simply specify a new value, for a
- * given attribute, effective at the given timestamp.
- *
- * @param t
- * Timestamp of the state change
- * @param value
- * The State Value we want to assign to the attribute
- * @param attributeQuark
- * Integer value of the quark corresponding to the attribute we
- * want to modify
- * @throws TimeRangeException
- * If the requested time is outside of the trace's range
- * @throws AttributeNotFoundException
- * If the requested attribute quark is invalid
- * @throws StateValueTypeException
- * If the inserted state value's type does not match what is
- * already assigned to this attribute.
- */
- void modifyAttribute(long t, ITmfStateValue value, int attributeQuark)
- throws AttributeNotFoundException, StateValueTypeException;
-
- /**
- * Increment attribute method. Reads the current value of a given integer
- * attribute (this value is right now in the Transient State), and increment
- * it by 1. Useful for statistics.
- *
- * @param t
- * Timestamp of the state change
- * @param attributeQuark
- * Attribute to increment. If it doesn't exist it will be added,
- * with a new value of 1.
- * @throws StateValueTypeException
- * If the attribute already exists but is not of type Integer
- * @throws TimeRangeException
- * If the given timestamp is invalid
- * @throws AttributeNotFoundException
- * If the quark is invalid
- */
- void incrementAttribute(long t, int attributeQuark)
- throws AttributeNotFoundException, StateValueTypeException;
-
- /**
- * "Push" helper method. This uses the given integer attribute as a stack:
- * The value of that attribute will represent the stack depth (always >= 1).
- * Sub-attributes will be created, their base-name will be the position in
- * the stack (1, 2, etc.) and their value will be the state value 'value'
- * that was pushed to this position.
- *
- * @param t
- * Timestamp of the state change
- * @param value
- * State value to assign to this stack position.
- * @param attributeQuark
- * The base attribute to use as a stack. If it does not exist if
- * will be created (with depth = 1)
- * @throws TimeRangeException
- * If the requested timestamp is invalid
- * @throws AttributeNotFoundException
- * If the attribute is invalid
- * @throws StateValueTypeException
- * If the attribute 'attributeQuark' already exists, but is not
- * of integer type.
- */
- void pushAttribute(long t, ITmfStateValue value, int attributeQuark)
- throws AttributeNotFoundException, StateValueTypeException;
-
- /**
- * Antagonist of the pushAttribute(), pops the top-most attribute on the
- * stack-attribute. If this brings it back to depth = 0, the attribute is
- * kept with depth = 0. If the value is already 0, or if the attribute
- * doesn't exist, nothing is done.
- *
- * @param t
- * Timestamp of the state change
- * @param attributeQuark
- * Quark of the stack-attribute to pop
- * @return The state value that was popped, or 'null' if nothing was
- * actually removed from the stack.
- * @throws AttributeNotFoundException
- * If the attribute is invalid
- * @throws TimeRangeException
- * If the timestamp is invalid
- * @throws StateValueTypeException
- * If the target attribute already exists, but its state value
- * type is invalid (not an integer)
- */
- ITmfStateValue popAttribute(long t, int attributeQuark)
- throws AttributeNotFoundException, StateValueTypeException;
-
- /**
- * Remove attribute method. Similar to the above modify- methods, with value
- * = 0 / null, except we will also "nullify" all the sub-contents of the
- * requested path (a bit like "rm -rf")
- *
- * @param t
- * Timestamp of the state change
- * @param attributeQuark
- * Attribute to remove
- * @throws TimeRangeException
- * If the timestamp is invalid
- * @throws AttributeNotFoundException
- * If the quark is invalid
- */
- void removeAttribute(long t, int attributeQuark)
- throws AttributeNotFoundException;
-
- /**
- * Method to close off the History Provider. This happens for example when
- * we are done reading an off-line trace. First we close the TransientState,
- * commit it to the Provider, mark it as inactive, then we write the
- * Attribute Tree somewhere so we can reopen it later.
- *
- * @param endTime
- * The requested End Time of the history, since it could be
- * bigger than the timestamp of the last event or state change we
- * have seen. All "ongoing" states will be extended until this
- * 'endTime'.
- * @throws TimeRangeException
- * If the passed endTime doesn't make sense (for example, if
- * it's earlier than the latest time) and the backend doesn't
- * know how to handle it.
- */
- void closeHistory(long endTime);
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2014 Ericsson
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- ******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core;
-
-import java.io.IOException;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.tracecompass.internal.statesystem.core.StateSystem;
-import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
-
-/**
- * Factory to create state systems.
- *
- * Since state system are meant to be accessed using the {@link ITmfStateSystem}
- * and {@link ITmfStateSystemBuilder} interfaces, you can use this factory to
- * instantiate new ones.
- *
- * @author Alexandre Montplaisir
- */
-@NonNullByDefault
-public final class StateSystemFactory {
-
- private StateSystemFactory() {}
-
- /**
- * New-file factory method. For when you build a state system with a new
- * file, or if the back-end does not require a file on disk.
- *
- * @param backend
- * Back-end plugin to use
- * @return The new state system
- * @since 1.0
- */
- public static ITmfStateSystemBuilder newStateSystem(IStateHistoryBackend backend) {
- return new StateSystem(backend);
- }
-
- /**
- * General factory method. The backend may try to open or create a file on
- * disk (the file contents and location are defined by the backend).
- *
- * @param backend
- * The "state history storage" back-end to use.
- * @param newFile
- * Put true if this is a new history started from scratch (any
- * existing file will be overwritten).
- * @return The new state system
- * @throws IOException
- * If there was a problem creating the new history file
- * @since 1.0
- */
- public static ITmfStateSystemBuilder newStateSystem(IStateHistoryBackend backend,
- boolean newFile) throws IOException {
- return new StateSystem(backend, newFile);
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2014, 2015 École Polytechnique de Montréal
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Geneviève Bastien - Initial API and implementation
- * Alexandre Montplaisir - Initial API and implementation
- * Patrick Tasse - Add message to exceptions
- *******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
-import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
-import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
-
-/**
- * Provide utility methods for the state system
- *
- * @author Geneviève Bastien
- */
-@NonNullByDefault
-public final class StateSystemUtils {
-
- private StateSystemUtils() {
- }
-
- /**
- * Convenience method to query attribute stacks (created with
- * pushAttribute()/popAttribute()). This will return the interval that is
- * currently at the top of the stack, or 'null' if that stack is currently
- * empty. It works similarly to querySingleState().
- *
- * To retrieve the other values in a stack, you can query the sub-attributes
- * manually.
- *
- * @param ss
- * The state system to query
- * @param t
- * The timestamp of the query
- * @param stackAttributeQuark
- * The top-level stack-attribute (that was the target of
- * pushAttribute() at creation time)
- * @return The interval that was at the top of the stack, or 'null' if the
- * stack was empty.
- * @throws StateValueTypeException
- * If the target attribute is not a valid stack attribute (if it
- * has a string value for example)
- * @throws AttributeNotFoundException
- * If the attribute was simply not found
- * @throws TimeRangeException
- * If the given timestamp is invalid
- * @throws StateSystemDisposedException
- * If the query is sent after the state system has been disposed
- */
- public static @Nullable ITmfStateInterval querySingleStackTop(ITmfStateSystem ss,
- long t, int stackAttributeQuark)
- throws AttributeNotFoundException, StateSystemDisposedException {
- ITmfStateValue curStackStateValue = ss.querySingleState(t, stackAttributeQuark).getStateValue();
-
- if (curStackStateValue.isNull()) {
- /* There is nothing stored in this stack at this moment */
- return null;
- }
- int curStackDepth = curStackStateValue.unboxInt();
- if (curStackDepth <= 0) {
- /*
- * This attribute is an integer attribute, but it doesn't seem like
- * it's used as a stack-attribute...
- */
- throw new StateValueTypeException(ss.getSSID() + " Quark:" + stackAttributeQuark + ", Stack depth:" + curStackDepth); //$NON-NLS-1$//$NON-NLS-2$
- }
-
- int subAttribQuark = ss.getQuarkRelative(stackAttributeQuark, String.valueOf(curStackDepth));
- return ss.querySingleState(t, subAttribQuark);
- }
-
- /**
- * Return a list of state intervals, containing the "history" of a given
- * attribute between timestamps t1 and t2. The list will be ordered by
- * ascending time.
- *
- * Note that contrary to queryFullState(), the returned list here is in the
- * "direction" of time (and not in the direction of attributes, as is the
- * case with queryFullState()).
- *
- * @param ss
- * The state system to query
- * @param attributeQuark
- * Which attribute this query is interested in
- * @param t1
- * Start time of the range query
- * @param t2
- * Target end time of the query. If t2 is greater than the end of
- * the trace, we will return what we have up to the end of the
- * history.
- * @return The List of state intervals that happened between t1 and t2
- * @throws TimeRangeException
- * If t1 is invalid, or if t2 <= t1
- * @throws AttributeNotFoundException
- * If the requested quark does not exist in the model.
- * @throws StateSystemDisposedException
- * If the query is sent after the state system has been disposed
- */
- public static List<ITmfStateInterval> queryHistoryRange(ITmfStateSystem ss,
- int attributeQuark, long t1, long t2)
- throws AttributeNotFoundException, StateSystemDisposedException {
-
- List<ITmfStateInterval> intervals;
- ITmfStateInterval currentInterval;
- long ts, tEnd;
-
- /* Make sure the time range makes sense */
- if (t2 < t1) {
- throw new TimeRangeException(ss.getSSID() + " Start:" + t1 + ", End:" + t2); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /* Set the actual, valid end time of the range query */
- if (t2 > ss.getCurrentEndTime()) {
- tEnd = ss.getCurrentEndTime();
- } else {
- tEnd = t2;
- }
-
- /* Get the initial state at time T1 */
- intervals = new ArrayList<>();
- currentInterval = ss.querySingleState(t1, attributeQuark);
- intervals.add(currentInterval);
-
- /* Get the following state changes */
- ts = currentInterval.getEndTime();
- while (ts != -1 && ts < tEnd) {
- ts++; /* To "jump over" to the next state in the history */
- currentInterval = ss.querySingleState(ts, attributeQuark);
- intervals.add(currentInterval);
- ts = currentInterval.getEndTime();
- }
- return intervals;
- }
-
- /**
- * Return the state history of a given attribute, but with at most one
- * update per "resolution". This can be useful for populating views (where
- * it's useless to have more than one query per pixel, for example). A
- * progress monitor can be used to cancel the query before completion.
- *
- * @param ss
- * The state system to query
- * @param attributeQuark
- * Which attribute this query is interested in
- * @param t1
- * Start time of the range query
- * @param t2
- * Target end time of the query. If t2 is greater than the end of
- * the trace, we will return what we have up to the end of the
- * history.
- * @param resolution
- * The "step" of this query
- * @param monitor
- * A progress monitor. If the monitor is canceled during a query,
- * we will return what has been found up to that point. You can
- * use "null" if you do not want to use one.
- * @return The List of states that happened between t1 and t2
- * @throws TimeRangeException
- * If t1 is invalid, if t2 <= t1, or if the resolution isn't
- * greater than zero.
- * @throws AttributeNotFoundException
- * If the attribute doesn't exist
- * @throws StateSystemDisposedException
- * If the query is sent after the state system has been disposed
- */
- public static List<ITmfStateInterval> queryHistoryRange(ITmfStateSystem ss,
- int attributeQuark, long t1, long t2, long resolution,
- @Nullable IProgressMonitor monitor)
- throws AttributeNotFoundException, StateSystemDisposedException {
- List<ITmfStateInterval> intervals = new LinkedList<>();
- ITmfStateInterval currentInterval = null;
- long ts, tEnd;
-
- /* Make sure the time range makes sense */
- if (t2 < t1 || resolution <= 0) {
- throw new TimeRangeException(ss.getSSID() + " Start:" + t1 + ", End:" + t2 + ", Resolution:" + resolution); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
-
- /* Set the actual, valid end time of the range query */
- if (t2 > ss.getCurrentEndTime()) {
- tEnd = ss.getCurrentEndTime();
- } else {
- tEnd = t2;
- }
-
- IProgressMonitor mon = monitor;
- if (mon == null) {
- mon = new NullProgressMonitor();
- }
-
- /*
- * Iterate over the "resolution points". We skip unneeded queries in the
- * case the current interval is longer than the resolution.
- */
- for (ts = t1; ts <= tEnd; ts += ((currentInterval.getEndTime() - ts) / resolution + 1) * resolution) {
- if (mon.isCanceled()) {
- return intervals;
- }
- currentInterval = ss.querySingleState(ts, attributeQuark);
- intervals.add(currentInterval);
- }
-
- /* Add the interval at t2, if it wasn't included already. */
- if (currentInterval != null && currentInterval.getEndTime() < tEnd) {
- currentInterval = ss.querySingleState(tEnd, attributeQuark);
- intervals.add(currentInterval);
- }
- return intervals;
- }
-
- /**
- * Queries intervals in the state system for a given attribute, starting at
- * time t1, until we obtain a non-null value.
- *
- * @param ss
- * The state system on which to query intervals
- * @param attributeQuark
- * The attribute quark to query
- * @param t1
- * Start time of the query
- * @param t2
- * Time limit of the query. Use {@link Long#MAX_VALUE} for no
- * limit.
- * @return The first interval from t1 for which the value is not a null
- * value, or <code>null</code> if no interval was found once we
- * reach either t2 or the end time of the state system.
- */
- public static @Nullable ITmfStateInterval queryUntilNonNullValue(ITmfStateSystem ss,
- int attributeQuark, long t1, long t2) {
-
- long current = t1;
- /* Make sure the range is ok */
- if (t1 < ss.getStartTime()) {
- current = ss.getStartTime();
- }
- long end = t2;
- if (end < ss.getCurrentEndTime()) {
- end = ss.getCurrentEndTime();
- }
- /* Make sure the time range makes sense */
- if (end < current) {
- return null;
- }
-
- try {
- while (current < t2) {
- ITmfStateInterval currentInterval = ss.querySingleState(current, attributeQuark);
- ITmfStateValue value = currentInterval.getStateValue();
-
- if (!value.isNull()) {
- return currentInterval;
- }
- current = currentInterval.getEndTime() + 1;
- }
- } catch (AttributeNotFoundException | StateSystemDisposedException | TimeRangeException e) {
- /* Nothing to do */
- }
- return null;
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2014 Ericsson
- * Copyright (c) 2010, 2011 École Polytechnique de Montréal
- * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- *******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.backend;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.PrintWriter;
-import java.util.List;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
-import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
-import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
-
-/**
- * The main difference between StateSystem and StateHistorySystem is that SHS
- * allows 'seeking' back in time to reload a Current State at a previous time.
- * "How to go back in time" is defined by the implementation of the
- * HistoryBackend.
- *
- * A StateHistorySystem contains one and only one HistoryBackend. If you want to
- * use a paradigm with more than one provider (eg. more or less precision
- * depending on what's asked by the user), implement one wrapper HistoryBackend
- * which can then contain your 2-3 other backends underneath.
- *
- * @author Alexandre Montplaisir
- */
-public interface IStateHistoryBackend {
-
- /**
- * Get the ID of the state system that populates this backend.
- *
- * @return The state system's ID.
- * @since 1.0
- */
- @NonNull String getSSID();
-
- /**
- * Get the start time of this state history. This is usually the same as the
- * start time of the originating trace.
- *
- * @return The start time
- */
- long getStartTime();
-
- /**
- * Get the current end time of the state history. It will change as the
- * history is being built.
- *
- * @return The end time
- */
- long getEndTime();
-
- /**
- * Main method to insert state intervals into the history.
- *
- * @param stateStartTime
- * The start time of the interval
- * @param stateEndTime
- * The end time of the interval
- * @param quark
- * The quark of the attribute this interval refers to
- * @param value
- * The StateValue represented by this interval
- * @throws TimeRangeException
- * If the start or end time are invalid
- */
- // FIXME change to IStateInterval?
- void insertPastState(long stateStartTime, long stateEndTime,
- int quark, ITmfStateValue value) throws TimeRangeException;
-
- /**
- * Indicate to the provider that we are done building the history (so it can
- * close off, stop threads, etc.)
- *
- * @param endTime
- * The end time to assign to this state history. It could be
- * farther in time than the last state inserted, for example.
- * @throws TimeRangeException
- * If the requested time makes no sense.
- */
- void finishedBuilding(long endTime) throws TimeRangeException;
-
- /**
- * It is the responsibility of the backend to define where to save the
- * Attribute Tree (since it's only useful to "reopen" an Attribute Tree if
- * we have the matching History).
- *
- * This method defines where to read for the attribute tree when opening an
- * already-existing history. Refer to the file format documentation.
- *
- * @return A FileInputStream object pointing to the correct file/location in
- * the file where to read the attribute tree information.
- */
- FileInputStream supplyAttributeTreeReader();
-
- // FIXME change to FOS too?
- /**
- * Supply the File object to which we will write the attribute tree. The
- * position in this file is supplied by -TreeWriterFilePosition.
- *
- * @return The target File
- */
- File supplyAttributeTreeWriterFile();
-
- /**
- * Supply the position in the file where we should write the attribute tree
- * when asked to.
- *
- * @return The file position (we will seek() to it)
- */
- long supplyAttributeTreeWriterFilePosition();
-
- /**
- * Delete any generated files or anything that might have been created by
- * the history backend (either temporary or save files). By calling this, we
- * return to the state as it was before ever building the history.
- *
- * You might not want to call automatically if, for example, you want an
- * index file to persist on disk. This could be limited to actions
- * originating from the user.
- */
- void removeFiles();
-
- /**
- * Notify the state history back-end that the trace is being closed, so it
- * should release its file descriptors, close its connections, etc.
- */
- void dispose();
-
- // ------------------------------------------------------------------------
- // Query methods
- // ------------------------------------------------------------------------
-
- /**
- * Complete "give me the state at a given time" method 'currentStateInfo' is
- * an "out" parameter, that is, write to it the needed information and
- * return. DO NOT 'new' currentStateInfo, it will be lost and nothing will
- * be returned!
- *
- * @param currentStateInfo
- * List of StateValues (index == quark) to fill up
- * @param t
- * Target timestamp of the query
- * @throws TimeRangeException
- * If the timestamp is outside of the history/trace
- * @throws StateSystemDisposedException
- * If the state system is disposed while a request is ongoing.
- */
- void doQuery(@NonNull List<ITmfStateInterval> currentStateInfo, long t)
- throws TimeRangeException, StateSystemDisposedException;
-
- /**
- * Some providers might want to specify a different way to obtain just a
- * single StateValue instead of updating the whole list. If the method to
- * use is the same, then feel free to just implement this as a wrapper using
- * doQuery().
- *
- * @param t
- * The target timestamp of the query.
- * @param attributeQuark
- * The single attribute for which you want the state interval
- * @return The state interval matching this timestamp/attribute pair
- * @throws TimeRangeException
- * If the timestamp was invalid
- * @throws AttributeNotFoundException
- * If the quark was invalid
- * @throws StateSystemDisposedException
- * If the state system is disposed while a request is ongoing.
- */
- ITmfStateInterval doSingularQuery(long t, int attributeQuark)
- throws TimeRangeException, AttributeNotFoundException,
- StateSystemDisposedException;
-
- /**
- * Debug method to print the contents of the history backend.
- *
- * @param writer
- * The PrintWriter where to write the output
- */
- void debugPrint(PrintWriter writer);
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2015 EfficiOS Inc., Alexandre Montplaisir
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- ******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.backend;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.tracecompass.internal.statesystem.core.backend.InMemoryBackend;
-import org.eclipse.tracecompass.internal.statesystem.core.backend.NullBackend;
-import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HistoryTreeBackend;
-import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.ThreadedHistoryTreeBackend;
-
-/**
- * Factory for the various types {@link IStateHistoryBackend} supplied by this
- * plugin.
- *
- * @author Alexandre Montplaisir
- * @since 1.0
- */
-@NonNullByDefault
-public final class StateHistoryBackendFactory {
-
- private StateHistoryBackendFactory() {}
-
- /**
- * Create a new null-backend, which will not store any history intervals
- * (only the current state can be queried).
- *
- * @param ssid
- * The ID for this state system
- * @return The state system backend
- */
- public static IStateHistoryBackend createNullBackend(String ssid) {
- return new NullBackend(ssid);
- }
-
- /**
- * Create a new in-memory backend. This backend will store all the history
- * intervals in memory, so it should not be used for anything serious.
- *
- * @param ssid
- * The ID for this state system
- * @param startTime
- * The start time of the state system and backend
- * @return The state system backend
- */
- public static IStateHistoryBackend createInMemoryBackend(String ssid, long startTime) {
- return new InMemoryBackend(ssid, startTime);
- }
-
- /**
- * Create a new backend using a History Tree. This backend stores all its
- * intervals on disk.
- *
- * By specifying a 'queueSize' parameter, the implementation that runs in a
- * separate thread can be used.
- *
- * @param ssid
- * The state system's id
- * @param stateFile
- * The filename/location where to store the state history (Should
- * end in .ht)
- * @param providerVersion
- * Version of of the state provider. We will only try to reopen
- * existing files if this version matches the one in the
- * framework.
- * @param startTime
- * The earliest time stamp that will be stored in the history
- * @param queueSize
- * The size of the interval insertion queue between the receiver
- * and writer threads. 2000 - 10000 usually works well. If 0 is
- * specified, no queue is used and the writes happen in the same
- * thread.
- * @return The state system backend
- * @throws IOException
- * Thrown if we can't create the file for some reason
- */
- public static IStateHistoryBackend createHistoryTreeBackendNewFile(String ssid,
- File stateFile, int providerVersion, long startTime, int queueSize) throws IOException {
- if (queueSize > 0) {
- return new ThreadedHistoryTreeBackend(ssid, stateFile, providerVersion, startTime, queueSize);
- }
- return new HistoryTreeBackend(ssid, stateFile, providerVersion, startTime);
- }
-
- /**
- * Create a new History Tree backend, but attempt to open an existing file
- * on disk. If the file cannot be found or recognized, an IOException will
- * be thrown.
- *
- * @param ssid
- * The state system's id
- * @param stateFile
- * Filename/location of the history we want to load
- * @param providerVersion
- * Expected version of of the state provider plugin.
- * @return The state system backend
- * @throws IOException
- * If we can't read the file, if it doesn't exist, is not
- * recognized, or if the version of the file does not match the
- * expected providerVersion.
- */
- public static IStateHistoryBackend createHistoryTreeBackendExistingFile(String ssid, File stateFile,
- int providerVersion) throws IOException {
- return new HistoryTreeBackend(ssid, stateFile, providerVersion);
- }
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson
- * Copyright (c) 2010, 2011 École Polytechnique de Montréal
- * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- * Patrick Tasse - Add message to exceptions
- *******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.exceptions;
-
-/**
- * This exception gets thrown when the user tries to access an attribute which
- * doesn't exist in the system, of if the quark is simply invalid (ie, < 0).
- *
- * @author Alexandre Montplaisir
- */
-public class AttributeNotFoundException extends Exception {
-
- private static final long serialVersionUID = 7964275803369706145L;
-
- /**
- * Default constructor
- */
- public AttributeNotFoundException() {
- super();
- }
-
- /**
- * Constructor with a message
- *
- * @param message
- * Message to attach to this exception
- */
- public AttributeNotFoundException(String message) {
- super(message);
- }
-
- /**
- * Constructor with both a message and a cause.
- *
- * @param message
- * Message to attach to this exception
- * @param e
- * Cause of this exception
- * @since 1.0
- */
- public AttributeNotFoundException(String message, Throwable e) {
- super(message, e);
- }
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2014 Ericsson
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.exceptions;
-
-/**
- * Exception thrown by the state system if a query is done on it after it has
- * been disposed.
- *
- * @author Alexandre Montplaisir
- */
-public class StateSystemDisposedException extends Exception {
-
- private static final long serialVersionUID = 7896041701818620084L;
-
- /**
- * Create a new simple StateSystemDisposedException.
- */
- public StateSystemDisposedException() {
- super();
- }
-
- /**
- * Create a new StateSystemDisposedException based on a previous one.
- *
- * @param e
- * The previous exception
- */
- public StateSystemDisposedException(Throwable e) {
- super(e);
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2014 Ericsson
- * Copyright (c) 2010, 2011 École Polytechnique de Montréal
- * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- *******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.exceptions;
-
-/**
- * The StateValue is a wrapper around the different type of values that can be
- * used and stored in the state system and history. "Unboxing" the value means
- * retrieving the base type (int, String, etc.) inside it.
- *
- * This exception is thrown if the user tries to unbox a StateValue with an
- * incorrect type (for example, tries to read a String value as an Int).
- *
- * To avoid it, always check for the state value's type before attempting to
- * unbox it, via
- * {@link org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue#getType()}.
- *
- * @author Alexandre Montplaisir
- */
-public class StateValueTypeException extends RuntimeException {
-
- private static final long serialVersionUID = -4548793451746144513L;
-
- /**
- * Default constructor
- */
- public StateValueTypeException() {
- super();
- }
-
- /**
- * Constructor with a message
- *
- * @param message
- * Message to attach to this exception
- */
- public StateValueTypeException(String message) {
- super(message);
- }
-
- /**
- * Constructor with both a message and a cause.
- *
- * @param message
- * Message to attach to this exception
- * @param e
- * Cause of this exception
- */
- public StateValueTypeException(String message, Throwable e) {
- super(message, e);
- }
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson
- * Copyright (c) 2010, 2011 École Polytechnique de Montréal
- * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- * Patrick Tasse - Add message to exceptions
- *******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.exceptions;
-
-/**
- * Generic exception for when the user specifies an invalid time stamp. Usually
- * timestamps must be within the range of the trace or state history being
- * queried.
- *
- * For insertions, it's forbidden to insert new states "in the past" (before where
- * the cursor is), so this exception is also thrown in that case.
- *
- * @author Alexandre Montplaisir
- */
-public class TimeRangeException extends RuntimeException {
-
- private static final long serialVersionUID = -4067685227260254532L;
-
- /**
- * Default constructor
- */
- public TimeRangeException() {
- }
-
- /**
- * Constructor with a message
- *
- * @param message
- * Message to attach to this exception
- * @since 1.0
- */
- public TimeRangeException(String message) {
- super(message);
- }
-
- /**
- * Constructor with both a message and a cause.
- *
- * @param message
- * Message to attach to this exception
- * @param e
- * Cause of this exception
- * @since 1.0
- */
- public TimeRangeException(String message, Throwable e) {
- super(message, e);
- }
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2014 Ericsson
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API
- ******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.interval;
-
-import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
-
-/**
- * This is the basic interface for accessing state intervals. See
- * StateInterval.java for a basic implementation.
- *
- * A StateInterval is meant to be immutable. All implementing (non-abstract)
- * classes should ideally be marked as 'final'.
- *
- * @author Alexandre Montplaisir
- */
-public interface ITmfStateInterval {
-
- /**
- * Retrieve the start time of the interval
- *
- * @return the start time of the interval
- */
- long getStartTime();
-
- /**
- * Retrieve the end time of the interval
- *
- * @return the end time of the interval
- */
- long getEndTime();
-
- /**
- * In case the "real" end time of the interval is not exactly the same as
- * the end time you want to show in views, you can implement this method to
- * assign a different value that the viewer can use.
- *
- * If not, you can simply have it return the same as getEndTime().
- *
- * @return The end time that views should use
- */
- long getViewerEndTime();
-
- /**
- * Retrieve the quark of the attribute this state interval refers to
- *
- * @return the quark of the attribute this state interval refers to
- */
- int getAttribute();
-
- /**
- * Retrieve the state value represented by this interval
- *
- * @return the state value represented by this interval
- */
- ITmfStateValue getStateValue();
-
- /**
- * Test if this interval intersects another timestamp, inclusively.
- *
- * @param timestamp
- * The target timestamp
- * @return True if the interval and timestamp intersect, false if they don't
- */
- boolean intersects(long timestamp);
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2013, 2014 Ericsson
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.interval;
-
-import java.util.Comparator;
-
-/**
- * Comparator for ITmfStateInterval, using their *end times*. Making intervals
- * Comparable wouldn't be clear if it's using their start or end times (or maybe
- * even values), so separate comparators are provided.
- *
- * @author Alexandre Montplaisir
- */
-public class TmfIntervalEndComparator implements Comparator<ITmfStateInterval> {
-
- @Override
- public int compare(ITmfStateInterval o1, ITmfStateInterval o2) {
- long e1 = o1.getEndTime();
- long e2 = o2.getEndTime();
-
- if (e1 < e2) {
- return -1;
- } else if (e1 > e2) {
- return 1;
- } else {
- return 0;
- }
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2014 Ericsson
- * Copyright (c) 2010, 2011 École Polytechnique de Montréal
- * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- *******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.interval;
-
-import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
-
-/**
- * The StateInterval represents the "state" a particular attribute was in, at a
- * given time. It is the main object being returned from queries to the state
- * system.
- *
- * @author Alexandre Montplaisir
- */
-public final class TmfStateInterval implements ITmfStateInterval {
-
- private final long start;
- private final long end;
- private final int attribute;
- private final ITmfStateValue sv;
-
- /**
- * Construct an interval from its given parameters
- *
- * @param start
- * Start time
- * @param end
- * End time
- * @param attribute
- * Attribute linked to this interval
- * @param sv
- * State value this interval will contain
- */
- public TmfStateInterval(long start, long end, int attribute,
- ITmfStateValue sv) {
- this.start = start;
- this.end = end;
- this.attribute = attribute;
- this.sv = sv;
- }
-
- @Override
- public long getStartTime() {
- return start;
- }
-
- @Override
- public long getEndTime() {
- return end;
- }
-
- @Override
- public long getViewerEndTime() {
- return end + 1;
- }
-
- @Override
- public int getAttribute() {
- return attribute;
- }
-
- @Override
- public ITmfStateValue getStateValue() {
- return sv;
- }
-
- @Override
- public boolean intersects(long timestamp) {
- if (start <= timestamp) {
- if (end >= timestamp) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public String toString() {
- /* Only used for debugging */
- StringBuffer buf = new StringBuffer(start + " to "); //$NON-NLS-1$
- buf.append(end + ", "); //$NON-NLS-1$
- buf.append(String.format("key = %4d, ", attribute)); //$NON-NLS-1$
- buf.append("value = " + sv.toString()); //$NON-NLS-1$
- return buf.toString();
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2013, 2014 Ericsson
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
-
- * Contributors:
- * Alexandre Montplaisir - Initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.statevalue;
-
-import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
-
-/**
- * A state value containing a double primitive.
- *
- * @author Alexandre Montplaisir
- */
-final class DoubleStateValue extends TmfStateValue {
-
- private final double value;
-
- public DoubleStateValue(double value) {
- this.value = value;
- }
-
- @Override
- public Type getType() {
- return Type.DOUBLE;
- }
-
- @Override
- public boolean isNull() {
- return false;
- }
-
- @Override
- public boolean equals(@Nullable Object object) {
- if (!(object instanceof DoubleStateValue)) {
- return false;
- }
- DoubleStateValue other = (DoubleStateValue) object;
- return (Double.compare(this.value, other.value) == 0);
- }
-
- @Override
- public int hashCode() {
- long bits = Double.doubleToLongBits(value);
- return ((int) bits) ^ ((int) (bits >>> 32));
- }
-
- @Override
- public @Nullable String toString() {
- return String.format("%3f", value); //$NON-NLS-1$
- }
-
- // ------------------------------------------------------------------------
- // Unboxing methods
- // ------------------------------------------------------------------------
-
- @Override
- public double unboxDouble() {
- return value;
- }
-
- @Override
- public int compareTo(@Nullable ITmfStateValue other) {
- if (other == null) {
- throw new IllegalArgumentException();
- }
-
- switch (other.getType()) {
- case INTEGER:
- double otherDoubleValue = ((IntegerStateValue) other).unboxInt();
- return Double.compare(this.value, otherDoubleValue);
- case DOUBLE:
- otherDoubleValue = ((DoubleStateValue) other).unboxDouble();
- return Double.compare(this.value, otherDoubleValue);
- case LONG:
- otherDoubleValue = ((LongStateValue) other).unboxLong();
- return Double.compare(this.value, otherDoubleValue);
- case NULL:
- return Double.compare(this.value, other.unboxDouble());
- case STRING:
- throw new StateValueTypeException("A Double state value cannot be compared to a String state value."); //$NON-NLS-1$
- default:
- throw new StateValueTypeException("A Double state value cannot be compared to the type " + other.getType()); //$NON-NLS-1$
- }
-
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2014 Ericsson
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Montplaisir - Initial API
- ******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.statevalue;
-
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
-
-/**
- * This is the interface for using state values and reading their contents.
- *
- * @author Alexandre Montplaisir
- */
-public interface ITmfStateValue extends Comparable<ITmfStateValue> {
-
- /**
- * The supported types of state values
- */
- public enum Type {
- /** Null value, for an interval not carrying any information */
- NULL,
- /** 32-bit integer value */
- INTEGER,
- /** 64-bit integer value */
- LONG,
- /** IEEE 754 double precision number */
- DOUBLE,
- /** Variable-length string value */
- STRING,
- }
-
- /**
- * Each implementation has to define which one (among the supported types)
- * they implement. There could be more than one implementation of each type,
- * depending on the needs of the different users.
- *
- * @return The ITmfStateValue.Type enum representing the type of this value
- */
- Type getType();
-
- /**
- * Only "null values" should return true here
- *
- * @return True if this type of SV is considered "null", false if it
- * contains a real value.
- */
- boolean isNull();
-
- /**
- * Read the contained value as an 'int' primitive
- *
- * @return The integer contained in the state value
- * @throws StateValueTypeException
- * If the contained value cannot be read as an integer
- */
- int unboxInt();
-
- /**
- * Read the contained value as a 'long' primitive
- *
- * @return The long contained in the state value
- * @throws StateValueTypeException
- * If the contained value cannot be read as a long
- */
- long unboxLong();
-
- /**
- * Read the contained value as a 'double' primitive
- *
- * @return The double contained in the state value
- * @throws StateValueTypeException
- * If the contained value cannot be read as a double
- */
- double unboxDouble();
-
- /**
- * Read the contained value as a String
- *
- * @return The String contained in the state value
- * @throws StateValueTypeException
- * If the contained value cannot be read as a String
- */
- String unboxStr();
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2014 Ericsson
- * Copyright (c) 2010, 2011 École Polytechnique de Montréal
- * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- *******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.statevalue;
-
-import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
-
-/**
- * A state value containing a simple integer.
- *
- * @version 1.0
- * @author Alexandre Montplaisir
- */
-final class IntegerStateValue extends TmfStateValue {
-
- private final int value;
-
- public IntegerStateValue(int valueAsInt) {
- this.value = valueAsInt;
- }
-
- @Override
- public Type getType() {
- return Type.INTEGER;
- }
-
- @Override
- public boolean isNull() {
- return false;
- }
-
- @Override
- public boolean equals(@Nullable Object object) {
- if (!(object instanceof IntegerStateValue)) {
- return false;
- }
- IntegerStateValue other = (IntegerStateValue) object;
- return (this.value == other.value);
- }
-
- @Override
- public int hashCode() {
- return value;
- }
-
- @Override
- public @Nullable String toString() {
- return String.format("%3d", value); //$NON-NLS-1$
- }
-
- // ------------------------------------------------------------------------
- // Unboxing methods
- // ------------------------------------------------------------------------
-
- @Override
- public int unboxInt() {
- return value;
- }
-
- @Override
- public long unboxLong() {
- /* It's always safe to up-cast an int into a long */
- return value;
- }
-
- @Override
- public int compareTo(@Nullable ITmfStateValue other) {
- if (other == null) {
- throw new IllegalArgumentException();
- }
-
- switch (other.getType()) {
- case INTEGER:
- IntegerStateValue otherIntValue = (IntegerStateValue) other;
- return Integer.compare(this.value, otherIntValue.value);
- case DOUBLE:
- double otherDoubleValue = ((DoubleStateValue) other).unboxDouble();
- return Double.compare(this.value, otherDoubleValue);
- case LONG:
- long otherLongValue = ((LongStateValue) other).unboxLong();
- return Long.compare(this.value, otherLongValue);
- case NULL:
- return Integer.compare(this.value, other.unboxInt());
- case STRING:
- throw new StateValueTypeException("An Integer state value cannot be compared to a String state value."); //$NON-NLS-1$
- default:
- throw new StateValueTypeException("An Integer state value cannot be compared to the type " + other.getType()); //$NON-NLS-1$
- }
-
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2013, 2014 École Polytechnique de Montréal
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
-
- * Contributors:
- * François Rajotte - Initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.statevalue;
-
-import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
-
-/**
- * A state value containing a long integer (8 bytes).
- *
- * @version 1.0
- * @author François Rajotte
- */
-final class LongStateValue extends TmfStateValue {
-
- private final long value;
-
- public LongStateValue(long valueAsLong) {
- this.value = valueAsLong;
- }
-
- @Override
- public Type getType() {
- return Type.LONG;
- }
-
- @Override
- public boolean isNull() {
- return false;
- }
-
- @Override
- public boolean equals(@Nullable Object object) {
- if (!(object instanceof LongStateValue)) {
- return false;
- }
- LongStateValue other = (LongStateValue) object;
- return (this.value == other.value);
- }
-
- @Override
- public int hashCode() {
- return ((int) value) ^ ((int) (value >>> 32));
- }
-
- @Override
- public @Nullable String toString() {
- return String.format("%3d", value); //$NON-NLS-1$
- }
-
- // ------------------------------------------------------------------------
- // Unboxing methods
- // ------------------------------------------------------------------------
-
- @Override
- public long unboxLong() {
- return value;
- }
-
- @Override
- public int compareTo(@Nullable ITmfStateValue other) {
- if (other == null) {
- throw new IllegalArgumentException();
- }
-
- switch (other.getType()) {
- case INTEGER:
- long otherLongValue = ((IntegerStateValue) other).unboxInt();
- return Long.compare(this.value, otherLongValue);
- case DOUBLE:
- double otherDoubleValue = ((DoubleStateValue) other).unboxDouble();
- return Double.compare(this.value, otherDoubleValue);
- case LONG:
- otherLongValue = ((LongStateValue) other).unboxLong();
- return Long.compare(this.value, otherLongValue);
- case NULL:
- return Long.compare(this.value, other.unboxLong());
- case STRING:
- throw new StateValueTypeException("A Long state value cannot be compared to a String state value."); //$NON-NLS-1$
- default:
- throw new StateValueTypeException("A Long state value cannot be compared to the type " + other.getType()); //$NON-NLS-1$
- }
-
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2014 Ericsson
- * Copyright (c) 2010, 2011 École Polytechnique de Montréal
- * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- *******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.statevalue;
-
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * A state value that contains no particular value. It is sometimes needed over
- * a "null" reference, since we avoid NPE's this way.
- *
- * It can also be read either as a String ("nullValue") or an Integer (-1).
- *
- * @version 1.0
- * @author Alexandre Montplaisir
- */
-final class NullStateValue extends TmfStateValue {
-
- private final String value = "nullValue"; //$NON-NLS-1$
-
- @Override
- public Type getType() {
- return Type.NULL;
- }
-
- @Override
- public boolean isNull() {
- return true;
- }
-
- @Override
- public boolean equals(@Nullable Object object) {
- return (object instanceof NullStateValue);
- }
-
- @Override
- public int hashCode() {
- return 0;
- }
-
- @Override
- public String toString() {
- return value;
- }
-
- // ------------------------------------------------------------------------
- // Unboxing methods. Null values can be unboxed into any type.
- // ------------------------------------------------------------------------
-
- @Override
- public int unboxInt() {
- return -1;
- }
-
- @Override
- public long unboxLong() {
- return -1;
- }
-
- @Override
- public double unboxDouble() {
- return Double.NaN;
- }
-
- @Override
- public String unboxStr() {
- return value;
- }
-
- @Override
- public int compareTo(@Nullable ITmfStateValue other) {
- if (other == null) {
- throw new IllegalArgumentException();
- }
- if (other instanceof NullStateValue) {
- return 0;
- }
- /*
- * For every other state value type, we defer to how that type wants to
- * be compared against null values.
- */
- return -(other.compareTo(this));
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2014 Ericsson
- * Copyright (c) 2010, 2011 École Polytechnique de Montréal
- * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- *******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.statevalue;
-
-import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
-
-/**
- * A state value containing a variable-sized string
- *
- * @version 1.0
- * @author Alexandre Montplaisir
- */
-final class StringStateValue extends TmfStateValue {
-
- private final String value;
-
- public StringStateValue(String valueAsString) {
- this.value = valueAsString;
- }
-
- @Override
- public Type getType() {
- return Type.STRING;
- }
-
- @Override
- public boolean isNull() {
- return false;
- }
-
- @Override
- public boolean equals(@Nullable Object object) {
- if (!(object instanceof StringStateValue)) {
- return false;
- }
- StringStateValue other = (StringStateValue) object;
- return value.equals(other.value);
- }
-
- @Override
- public int hashCode() {
- return value.hashCode();
- }
-
- @Override
- public String toString() {
- return value;
- }
-
- // ------------------------------------------------------------------------
- // Unboxing methods
- // ------------------------------------------------------------------------
-
- @Override
- public String unboxStr() {
- return value;
- }
-
- @Override
- public int compareTo(@Nullable ITmfStateValue other) {
- if (other == null) {
- throw new IllegalArgumentException();
- }
-
- switch (other.getType()) {
- case DOUBLE:
- throw new StateValueTypeException("A String state value cannot be compared to a Double state value."); //$NON-NLS-1$
- case INTEGER:
- throw new StateValueTypeException("A String state value cannot be compared to an Integer state value."); //$NON-NLS-1$
- case LONG:
- throw new StateValueTypeException("A String state value cannot be compared to a Long state value."); //$NON-NLS-1$
- case NULL:
- /*
- * We assume that every string state value is greater than a null
- * state value.
- */
- return 1;
- case STRING:
- StringStateValue otherStringValue = (StringStateValue) other;
- return value.compareTo(otherStringValue.value);
- default:
- throw new StateValueTypeException("A String state value cannot be compared to the type " + other.getType()); //$NON-NLS-1$
- }
-
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2014 Ericsson
- * Copyright (c) 2010, 2011 École Polytechnique de Montréal
- * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- ******************************************************************************/
-
-package org.eclipse.tracecompass.statesystem.core.statevalue;
-
-import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.tracecompass.internal.statesystem.core.Activator;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
-
-/**
- * This is the wrapper class that exposes the different types of 'state values'
- * available to use in the State System.
- *
- * This also defines how these values are to be stored in the History Tree. For
- * example, we can save numerical values as integers instead of arrays of
- * 1-digit characters.
- *
- * The available types are Int, Long, Double and String.
- *
- * @author Alexandre Montplaisir
- */
-public abstract class TmfStateValue implements ITmfStateValue {
-
- // ------------------------------------------------------------------------
- // State value caches (sizes must be powers of 2)
- // ------------------------------------------------------------------------
-
- private static final int INT_CACHE_SIZE = 128;
- private static final int LONG_CACHE_SIZE = 128;
- private static final int DOUBLE_CACHE_SIZE = 128;
-
- private static final IntegerStateValue intCache[] = new IntegerStateValue[INT_CACHE_SIZE];
- private static final LongStateValue longCache[] = new LongStateValue[LONG_CACHE_SIZE];
- private static final DoubleStateValue doubleCache[] = new DoubleStateValue[DOUBLE_CACHE_SIZE];
-
- // ------------------------------------------------------------------------
- // Factory methods to instantiate new state values
- // ------------------------------------------------------------------------
-
- /*
- * Since all "null state values" are the same, we only need one copy in
- * memory.
- */
- private static TmfStateValue nullValue = new NullStateValue();
-
- /**
- * Return an instance of a "null" value. Only one copy exists in memory.
- *
- * @return A null value
- */
- public static final TmfStateValue nullValue() {
- return nullValue;
- }
-
- /**
- * Factory constructor for Integer state values
- *
- * @param intValue
- * The integer value to contain
- * @return The newly-created TmfStateValue object
- */
- public static TmfStateValue newValueInt(int intValue) {
- /* Lookup in cache for the existence of the same value. */
- int offset = intValue & (INT_CACHE_SIZE - 1);
- IntegerStateValue cached = intCache[offset];
- if (cached != null && cached.unboxInt() == intValue) {
- return cached;
- }
-
- /* Not in cache, create a new value and cache it. */
- IntegerStateValue newValue = new IntegerStateValue(intValue);
- intCache[offset] = newValue;
- return newValue;
- }
-
- /**
- * Factory constructor for Long state values
- *
- * @param longValue
- * The long value to contain
- * @return The newly-created TmfStateValue object
- */
- public static TmfStateValue newValueLong(long longValue) {
- /* Lookup in cache for the existence of the same value. */
- int offset = (int) longValue & (LONG_CACHE_SIZE - 1);
- LongStateValue cached = longCache[offset];
- if (cached != null && cached.unboxLong() == longValue) {
- return cached;
- }
-
- /* Not in cache, create a new value and cache it. */
- LongStateValue newValue = new LongStateValue(longValue);
- longCache[offset] = newValue;
- return newValue;
- }
-
- /**
- * Factory constructor for Double state values
- *
- * @param value
- * The double value to contain
- * @return The newly-created TmfStateValue object
- */
- public static TmfStateValue newValueDouble(double value) {
- /* Lookup in cache for the existence of the same value. */
- int offset = (int) Double.doubleToLongBits(value) & (DOUBLE_CACHE_SIZE - 1);
- DoubleStateValue cached = doubleCache[offset];
-
- /*
- * We're using Double.compare() instead of .equals(), because .compare()
- * works when both values are Double.NaN.
- */
- if (cached != null && Double.compare(cached.unboxDouble(), value) == 0) {
- return cached;
- }
-
- /* Not in cache, create a new value and cache it. */
- DoubleStateValue newValue = new DoubleStateValue(value);
- doubleCache[offset] = newValue;
- return newValue;
- }
-
- /**
- * Factory constructor for String state values
- *
- * @param strValue
- * The string value to contain
- * @return The newly-created TmfStateValue object
- */
- public static TmfStateValue newValueString(@Nullable String strValue) {
- if (strValue == null) {
- return nullValue();
- }
- /*
- * Make sure the String does not contain "weird" things, like ISO
- * control characters.
- */
- for (char c : strValue.toCharArray()) {
- if (Character.isISOControl(c)) {
- Activator.getDefault().logError("Trying to use invalid string: " + strValue); //$NON-NLS-1$
- throw new IllegalArgumentException();
- }
- }
- return new StringStateValue(strValue);
- }
-
- // ------------------------------------------------------------------------
- // Default unboxing methods.
- // Subclasses can override those for the types they support.
- // ------------------------------------------------------------------------
-
- private String unboxErrMsg(String targetType) {
- return "Type " + getClass().getSimpleName() + //$NON-NLS-1$
- " cannot be unboxed into a " + targetType + " value."; //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- @Override
- public int unboxInt() {
- throw new StateValueTypeException(unboxErrMsg("Int")); //$NON-NLS-1$
- }
-
- @Override
- public long unboxLong() {
- throw new StateValueTypeException(unboxErrMsg("Long")); //$NON-NLS-1$
- }
-
- @Override
- public double unboxDouble() {
- throw new StateValueTypeException(unboxErrMsg("Double")); //$NON-NLS-1$
- }
-
- @Override
- public String unboxStr() {
- throw new StateValueTypeException(unboxErrMsg("String")); //$NON-NLS-1$
- }
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2014 Ericsson
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Ericsson - Initial API and implementation
- *******************************************************************************/
-@org.eclipse.jdt.annotation.NonNullByDefault package org.eclipse.tracecompass.statesystem.core.statevalue;
<module>doc</module>
<module>gdbtrace</module>
<module>pcap</module>
+ <module>statesystem</module>
<module>org.eclipse.tracecompass.ctf</module>
<module>org.eclipse.tracecompass.ctf.core</module>
<module>org.eclipse.tracecompass.ctf.parser</module>
<module>org.eclipse.tracecompass.ctf.parser.tests</module>
- <module>org.eclipse.tracecompass.statesystem.core</module>
- <module>org.eclipse.tracecompass.statesystem.core.tests</module>
-
<module>org.eclipse.tracecompass.tmf</module>
<module>org.eclipse.tracecompass.tmf.core</module>
<module>org.eclipse.tracecompass.tmf.core.tests</module>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.tracecompass.statesystem.core.tests</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
--- /dev/null
+eclipse.preferences.version=1
+line.separator=\n
--- /dev/null
+eclipse.preferences.version=1
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=f
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=enabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=error
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=error
+org.eclipse.jdt.core.compiler.problem.deadCode=error
+org.eclipse.jdt.core.compiler.problem.deprecation=error
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=error
+org.eclipse.jdt.core.compiler.problem.emptyStatement=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=error
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=error
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=error
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=error
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=error
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=error
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=error
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=error
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=error
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=enabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=error
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=error
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=error
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=error
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=error
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=error
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=error
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=error
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=error
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=error
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=error
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=error
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=error
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=error
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=disabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=disabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=error
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=error
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error
+org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=0
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=false
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=250
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=false
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
--- /dev/null
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_tmf-style
+formatter_settings_version=12
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.overrideannotation=true
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=false
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=false
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=false
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=false
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=true
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
--- /dev/null
+ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error
+ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error
+API_USE_SCAN_FIELD_SEVERITY=Error
+API_USE_SCAN_METHOD_SEVERITY=Error
+API_USE_SCAN_TYPE_SEVERITY=Error
+CLASS_ELEMENT_TYPE_ADDED_METHOD=Error
+CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Error
+CLASS_ELEMENT_TYPE_REMOVED_FIELD=Error
+CLASS_ELEMENT_TYPE_REMOVED_METHOD=Error
+CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Error
+ENUM_ELEMENT_TYPE_REMOVED_FIELD=Error
+ENUM_ELEMENT_TYPE_REMOVED_METHOD=Error
+ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+FIELD_ELEMENT_TYPE_ADDED_VALUE=Error
+FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_TYPE=Error
+FIELD_ELEMENT_TYPE_CHANGED_VALUE=Error
+FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Error
+FIELD_ELEMENT_TYPE_REMOVED_VALUE=Error
+ILLEGAL_EXTEND=Warning
+ILLEGAL_IMPLEMENT=Warning
+ILLEGAL_INSTANTIATE=Warning
+ILLEGAL_OVERRIDE=Warning
+ILLEGAL_REFERENCE=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+INVALID_JAVADOC_TAG=Warning
+INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Warning
+LEAK_EXTEND=Warning
+LEAK_FIELD_DECL=Warning
+LEAK_IMPLEMENT=Warning
+LEAK_METHOD_PARAM=Warning
+LEAK_METHOD_RETURN_TYPE=Warning
+METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error
+METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+MISSING_EE_DESCRIPTIONS=Ignore
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
+UNUSED_PROBLEM_FILTERS=Warning
+automatically_removed_unused_problem_filters=false
+eclipse.preferences.version=1
+incompatible_api_component_version=Error
+incompatible_api_component_version_include_major_without_breaking_change=Disabled
+incompatible_api_component_version_include_minor_without_api_change=Disabled
+invalid_since_tag_version=Error
+malformed_since_tag=Error
+missing_since_tag=Error
+report_api_breakage_when_major_version_incremented=Disabled
+report_resolution_errors_api_component=Warning
--- /dev/null
+compilers.f.unresolved-features=1
+compilers.f.unresolved-plugins=1
+compilers.incompatible-environment=1
+compilers.p.build=1
+compilers.p.build.bin.includes=1
+compilers.p.build.encodings=2
+compilers.p.build.java.compiler=2
+compilers.p.build.java.compliance=1
+compilers.p.build.missing.output=2
+compilers.p.build.output.library=1
+compilers.p.build.source.library=1
+compilers.p.build.src.includes=1
+compilers.p.deprecated=1
+compilers.p.discouraged-class=1
+compilers.p.internal=1
+compilers.p.missing-packages=2
+compilers.p.missing-version-export-package=2
+compilers.p.missing-version-import-package=2
+compilers.p.missing-version-require-bundle=2
+compilers.p.no-required-att=0
+compilers.p.not-externalized-att=2
+compilers.p.unknown-attribute=1
+compilers.p.unknown-class=1
+compilers.p.unknown-element=1
+compilers.p.unknown-identifier=1
+compilers.p.unknown-resource=1
+compilers.p.unresolved-ex-points=0
+compilers.p.unresolved-import=0
+compilers.s.create-docs=false
+compilers.s.doc-folder=doc
+compilers.s.open-tags=1
+eclipse.preferences.version=1
--- /dev/null
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-Vendor: %Bundle-Vendor
+Bundle-Version: 1.0.0.qualifier
+Bundle-Localization: plugin
+Bundle-SymbolicName: org.eclipse.tracecompass.statesystem.core.tests;singleton:=true
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Require-Bundle: org.junit;bundle-version="4.0.0",
+ org.eclipse.core.runtime,
+ org.eclipse.core.resources,
+ org.eclipse.tracecompass.common.core,
+ org.eclipse.tracecompass.statesystem.core
+Export-Package: org.eclipse.tracecompass.statesystem.core.tests
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 5, 2006</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+###############################################################################
+# Copyright (c) 2014, 2015 Ericsson
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Ericsson - Initial API and implementation
+###############################################################################
+
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.properties,\
+ about.html
+src.includes = about.html
+additional.bundles = org.eclipse.jdt.annotation
+jars.extra.classpath = platform:/plugin/org.eclipse.jdt.annotation
--- /dev/null
+###############################################################################
+# Copyright (c) 2014 Ericsson
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Ericsson - Initial API and implementation
+###############################################################################
+
+Bundle-Vendor = Eclipse Trace Compass
+Bundle-Name = Trace Compass State System Core Tests Plug-in
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2014, Ericsson
+
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/epl-v10.html
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>org.eclipse.tracecompass.statesystem-parent</artifactId>
+ <groupId>org.eclipse.tracecompass</groupId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>org.eclipse.tracecompass.statesystem.core.tests</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <packaging>eclipse-test-plugin</packaging>
+
+ <name>Trace Compass State System Core Tests Plug-in</name>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-surefire-plugin</artifactId>
+ <version>${tycho-version}</version>
+ <configuration>
+ <testSuite>org.eclipse.tracecompass.statesystem.core.tests</testSuite>
+ <testClass>org.eclipse.tracecompass.statesystem.core.tests.AllTests</testClass>
+ <useUIHarness>false</useUIHarness>
+ <useUIThread>false</useUIThread>
+ <product>org.eclipse.platform.ide</product>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <groupId>org.eclipse.tracecompass</groupId>
+</project>
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2014, 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ * Patrick Tasse - Enable StateSystemUtils tests
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.tests;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * Master test suite
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ StateSystemPushPopTest.class,
+ StateSystemUtilsTest.class,
+ org.eclipse.tracecompass.statesystem.core.tests.backend.AllTests.class,
+ org.eclipse.tracecompass.statesystem.core.tests.statevalue.AllTests.class
+})
+public class AllTests {
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ * Alexandre Montplaisir - Port to JUnit4
+ ******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.tests;
+
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.eclipse.tracecompass.internal.statesystem.core.StateSystem;
+import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
+import org.eclipse.tracecompass.statesystem.core.StateSystemUtils;
+import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
+import org.eclipse.tracecompass.statesystem.core.backend.StateHistoryBackendFactory;
+import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
+import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit tests for stack-attributes in the Generic State System (using
+ * pushAttribute() and popAttribute())
+ *
+ * @author Alexandre Montplaisir
+ */
+public class StateSystemPushPopTest {
+
+ private ITmfStateSystemBuilder ss;
+ private int attribute;
+
+ private File testHtFile;
+
+ private final static String errMsg = "Caught exception: ";
+
+ /* State values that will be used */
+ //private final static ITmfStateValue nullValue = TmfStateValue.nullValue();
+ private final static ITmfStateValue value1 = TmfStateValue.newValueString("A");
+ private final static ITmfStateValue value2 = TmfStateValue.newValueInt(10);
+ private final static ITmfStateValue value3 = TmfStateValue.nullValue();
+ private final static ITmfStateValue value4 = TmfStateValue.newValueString("D");
+ private final static ITmfStateValue value5 = TmfStateValue.newValueLong(Long.MAX_VALUE);
+
+ /**
+ * Initialization. We run the checks for the return values of
+ * .popAttribute() in here, since this is only available when we are
+ * building the state history.
+ *
+ * @throws IOException
+ * If we can write the file to the temporary directory.
+ * @throws TimeRangeException
+ * Fails the test
+ * @throws AttributeNotFoundException
+ * Fails the test
+ * @throws StateValueTypeException
+ * Fails the test
+ */
+ @Before
+ public void setUp() throws IOException, TimeRangeException,
+ AttributeNotFoundException, StateValueTypeException {
+ ITmfStateValue value;
+ testHtFile = File.createTempFile("test", ".ht");
+
+ IStateHistoryBackend backend = StateHistoryBackendFactory.createHistoryTreeBackendNewFile(
+ "push-pop-test", checkNotNull(testHtFile), 0, 0, 0);
+ ss = new StateSystem(backend, true);
+
+ /* Build the thing */
+ final int attrib = ss.getQuarkAbsoluteAndAdd("Test", "stack");
+
+ ss.pushAttribute( 2, value1, attrib);
+ ss.pushAttribute( 4, value2, attrib);
+ ss.pushAttribute( 6, value3, attrib);
+ ss.pushAttribute( 8, value4, attrib);
+ ss.pushAttribute(10, value5, attrib);
+
+ value = ss.popAttribute(11, attrib);
+ assertEquals(value5, value);
+
+ value = ss.popAttribute(12, attrib);
+ assertEquals(value4, value);
+
+ value = ss.popAttribute(14, attrib);
+ assertEquals(value3, value);
+
+ value = ss.popAttribute(16, attrib);
+ assertEquals(value2, value);
+
+ value = ss.popAttribute(17, attrib);
+ assertEquals(value1, value);
+
+ value = ss.popAttribute(20, attrib);
+ assertEquals(null, value); // Stack should already be empty here.
+
+ ss.pushAttribute(21, value1, attrib);
+ //ss.pushAttribute(22, value1, attrib); //FIXME pushing twice the same value bugs out atm
+ ss.pushAttribute(22, value2, attrib);
+
+ value = ss.popAttribute(24, attrib);
+ //assertEquals(value1, value);
+ assertEquals(value2, value);
+
+ value = ss.popAttribute(26, attrib);
+ assertEquals(value1, value);
+
+ value = ss.popAttribute(28, attrib);
+ assertEquals(null, value); // Stack should already be empty here.
+
+ ss.closeHistory(30);
+ attribute = ss.getQuarkAbsolute("Test", "stack");
+ }
+
+ /**
+ * Clean-up after running a test. Delete the .ht file we created.
+ */
+ @After
+ public void tearDown() {
+ testHtFile.delete();
+ }
+
+ /**
+ * Test that the value of the stack-attribute at the start and end of the
+ * history are correct.
+ */
+ @Test
+ public void testBeginEnd() {
+ try {
+ ITmfStateInterval interval = ss.querySingleState(0, attribute);
+ assertEquals(0, interval.getStartTime());
+ assertEquals(1, interval.getEndTime());
+ assertTrue(interval.getStateValue().isNull());
+
+ interval = ss.querySingleState(29, attribute);
+ assertEquals(26, interval.getStartTime());
+ assertEquals(30, interval.getEndTime());
+ assertTrue(interval.getStateValue().isNull());
+
+ } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException e) {
+ fail(errMsg + e.toString());
+ }
+ }
+
+ /**
+ * Run single queries on the attribute stacks (with .querySingleState()).
+ */
+ @Test
+ public void testSingleQueries() {
+ try {
+ final int subAttribute1 = ss.getQuarkRelative(attribute, "1");
+ final int subAttribute2 = ss.getQuarkRelative(attribute, "2");
+
+ /* Test the stack attributes themselves */
+ ITmfStateInterval interval = ss.querySingleState(11, attribute);
+ assertEquals(4, interval.getStateValue().unboxInt());
+
+ interval = ss.querySingleState(24, attribute);
+ assertEquals(1, interval.getStateValue().unboxInt());
+
+ /* Go retrieve the user values manually */
+ interval = ss.querySingleState(10, subAttribute1);
+ assertEquals(value1, interval.getStateValue()); //
+
+ interval = ss.querySingleState(22, subAttribute2);
+ assertEquals(value2, interval.getStateValue());
+
+ interval = ss.querySingleState(25, subAttribute2);
+ assertTrue(interval.getStateValue().isNull()); // Stack depth is 1 at that point.
+
+ } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException e) {
+ fail(errMsg + e.toString());
+ }
+ }
+
+ /**
+ * Test the .querySingletStackTop() convenience method.
+ */
+ @Test
+ public void testStackTop() {
+ final ITmfStateSystemBuilder ss2 = ss;
+ assertNotNull(ss2);
+
+ try {
+ ITmfStateInterval interval = StateSystemUtils.querySingleStackTop(ss2, 10, attribute);
+ assertNotNull(interval);
+ assertEquals(value5, interval.getStateValue());
+
+ interval = StateSystemUtils.querySingleStackTop(ss2, 9, attribute);
+ assertNotNull(interval);
+ assertEquals(value4, interval.getStateValue());
+
+ interval = StateSystemUtils.querySingleStackTop(ss2, 13, attribute);
+ assertNotNull(interval);
+ assertEquals(value3, interval.getStateValue());
+
+ interval = StateSystemUtils.querySingleStackTop(ss2, 16, attribute);
+ assertNotNull(interval);
+ assertEquals(value1, interval.getStateValue());
+
+ interval = StateSystemUtils.querySingleStackTop(ss2, 25, attribute);
+ assertNotNull(interval);
+ assertEquals(value1, interval.getStateValue());
+
+ } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException e) {
+ fail(errMsg + e.toString());
+ }
+ }
+
+ /**
+ * Test the places where the stack is empty.
+ */
+ @Test
+ public void testEmptyStack() {
+ final ITmfStateSystemBuilder ss2 = ss;
+ assertNotNull(ss2);
+
+ try {
+ /* At the start */
+ ITmfStateInterval interval = ss.querySingleState(1, attribute);
+ assertTrue(interval.getStateValue().isNull());
+ interval = StateSystemUtils.querySingleStackTop(ss2, 1, attribute);
+ assertEquals(null, interval);
+
+ /* Between the two "stacks" in the state history */
+ interval = ss.querySingleState(19, attribute);
+ assertTrue(interval.getStateValue().isNull());
+ interval = StateSystemUtils.querySingleStackTop(ss2, 19, attribute);
+ assertEquals(null, interval);
+
+ /* At the end */
+ interval = ss.querySingleState(27, attribute);
+ assertTrue(interval.getStateValue().isNull());
+ interval = StateSystemUtils.querySingleStackTop(ss2, 27, attribute);
+ assertEquals(null, interval);
+
+ } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException e) {
+ fail(errMsg + e.toString());
+ }
+ }
+
+ /**
+ * Test full-queries (.queryFullState()) on the attribute stacks.
+ */
+ @Test
+ public void testFullQueries() {
+ List<ITmfStateInterval> state;
+ try {
+ final int subAttrib1 = ss.getQuarkRelative(attribute, "1");
+ final int subAttrib2 = ss.getQuarkRelative(attribute, "2");
+ final int subAttrib3 = ss.getQuarkRelative(attribute, "3");
+ final int subAttrib4 = ss.getQuarkRelative(attribute, "4");
+
+ /* Stack depth = 5 */
+ state = ss.queryFullState(10);
+ assertEquals(5, state.get(attribute).getStateValue().unboxInt());
+ assertEquals(value1, state.get(subAttrib1).getStateValue());
+ assertEquals(value2, state.get(subAttrib2).getStateValue());
+ assertEquals(value3, state.get(subAttrib3).getStateValue());
+ assertEquals(value4, state.get(subAttrib4).getStateValue());
+
+ /* Stack is empty */
+ state = ss.queryFullState(18);
+ assertTrue(state.get(attribute).getStateValue().isNull());
+ assertTrue(state.get(subAttrib1).getStateValue().isNull());
+ assertTrue(state.get(subAttrib2).getStateValue().isNull());
+ assertTrue(state.get(subAttrib3).getStateValue().isNull());
+ assertTrue(state.get(subAttrib4).getStateValue().isNull());
+
+ /* Stack depth = 1 */
+ state = ss.queryFullState(21);
+ assertEquals(1, state.get(attribute).getStateValue().unboxInt());
+ assertEquals(value1, state.get(subAttrib1).getStateValue());
+ assertTrue(state.get(subAttrib2).getStateValue().isNull());
+ assertTrue(state.get(subAttrib3).getStateValue().isNull());
+ assertTrue(state.get(subAttrib4).getStateValue().isNull());
+
+ } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException e) {
+ fail(errMsg + e.toString());
+ }
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2014, 2015 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
+import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
+import org.eclipse.tracecompass.statesystem.core.StateSystemFactory;
+import org.eclipse.tracecompass.statesystem.core.StateSystemUtils;
+import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
+import org.eclipse.tracecompass.statesystem.core.backend.StateHistoryBackendFactory;
+import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
+import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test the {@link StateSystemUtils} class
+ *
+ * @author Geneviève Bastien
+ */
+public class StateSystemUtilsTest {
+
+ private static final long START_TIME = 1000L;
+ private static final @NonNull String DUMMY_STRING = "test";
+
+ private ITmfStateSystemBuilder fStateSystem;
+
+ /**
+ * Build a small test state system in memory
+ */
+ @Before
+ public void setupStateSystem() {
+ try {
+ IStateHistoryBackend backend = StateHistoryBackendFactory.createInMemoryBackend(DUMMY_STRING, START_TIME);
+ fStateSystem = StateSystemFactory.newStateSystem(backend);
+ int quark = fStateSystem.getQuarkAbsoluteAndAdd(DUMMY_STRING);
+
+ fStateSystem.modifyAttribute(1200L, TmfStateValue.newValueInt(10), quark);
+ fStateSystem.modifyAttribute(1500L, TmfStateValue.newValueInt(20), quark);
+ fStateSystem.closeHistory(2000L);
+ } catch (StateValueTypeException | AttributeNotFoundException e) {
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Clean-up
+ */
+ @After
+ public void tearDown() {
+ fStateSystem.dispose();
+ }
+
+ /**
+ * Test the {@link StateSystemUtils#queryUntilNonNullValue} method.
+ */
+ @Test
+ public void testQueryUntilNonNullValue() {
+ ITmfStateSystem ss = fStateSystem;
+ assertNotNull(ss);
+
+ int quark;
+ try {
+ quark = ss.getQuarkAbsolute(DUMMY_STRING);
+
+ /* Should return null if requested range is not within range */
+ assertNull(StateSystemUtils.queryUntilNonNullValue(ss, quark, 0, 999L));
+ assertNull(StateSystemUtils.queryUntilNonNullValue(ss, quark, 2001L, 5000L));
+
+ /*
+ * Should return null if request within range, but condition is
+ * false
+ */
+ assertNull(StateSystemUtils.queryUntilNonNullValue(ss, quark, 1000L, 1199L));
+
+ /*
+ * Should return the right interval if an interval is within range,
+ * even if the range starts or ends outside state system range
+ */
+ ITmfStateInterval interval = StateSystemUtils.queryUntilNonNullValue(ss, quark, 1000L, 1300L);
+ assertNotNull(interval);
+ assertEquals(ITmfStateValue.Type.INTEGER, interval.getStateValue().getType());
+ assertEquals(10, interval.getStateValue().unboxInt());
+
+ interval = StateSystemUtils.queryUntilNonNullValue(ss, quark, 800L, 2500L);
+ assertNotNull(interval);
+ assertEquals(ITmfStateValue.Type.INTEGER, interval.getStateValue().getType());
+ assertEquals(10, interval.getStateValue().unboxInt());
+
+ interval = StateSystemUtils.queryUntilNonNullValue(ss, quark, 1300L, 1800L);
+ assertNotNull(interval);
+ assertEquals(ITmfStateValue.Type.INTEGER, interval.getStateValue().getType());
+ assertEquals(10, interval.getStateValue().unboxInt());
+
+ interval = StateSystemUtils.queryUntilNonNullValue(ss, quark, 1500L, 1800L);
+ assertNotNull(interval);
+ assertEquals(ITmfStateValue.Type.INTEGER, interval.getStateValue().getType());
+ assertEquals(20, interval.getStateValue().unboxInt());
+
+ interval = StateSystemUtils.queryUntilNonNullValue(ss, quark, 1800L, 2500L);
+ assertNotNull(interval);
+ assertEquals(ITmfStateValue.Type.INTEGER, interval.getStateValue().getType());
+ assertEquals(20, interval.getStateValue().unboxInt());
+
+ } catch (AttributeNotFoundException e) {
+ fail(e.getMessage());
+ }
+
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2013, 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.tests.backend;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * Test suite for org.eclipse.tracecompass.statesystem.core.backend
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ InMemoryBackendTest.class
+})
+public class AllTests {
+
+}
\ No newline at end of file
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2013, 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Matthew Khouzam - Initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.tests.backend;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
+import org.eclipse.tracecompass.statesystem.core.backend.StateHistoryBackendFactory;
+import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.statesystem.core.interval.TmfStateInterval;
+import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test cases for the in-memory backend
+ *
+ * @author Matthew Khouzam
+ */
+public class InMemoryBackendTest {
+
+ private static final int NUMBER_OF_ATTRIBUTES = 10;
+ private static IStateHistoryBackend fixture;
+
+ /**
+ * Test setup. make a state system that is moderately large
+ */
+ @BeforeClass
+ public static void init() {
+ fixture = StateHistoryBackendFactory.createInMemoryBackend("test-ss", 0);
+ for (int attribute = 0; attribute < NUMBER_OF_ATTRIBUTES; attribute++) {
+ for (int timeStart = 0; timeStart < 1000; timeStart++) {
+ try {
+ final int stateEndTime = (timeStart * 100) + 90 + attribute;
+ final int stateStartTime = timeStart * 100 + attribute;
+ fixture.insertPastState(stateStartTime, stateEndTime, attribute, TmfStateValue.newValueInt(timeStart % 100));
+ if (timeStart != 999) {
+ fixture.insertPastState(stateEndTime + 1, stateEndTime + 9, attribute, TmfStateValue.nullValue());
+ }
+ } catch (TimeRangeException e) {
+ /* Should not happen here */
+ throw new IllegalStateException();
+ }
+ }
+ }
+ }
+
+ private static void testInterval(ITmfStateInterval interval, int startTime,
+ int endTime, int value) {
+ assertNotNull(interval);
+ assertEquals(startTime, interval.getStartTime());
+ assertEquals(endTime, interval.getEndTime());
+ try {
+ assertEquals(value, interval.getStateValue().unboxInt());
+ } catch (StateValueTypeException e) {
+ fail(e.getMessage());
+ }
+ }
+
+
+ /**
+ * Test at start time
+ */
+ @Test
+ public void testStartTime() {
+ assertEquals(0, fixture.getStartTime());
+ }
+
+ /**
+ * Test at end time
+ */
+ @Test
+ public void testEndTime() {
+ assertEquals(99999, fixture.getEndTime());
+ }
+
+ /**
+ * Query the state system
+ */
+ @Test
+ public void testDoQuery() {
+ List<ITmfStateInterval> interval = new ArrayList<>(NUMBER_OF_ATTRIBUTES);
+ for (int i = 0; i < NUMBER_OF_ATTRIBUTES; i++) {
+ interval.add(null);
+ }
+ try {
+ fixture.doQuery(interval, 950);
+ } catch (TimeRangeException | StateSystemDisposedException e) {
+ fail(e.getMessage());
+ }
+
+ assertEquals(NUMBER_OF_ATTRIBUTES, interval.size());
+ testInterval(interval.get(0), 900, 990, 9);
+ testInterval(interval.get(1), 901, 991, 9);
+ testInterval(interval.get(2), 902, 992, 9);
+ testInterval(interval.get(3), 903, 993, 9);
+ testInterval(interval.get(4), 904, 994, 9);
+ testInterval(interval.get(5), 905, 995, 9);
+ testInterval(interval.get(6), 906, 996, 9);
+ testInterval(interval.get(7), 907, 997, 9);
+ testInterval(interval.get(8), 908, 998, 9);
+ testInterval(interval.get(9), 909, 999, 9);
+ }
+
+
+ /**
+ * Test single attribute then compare it to a full query
+ */
+ @Test
+ public void testQueryAttribute() {
+ try {
+ ITmfStateInterval interval[] = new TmfStateInterval[10];
+ for (int i = 0; i < 10; i++) {
+ interval[i] = fixture.doSingularQuery(950, i);
+ }
+
+ testInterval(interval[0], 900, 990, 9);
+ testInterval(interval[1], 901, 991, 9);
+ testInterval(interval[2], 902, 992, 9);
+ testInterval(interval[3], 903, 993, 9);
+ testInterval(interval[4], 904, 994, 9);
+ testInterval(interval[5], 905, 995, 9);
+ testInterval(interval[6], 906, 996, 9);
+ testInterval(interval[7], 907, 997, 9);
+ testInterval(interval[8], 908, 998, 9);
+ testInterval(interval[9], 909, 999, 9);
+
+ List<ITmfStateInterval> intervalQuery = new ArrayList<>(NUMBER_OF_ATTRIBUTES);
+ for (int i = 0; i < NUMBER_OF_ATTRIBUTES; i++) {
+ intervalQuery.add(null);
+ }
+
+ fixture.doQuery(intervalQuery, 950);
+ ITmfStateInterval ref[] = intervalQuery.toArray(new ITmfStateInterval[0]);
+ assertArrayEquals(ref, interval);
+
+ } catch (TimeRangeException | AttributeNotFoundException | StateSystemDisposedException e) {
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Test single attribute that should not exist
+ */
+ @Test
+ public void testQueryAttributeEmpty() {
+ try {
+ ITmfStateInterval interval = fixture.doSingularQuery(999, 0);
+ assertEquals(TmfStateValue.nullValue(), interval.getStateValue());
+
+ } catch (TimeRangeException | AttributeNotFoundException | StateSystemDisposedException e) {
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Test first element in ss
+ */
+ @Test
+ public void testBegin() {
+ try {
+ ITmfStateInterval interval = fixture.doSingularQuery(0, 0);
+ assertEquals(0, interval.getStartTime());
+ assertEquals(90, interval.getEndTime());
+ assertEquals(0, interval.getStateValue().unboxInt());
+
+ } catch (TimeRangeException | AttributeNotFoundException | StateSystemDisposedException e) {
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Test last element in ss
+ */
+ @Test
+ public void testEnd() {
+ try {
+ ITmfStateInterval interval = fixture.doSingularQuery(99998, 9);
+ testInterval(interval, 99909, 99999, 99);
+
+ } catch (TimeRangeException | AttributeNotFoundException | StateSystemDisposedException e) {
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Test out of range query
+ *
+ * @throws TimeRangeException
+ * Expected
+ */
+ @Test(expected = TimeRangeException.class)
+ public void testOutOfRange_1() throws TimeRangeException {
+ try {
+ ITmfStateInterval interval = fixture.doSingularQuery(-1, 0);
+ assertNull(interval);
+
+ } catch (AttributeNotFoundException | StateSystemDisposedException e) {
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Test out of range query
+ *
+ * @throws TimeRangeException
+ * Expected
+ */
+ @Test(expected = TimeRangeException.class)
+ public void testOutOfRange_2() throws TimeRangeException {
+ try {
+ ITmfStateInterval interval = fixture.doSingularQuery(100000, 0);
+ assertNull(interval);
+
+ } catch (AttributeNotFoundException | StateSystemDisposedException e) {
+ fail(e.getMessage());
+ }
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2014 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Naser Ezzati - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.tests.statevalue;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * Test suite for the StateValue package
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ StateValueCompareToTest.class
+})
+public class AllTests {
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2014 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made availabComparisonOperator.LE under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is availabComparisonOperator.LE at
+ * http://www.eclipse.org/ComparisonOperator.LEgal/epl-v10.html
+ *
+ * Contributors:
+ * Naser Ezzati - Initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.tests.statevalue;
+
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
+import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
+import org.junit.Test;
+
+/**
+ * Unit test for the {@link ITmfStateValue#compareTo(ITmfStateValue)} method
+ *
+ * @author Naser Ezzati
+ */
+public class StateValueCompareToTest {
+
+ // ------------------------------------------------------------------------
+ // Static fields
+ // ------------------------------------------------------------------------
+
+ /* State values that will be used */
+ private static final ITmfStateValue BASE_INT_VALUE = TmfStateValue.newValueInt(10);
+ private static final ITmfStateValue BIGGER_INT_VALUE = TmfStateValue.newValueInt(20);
+ private static final ITmfStateValue SMALLER_INT_VALUE = TmfStateValue.newValueInt(6);
+
+ private static final ITmfStateValue BASE_LONG_VALUE = TmfStateValue.newValueLong(10);
+ private static final ITmfStateValue BIGGER_LONG_VALUE = TmfStateValue.newValueLong(20);
+ private static final ITmfStateValue SMALLER_LONG_VALUE = TmfStateValue.newValueLong(6);
+ private static final ITmfStateValue MIN_LONG_VALUE = TmfStateValue.newValueLong(Long.MIN_VALUE);
+ private static final ITmfStateValue MAX_LONG_VALUE = TmfStateValue.newValueLong(Long.MAX_VALUE);
+
+ private static final ITmfStateValue BASE_DOUBLE_VALUE = TmfStateValue.newValueDouble(10.00);
+ private static final ITmfStateValue BIGGER_DOUBLE_VALUE1 = TmfStateValue.newValueDouble(20.00);
+ private static final ITmfStateValue BIGGER_DOUBLE_VALUE2 = TmfStateValue.newValueDouble(10.03);
+ private static final ITmfStateValue SMALLER_DOUBLE_VALUE1 = TmfStateValue.newValueDouble(6.00);
+ private static final ITmfStateValue SMALLER_DOUBLE_VALUE2 = TmfStateValue.newValueDouble(9.99);
+ private static final ITmfStateValue MIN_DOUBLE_VALUE = TmfStateValue.newValueDouble(Double.MIN_VALUE);
+ private static final ITmfStateValue MAX_DOUBLE_VALUE = TmfStateValue.newValueDouble(Double.MAX_VALUE);
+ private static final ITmfStateValue POSITIVE_INFINITY = TmfStateValue.newValueDouble(Double.POSITIVE_INFINITY);
+ private static final ITmfStateValue NEGATIVE_INFINITY = TmfStateValue.newValueDouble(Double.NEGATIVE_INFINITY);
+
+ private static final ITmfStateValue BASE_STRING_VALUE = TmfStateValue.newValueString("D");
+ private static final ITmfStateValue BIGGER_STRING_VALUE = TmfStateValue.newValueString("Z");
+ private static final ITmfStateValue SMALLER_STRING_VALUE = TmfStateValue.newValueString("A");
+
+ private static final ITmfStateValue NULL_VALUE = TmfStateValue.nullValue();
+
+ // ------------------------------------------------------------------------
+ // Comparisons of Integer state values
+ // ------------------------------------------------------------------------
+
+ /**
+ * Compare Integer state values together
+ */
+ @Test
+ public void compareIntWithInt() {
+ assertTrue(BASE_INT_VALUE.compareTo(BASE_INT_VALUE) == 0);
+ assertTrue(BASE_INT_VALUE.compareTo(BIGGER_INT_VALUE) < 0);
+ assertTrue(BASE_INT_VALUE.compareTo(SMALLER_INT_VALUE) > 0);
+ }
+
+ /**
+ * Compare Integer with Long state values
+ */
+ @Test
+ public void compareIntWithLong() {
+ assertTrue(BASE_INT_VALUE.compareTo(BASE_LONG_VALUE) == 0);
+ assertTrue(BASE_INT_VALUE.compareTo(BIGGER_LONG_VALUE) < 0);
+ assertTrue(BASE_INT_VALUE.compareTo(MAX_LONG_VALUE) < 0);
+
+ assertTrue(BASE_INT_VALUE.compareTo(SMALLER_LONG_VALUE) > 0);
+ assertTrue(BASE_INT_VALUE.compareTo(MIN_LONG_VALUE) > 0);
+ }
+
+ /**
+ * Compare Integer with Double state values
+ */
+ @Test
+ public void compareIntWithDouble() {
+ assertTrue(BASE_INT_VALUE.compareTo(BASE_DOUBLE_VALUE) == 0);
+ assertTrue(BASE_INT_VALUE.compareTo(BIGGER_DOUBLE_VALUE1) < 0);
+ assertTrue(BASE_INT_VALUE.compareTo(BIGGER_DOUBLE_VALUE2) < 0);
+ assertTrue(BASE_INT_VALUE.compareTo(MAX_DOUBLE_VALUE) < 0);
+ assertTrue(BASE_INT_VALUE.compareTo(POSITIVE_INFINITY) < 0);
+ assertTrue(BASE_INT_VALUE.compareTo(SMALLER_DOUBLE_VALUE1) > 0);
+ assertTrue(BASE_INT_VALUE.compareTo(SMALLER_DOUBLE_VALUE2) > 0);
+ assertTrue(BASE_INT_VALUE.compareTo(MIN_DOUBLE_VALUE) > 0);
+ assertTrue(BASE_INT_VALUE.compareTo(NEGATIVE_INFINITY) > 0);
+ }
+
+ /**
+ * Compare Integer with Null state values
+ */
+ @Test
+ public void compareIntWithNull() {
+ assertTrue(BASE_INT_VALUE.compareTo(NULL_VALUE) > 0);
+ }
+
+ /**
+ * Compare Integer with String state values (should fail)
+ */
+ @Test(expected = StateValueTypeException.class)
+ public void tcompareIntWithString() {
+ BASE_INT_VALUE.compareTo(BASE_STRING_VALUE);
+ }
+
+ // ------------------------------------------------------------------------
+ // Comparisons of Long state values
+ // ------------------------------------------------------------------------
+
+ /**
+ * Compare Long with Integer state values
+ */
+ @Test
+ public void compareLongWithInt() {
+ // with Integer
+ assertTrue(BASE_LONG_VALUE.compareTo(BASE_INT_VALUE) == 0);
+ assertTrue(BASE_LONG_VALUE.compareTo(BIGGER_INT_VALUE) < 0);
+ assertTrue(BASE_LONG_VALUE.compareTo(SMALLER_INT_VALUE) > 0);
+ }
+
+ /**
+ * Compare Long state values together
+ */
+ @Test
+ public void compareLongWithLong() {
+ assertTrue(BASE_LONG_VALUE.compareTo(BASE_LONG_VALUE) == 0);
+ assertTrue(BASE_LONG_VALUE.compareTo(BIGGER_LONG_VALUE) < 0);
+ assertTrue(BASE_LONG_VALUE.compareTo(MAX_LONG_VALUE) < 0);
+ assertTrue(BASE_LONG_VALUE.compareTo(SMALLER_LONG_VALUE) > 0);
+ assertTrue(BASE_LONG_VALUE.compareTo(MIN_LONG_VALUE) > 0);
+ }
+
+ /**
+ * Compare Long with Double state values
+ */
+ @Test
+ public void compareLongWithDouble() {
+ assertTrue(BASE_LONG_VALUE.compareTo(BASE_DOUBLE_VALUE) == 0);
+ assertTrue(BASE_LONG_VALUE.compareTo(BIGGER_DOUBLE_VALUE1) < 0);
+ assertTrue(BASE_LONG_VALUE.compareTo(BIGGER_DOUBLE_VALUE2) < 0);
+ assertTrue(BASE_LONG_VALUE.compareTo(MAX_DOUBLE_VALUE) < 0);
+ assertTrue(BASE_LONG_VALUE.compareTo(POSITIVE_INFINITY) < 0);
+ assertTrue(BASE_LONG_VALUE.compareTo(SMALLER_DOUBLE_VALUE1) > 0);
+ assertTrue(BASE_LONG_VALUE.compareTo(SMALLER_DOUBLE_VALUE2) > 0);
+ assertTrue(BASE_LONG_VALUE.compareTo(MIN_DOUBLE_VALUE) > 0);
+ assertTrue(BASE_LONG_VALUE.compareTo(NEGATIVE_INFINITY) > 0);
+ }
+
+ /**
+ * Compare Long with Null state values
+ */
+ @Test
+ public void compareLongWithNull() {
+ assertTrue(BASE_LONG_VALUE.compareTo(NULL_VALUE) > 0);
+ }
+
+ /**
+ * Compare Long with String state values (should fail)
+ */
+ @Test(expected = StateValueTypeException.class)
+ public void compareLongWithString() {
+ BASE_LONG_VALUE.compareTo(BASE_STRING_VALUE);
+ }
+
+ // ------------------------------------------------------------------------
+ // Comparisons of Double state values
+ // ------------------------------------------------------------------------
+
+ /**
+ * Compare Double with Integer state values
+ */
+ @Test
+ public void compareDoubleWithInt() {
+ assertTrue(BASE_DOUBLE_VALUE.compareTo(BASE_INT_VALUE) == 0);
+ assertTrue(BASE_DOUBLE_VALUE.compareTo(BIGGER_INT_VALUE) < 0);
+ assertTrue(BASE_DOUBLE_VALUE.compareTo(SMALLER_INT_VALUE) > 0);
+ }
+
+ /**
+ * Compare Double with Long state values
+ */
+ @Test
+ public void compareDoubleWithLong() {
+ assertTrue(BASE_DOUBLE_VALUE.compareTo(BASE_LONG_VALUE) == 0);
+ assertTrue(BASE_DOUBLE_VALUE.compareTo(BIGGER_LONG_VALUE) < 0);
+ assertTrue(SMALLER_DOUBLE_VALUE2.compareTo(BASE_LONG_VALUE) < 0);
+ assertTrue(BASE_DOUBLE_VALUE.compareTo(MAX_LONG_VALUE) < 0);
+ assertTrue(BIGGER_DOUBLE_VALUE1.compareTo(SMALLER_LONG_VALUE) > 0);
+ assertTrue(BIGGER_DOUBLE_VALUE2.compareTo(BASE_LONG_VALUE) > 0);
+ assertTrue(BASE_DOUBLE_VALUE.compareTo(MIN_LONG_VALUE) > 0);
+ }
+
+ /**
+ * Compare Double state values together
+ */
+ @Test
+ public void compareDoubleWithDouble() {
+ assertTrue(BASE_DOUBLE_VALUE.compareTo(BASE_DOUBLE_VALUE) == 0);
+ assertTrue(BASE_DOUBLE_VALUE.compareTo(BIGGER_DOUBLE_VALUE2) < 0);
+ assertTrue(BASE_DOUBLE_VALUE.compareTo(MAX_DOUBLE_VALUE) < 0);
+ assertTrue(BASE_DOUBLE_VALUE.compareTo(SMALLER_DOUBLE_VALUE2) > 0);
+ assertTrue(BASE_DOUBLE_VALUE.compareTo(MIN_DOUBLE_VALUE) > 0);
+ }
+
+ /**
+ * Compare Double with Null state values
+ */
+ @Test
+ public void compareDoubleWithNull() {
+ /* NullValue.unboxDouble returns NaN */
+ assertTrue(BASE_DOUBLE_VALUE.compareTo(NULL_VALUE) < 0);
+ }
+
+ /**
+ * Compare Double with String state values (should fail)
+ */
+ @Test(expected = StateValueTypeException.class)
+ public void compareDoubleWithString() {
+ BASE_DOUBLE_VALUE.compareTo(BASE_STRING_VALUE);
+ }
+
+ // ------------------------------------------------------------------------
+ // Comparisons of String state values
+ // ------------------------------------------------------------------------
+
+ /**
+ * Compare String with Integer state values (should fail)
+ */
+ @Test(expected = StateValueTypeException.class)
+ public void compareStringWithInt() {
+ BASE_STRING_VALUE.compareTo(BASE_INT_VALUE);
+ }
+
+ /**
+ * Compare String with Long state values (should fail)
+ */
+ @Test(expected = StateValueTypeException.class)
+ public void compareStringWithLong() {
+ BASE_STRING_VALUE.compareTo(BASE_LONG_VALUE);
+ }
+
+ /**
+ * Compare String with Double state values (should fail)
+ */
+ @Test(expected = StateValueTypeException.class)
+ public void compareStringWithDouble() {
+ BASE_STRING_VALUE.compareTo(BASE_DOUBLE_VALUE);
+ }
+
+ /**
+ * Compare String state values together
+ */
+ @Test
+ public void compareStringWithString() {
+ assertTrue(BASE_STRING_VALUE.compareTo(BASE_STRING_VALUE) == 0);
+ assertTrue(BASE_STRING_VALUE.compareTo(SMALLER_STRING_VALUE) > 0);
+ assertTrue(BASE_STRING_VALUE.compareTo(BIGGER_STRING_VALUE) < 0);
+ }
+
+ /**
+ * Compare String with Null state values
+ */
+ @Test
+ public void compareStringWithNull() {
+ assertTrue(BASE_STRING_VALUE.compareTo(NULL_VALUE) > 0);
+ }
+
+ // ------------------------------------------------------------------------
+ // Comparisons of Null state values
+ // ------------------------------------------------------------------------
+
+ /**
+ * Compare Null with Integer state values
+ */
+ @Test
+ public void compareNullWithInt() {
+ assertTrue(NULL_VALUE.compareTo(BASE_INT_VALUE) < 0);
+ }
+
+ /**
+ * Compare Null with Long state values
+ */
+ @Test
+ public void compareNullWithLong() {
+ assertTrue(NULL_VALUE.compareTo(BASE_LONG_VALUE) < 0);
+ }
+
+ /**
+ * Compare Null with Double state values
+ */
+ @Test
+ public void compareNullWithDouble() {
+ /* NullValue.unboxDouble returns NaN */
+ assertTrue(NULL_VALUE.compareTo(BASE_DOUBLE_VALUE) > 0);
+ }
+
+ /**
+ * Compare Null with String state values
+ */
+ @Test
+ public void compareNullWithString() {
+ assertTrue(NULL_VALUE.compareTo(BASE_STRING_VALUE) < 0);
+ }
+
+ /**
+ * Compare Null state values together
+ */
+ @Test
+ public void compareNullWithNull() {
+ assertTrue(NULL_VALUE.compareTo(NULL_VALUE) == 0);
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.tracecompass.statesystem.core</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
--- /dev/null
+eclipse.preferences.version=1
+line.separator=\n
--- /dev/null
+eclipse.preferences.version=1
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=f
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=enabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=error
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=error
+org.eclipse.jdt.core.compiler.problem.deadCode=error
+org.eclipse.jdt.core.compiler.problem.deprecation=error
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=error
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=error
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=error
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=error
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=error
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=error
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=error
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=error
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=error
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=enabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=error
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=error
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=error
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=error
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=error
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=error
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=error
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=error
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=error
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=error
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=error
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=disabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=disabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=error
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=error
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=error
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=error
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error
+org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=0
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=false
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=250
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=false
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
--- /dev/null
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_tmf-style
+formatter_settings_version=12
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.overrideannotation=true
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=false
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=false
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=false
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=false
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=true
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
--- /dev/null
+ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error
+ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error
+API_USE_SCAN_FIELD_SEVERITY=Error
+API_USE_SCAN_METHOD_SEVERITY=Error
+API_USE_SCAN_TYPE_SEVERITY=Error
+CLASS_ELEMENT_TYPE_ADDED_METHOD=Error
+CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Error
+CLASS_ELEMENT_TYPE_REMOVED_FIELD=Error
+CLASS_ELEMENT_TYPE_REMOVED_METHOD=Error
+CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Error
+ENUM_ELEMENT_TYPE_REMOVED_FIELD=Error
+ENUM_ELEMENT_TYPE_REMOVED_METHOD=Error
+ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+FIELD_ELEMENT_TYPE_ADDED_VALUE=Error
+FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_TYPE=Error
+FIELD_ELEMENT_TYPE_CHANGED_VALUE=Error
+FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Error
+FIELD_ELEMENT_TYPE_REMOVED_VALUE=Error
+ILLEGAL_EXTEND=Warning
+ILLEGAL_IMPLEMENT=Warning
+ILLEGAL_INSTANTIATE=Warning
+ILLEGAL_OVERRIDE=Warning
+ILLEGAL_REFERENCE=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+INVALID_JAVADOC_TAG=Warning
+INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Warning
+LEAK_EXTEND=Warning
+LEAK_FIELD_DECL=Warning
+LEAK_IMPLEMENT=Warning
+LEAK_METHOD_PARAM=Warning
+LEAK_METHOD_RETURN_TYPE=Warning
+METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error
+METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+MISSING_EE_DESCRIPTIONS=Ignore
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
+UNUSED_PROBLEM_FILTERS=Warning
+automatically_removed_unused_problem_filters=false
+eclipse.preferences.version=1
+incompatible_api_component_version=Error
+incompatible_api_component_version_include_major_without_breaking_change=Disabled
+incompatible_api_component_version_include_minor_without_api_change=Disabled
+invalid_since_tag_version=Error
+malformed_since_tag=Error
+missing_since_tag=Error
+report_api_breakage_when_major_version_incremented=Disabled
+report_resolution_errors_api_component=Warning
--- /dev/null
+compilers.f.unresolved-features=1
+compilers.f.unresolved-plugins=1
+compilers.incompatible-environment=1
+compilers.p.build=1
+compilers.p.build.bin.includes=1
+compilers.p.build.encodings=2
+compilers.p.build.java.compiler=2
+compilers.p.build.java.compliance=1
+compilers.p.build.missing.output=2
+compilers.p.build.output.library=1
+compilers.p.build.source.library=1
+compilers.p.build.src.includes=1
+compilers.p.deprecated=1
+compilers.p.discouraged-class=1
+compilers.p.internal=1
+compilers.p.missing-packages=1
+compilers.p.missing-version-export-package=2
+compilers.p.missing-version-import-package=2
+compilers.p.missing-version-require-bundle=2
+compilers.p.no-required-att=0
+compilers.p.not-externalized-att=1
+compilers.p.unknown-attribute=1
+compilers.p.unknown-class=1
+compilers.p.unknown-element=1
+compilers.p.unknown-identifier=1
+compilers.p.unknown-resource=1
+compilers.p.unresolved-ex-points=0
+compilers.p.unresolved-import=0
+compilers.s.create-docs=false
+compilers.s.doc-folder=doc
+compilers.s.open-tags=1
+eclipse.preferences.version=1
--- /dev/null
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-Vendor: %Bundle-Vendor
+Bundle-Version: 1.0.0.qualifier
+Bundle-Localization: plugin
+Bundle-SymbolicName: org.eclipse.tracecompass.statesystem.core;singleton:=true
+Bundle-Activator: org.eclipse.tracecompass.internal.statesystem.core.Activator
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.core.resources,
+ org.eclipse.tracecompass.common.core
+Export-Package: org.eclipse.tracecompass.internal.statesystem.core;x-friends:="org.eclipse.tracecompass.statesystem.core.tests",
+ org.eclipse.tracecompass.internal.statesystem.core.backend;x-internal:=true,
+ org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;x-friends:="org.eclipse.tracecompass.statesystem.core.tests",
+ org.eclipse.tracecompass.statesystem.core,
+ org.eclipse.tracecompass.statesystem.core.backend,
+ org.eclipse.tracecompass.statesystem.core.exceptions,
+ org.eclipse.tracecompass.statesystem.core.interval,
+ org.eclipse.tracecompass.statesystem.core.statevalue
+Import-Package: com.google.common.collect;version="12.0.0"
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 5, 2006</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+###############################################################################
+# Copyright (c) 2014 Ericsson
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Ericsson - Initial API and implementation
+###############################################################################
+
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ plugin.properties,\
+ about.html,\
+ .
+src.includes = about.html
+additional.bundles = org.eclipse.jdt.annotation
+jars.extra.classpath = platform:/plugin/org.eclipse.jdt.annotation
--- /dev/null
+###############################################################################
+# Copyright (c) 2014 Ericsson
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Ericsson - Initial API and implementation
+###############################################################################
+
+Bundle-Vendor = Eclipse Trace Compass
+Bundle-Name = Trace Compass State System Core Plug-in
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2014, Ericsson
+
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>org.eclipse.tracecompass.statesystem-parent</artifactId>
+ <groupId>org.eclipse.tracecompass</groupId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>org.eclipse.tracecompass.statesystem.core</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <packaging>eclipse-plugin</packaging>
+
+ <name>Trace Compass State System Core Plug-in</name>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-source-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+ <groupId>org.eclipse.tracecompass</groupId>
+</project>
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.statesystem.core;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
+import org.osgi.framework.BundleContext;
+
+/**
+ * <b><u>Activator</u></b>
+ * <p>
+ * The activator class controls the plug-in life cycle
+ */
+public final class Activator extends Plugin {
+
+ // ------------------------------------------------------------------------
+ // Attributes
+ // ------------------------------------------------------------------------
+
+ /**
+ * The plug-in ID
+ */
+ public static final String PLUGIN_ID = "org.eclipse.tracecompass.statesystem.core"; //$NON-NLS-1$
+
+ /**
+ * The shared instance
+ */
+ private static Activator plugin;
+
+ // ------------------------------------------------------------------------
+ // Constructors
+ // ------------------------------------------------------------------------
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ // ------------------------------------------------------------------------
+ // Accessors
+ // ------------------------------------------------------------------------
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+ // ------------------------------------------------------------------------
+ // Operators
+ // ------------------------------------------------------------------------
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Logs a message with severity INFO in the runtime log of the plug-in.
+ *
+ * @param message A message to log
+ */
+ public void logInfo(String message) {
+ getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message));
+ }
+
+ /**
+ * Logs a message and exception with severity INFO in the runtime log of the plug-in.
+ *
+ * @param message A message to log
+ * @param exception A exception to log
+ */
+ public void logInfo(String message, Throwable exception) {
+ getLog().log(new Status(IStatus.INFO, PLUGIN_ID, message, exception));
+ }
+
+ /**
+ * Logs a message and exception with severity WARNING in the runtime log of the plug-in.
+ *
+ * @param message A message to log
+ */
+ public void logWarning(String message) {
+ getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message));
+ }
+
+ /**
+ * Logs a message and exception with severity WARNING in the runtime log of the plug-in.
+ *
+ * @param message A message to log
+ * @param exception A exception to log
+ */
+ public void logWarning(String message, Throwable exception) {
+ getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, message, exception));
+ }
+
+ /**
+ * Logs a message and exception with severity ERROR in the runtime log of the plug-in.
+ *
+ * @param message A message to log
+ */
+ public void logError(String message) {
+ getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message));
+ }
+
+ /**
+ * Logs a message and exception with severity ERROR in the runtime log of the plug-in.
+ *
+ * @param message A message to log
+ * @param exception A exception to log
+ */
+ public void logError(String message, Throwable exception) {
+ getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message, exception));
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2015 Ericsson, EfficiOS Inc.
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.statesystem.core;
+
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
+import java.io.PrintWriter;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.eclipse.jdt.annotation.NonNull;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * An Attribute is a "node" in the Attribute Tree. It represents a smallest
+ * unit of the model which can be in a particular state at a given time.
+ *
+ * It is abstract, as different implementations can provide different ways to
+ * access sub-attributes
+ *
+ * @author Alexandre Montplaisir
+ *
+ */
+public final class Attribute {
+
+ private final Attribute parent;
+ private final @NonNull String name;
+ private final int quark;
+
+ /** The sub-attributes (<basename, attribute>) of this attribute */
+ private final Map<String, Attribute> subAttributes;
+
+ /**
+ * Constructor
+ *
+ * @param parent
+ * The parent attribute of this one. Can be 'null' to represent
+ * this attribute is the root node of the tree.
+ * @param name
+ * Base name of this attribute
+ * @param quark
+ * The integer representation of this attribute
+ */
+ public Attribute(Attribute parent, @NonNull String name, int quark) {
+ this.parent = parent;
+ this.quark = quark;
+ this.name = name;
+ this.subAttributes = Collections.synchronizedMap(new LinkedHashMap<String, Attribute>());
+ }
+
+ // ------------------------------------------------------------------------
+ // Accessors
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get the quark (integer representation) of this attribute.
+ *
+ * @return The quark of this attribute
+ */
+ public int getQuark() {
+ return quark;
+ }
+
+ /**
+ * Get the name of this attribute.
+ *
+ * @return The name of this attribute
+ */
+ public @NonNull String getName() {
+ return name;
+ }
+
+ /**
+ * Get the list of child attributes below this one.
+ *
+ * @return The child attributes.
+ */
+ public Iterable<Attribute> getSubAttributes() {
+ return ImmutableList.copyOf(subAttributes.values());
+ }
+
+ /**
+ * Get the matching quark for a given path-of-strings
+ *
+ * @param path
+ * The path we are looking for, *relative to this node*.
+ * @return The matching quark, or -1 if that attribute does not exist.
+ */
+ public int getSubAttributeQuark(String... path) {
+ return this.getSubAttributeQuark(path, 0);
+ }
+
+ /**
+ * Other method to search through the attribute tree, but instead of
+ * returning the matching quark we return the AttributeTreeNode object
+ * itself. It can then be used as new "root node" for faster queries on the
+ * tree.
+ *
+ * @param path
+ * The target path, *relative to this node*
+ * @return The Node object matching the last element in the path, or "null"
+ * if that attribute does not exist.
+ */
+ public Attribute getSubAttributeNode(String... path) {
+ return this.getSubAttributeNode(path, 0);
+ }
+
+ /**
+ * "Inner" part of the previous public method, which is used recursively. To
+ * avoid having to copy sub-arrays to pass down, we just track where we are
+ * at with the index parameter. It uses getSubAttributeNode(), whose
+ * implementation is left to the derived classes.
+ */
+ private int getSubAttributeQuark(String[] path, int index) {
+ Attribute targetNode = this.getSubAttributeNode(path, index);
+ if (targetNode == null) {
+ return -1;
+ }
+ return targetNode.getQuark();
+ }
+
+ /**
+ * Get the parent attribute of this attribute
+ *
+ * @return The parent attribute
+ */
+ public Attribute getParentAttribute() {
+ return this.parent;
+ }
+
+ /**
+ * Get the parent quark of this attribute
+ *
+ * @return The quark of the parent attribute
+ */
+ public int getParentAttributeQuark() {
+ return this.parent.getQuark();
+ }
+
+ /* The methods how to access children are left to derived classes */
+
+ /**
+ * Add a sub-attribute to this attribute
+ *
+ * @param newSubAttribute The new attribute to add
+ */
+ public void addSubAttribute(Attribute newSubAttribute) {
+ if (newSubAttribute == null) {
+ throw new IllegalArgumentException();
+ }
+ subAttributes.put(newSubAttribute.getName(), newSubAttribute);
+ }
+
+ /**
+ * Get a sub-attribute from this node's sub-attributes
+ *
+ * @param path
+ * The *full* path to the attribute
+ * @param index
+ * The index in 'path' where this attribute is located
+ * (indicating where to start searching).
+ * @return The requested attribute
+ */
+ private Attribute getSubAttributeNode(String[] path, int index) {
+ final Attribute nextNode = subAttributes.get(path[index]);
+
+ if (nextNode == null) {
+ /* We don't have the expected child => the attribute does not exist */
+ return null;
+ }
+ if (index == path.length - 1) {
+ /* It's our job to process this request */
+ return nextNode;
+ }
+
+ /* Pass on the rest of the path to the relevant child */
+ return nextNode.getSubAttributeNode(path, index + 1);
+ }
+
+ /**
+ * Return a String array composed of the full (absolute) path representing
+ * this attribute
+ *
+ * @return The full attribute path elements
+ */
+ public @NonNull String[] getFullAttribute() {
+ LinkedList<String> list = new LinkedList<>();
+ Attribute curNode = this;
+
+ /* Add recursive parents to the list, but stop at the root node */
+ while (curNode.parent != null) {
+ list.addFirst(curNode.getName());
+ curNode = curNode.parent;
+ }
+
+ return checkNotNull(list.toArray(new String[0]));
+ }
+
+ /**
+ * Return the absolute path of this attribute, as a single slash-separated
+ * String.
+ *
+ * @return The full name of this attribute
+ */
+ public @NonNull String getFullAttributeName() {
+ String[] array = this.getFullAttribute();
+ StringBuffer buf = new StringBuffer();
+
+ for (int i = 0; i < array.length - 1; i++) {
+ buf.append(array[i]);
+ buf.append('/');
+ }
+ buf.append(array[array.length - 1]);
+ return checkNotNull(buf.toString());
+ }
+
+ @Override
+ public String toString() {
+ return getFullAttributeName() + " (" + quark + ')'; //$NON-NLS-1$
+ }
+
+ private int curDepth;
+
+ private void attributeNodeToString(PrintWriter writer, Attribute currentNode) {
+ writer.println(currentNode.getName() + " (" + currentNode.quark + ')'); //$NON-NLS-1$
+ curDepth++;
+
+ for (Attribute nextNode : currentNode.getSubAttributes()) {
+ /* Skip printing 'null' entries */
+ if (nextNode == null) {
+ continue;
+ }
+ for (int j = 0; j < curDepth - 1; j++) {
+ writer.print(" "); //$NON-NLS-1$
+ }
+ writer.print(" "); //$NON-NLS-1$
+ attributeNodeToString(writer, nextNode);
+ }
+ curDepth--;
+ return;
+ }
+
+ /**
+ * Debugging method to print the contents of this attribute
+ *
+ * @param writer
+ * PrintWriter where to write the information
+ */
+ public void debugPrint(PrintWriter writer) {
+ /* Only used for debugging, shouldn't be externalized */
+ writer.println("------------------------------"); //$NON-NLS-1$
+ writer.println("Attribute tree: (quark)\n"); //$NON-NLS-1$
+ curDepth = 0;
+ attributeNodeToString(writer, this);
+ writer.print('\n');
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2015 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ * Patrick Tasse - Add message to exceptions
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.statesystem.core;
+
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.PrintWriter;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
+
+/**
+ * The Attribute Tree is the /proc-like filesystem used to organize attributes.
+ * Each node of this tree is both like a file and a directory in the
+ * "file system".
+ *
+ * @author alexmont
+ *
+ */
+public final class AttributeTree {
+
+ /* "Magic number" for attribute tree files or file sections */
+ private static final int ATTRIB_TREE_MAGIC_NUMBER = 0x06EC3671;
+
+ private final StateSystem ss;
+ private final List<Attribute> attributeList;
+ private final Attribute attributeTreeRoot;
+
+ /**
+ * Standard constructor, create a new empty Attribute Tree
+ *
+ * @param ss
+ * The StateSystem to which this AT is attached
+ */
+ public AttributeTree(StateSystem ss) {
+ this.ss = ss;
+ this.attributeList = Collections.synchronizedList(new ArrayList<Attribute>());
+ this.attributeTreeRoot = new Attribute(null, "root", -1); //$NON-NLS-1$
+ }
+
+ /**
+ * "Existing file" constructor. Builds an attribute tree from a
+ * "mapping file" or mapping section previously saved somewhere.
+ *
+ * @param ss
+ * StateSystem to which this AT is attached
+ * @param fis
+ * File stream where to read the AT information. Make sure it's
+ * sought at the right place!
+ * @throws IOException
+ * If there is a problem reading from the file stream
+ */
+ public AttributeTree(StateSystem ss, FileInputStream fis) throws IOException {
+ this(ss);
+ ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(fis));
+
+ /* Read the header of the Attribute Tree file (or file section) */
+ int res = ois.readInt(); /* Magic number */
+ if (res != ATTRIB_TREE_MAGIC_NUMBER) {
+ throw new IOException("The attribute tree file section is either invalid or corrupted."); //$NON-NLS-1$
+ }
+
+
+ ArrayList<String[]> attribList;
+ try {
+ @SuppressWarnings("unchecked")
+ ArrayList<String[]> list = (ArrayList<String[]>) ois.readObject();
+ attribList = list;
+ } catch (ClassNotFoundException e) {
+ throw new IOException("Unrecognizable attribute list"); //$NON-NLS-1$
+ }
+
+ /*
+ * Now we have 'list', the ArrayList of String arrays representing all
+ * the attributes. Simply create attributes the normal way from them.
+ */
+ for (String[] attrib : attribList) {
+ this.getQuarkAndAdd(-1, attrib);
+ }
+ }
+
+ /**
+ * Tell the Attribute Tree to write itself somewhere in a file.
+ *
+ * @param file
+ * The file to write to
+ * @param pos
+ * The position (in bytes) in the file where to write
+ */
+ public void writeSelf(File file, long pos) {
+ try (FileOutputStream fos = new FileOutputStream(file, true);
+ FileChannel fc = fos.getChannel();) {
+ fc.position(pos);
+ try (ObjectOutputStream oos = new ObjectOutputStream(fos)) {
+
+ /* Write the almost-magic number */
+ oos.writeInt(ATTRIB_TREE_MAGIC_NUMBER);
+
+ /* Compute the serialized list of attributes and write it */
+ List<String[]> list = new ArrayList<>(attributeList.size());
+ for (Attribute entry : this.attributeList) {
+ list.add(entry.getFullAttribute());
+ }
+ oos.writeObject(list);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ /**
+ * Return the number of attributes this system as seen so far. Note that
+ * this also equals the integer value (quark) the next added attribute will
+ * have.
+ *
+ * @return The current number of attributes in the tree
+ */
+ public int getNbAttributes() {
+ return attributeList.size();
+ }
+
+ /**
+ * Get the quark for a given attribute path. No new attribute will be
+ * created : if the specified path does not exist, throw an error.
+ *
+ * @param startingNodeQuark
+ * The quark of the attribute from which relative queries will
+ * start. Use '-1' to start at the root node.
+ * @param subPath
+ * The path to the attribute, relative to the starting node.
+ * @return The quark of the specified attribute
+ * @throws AttributeNotFoundException
+ * If the specified path was not found
+ */
+ public int getQuarkDontAdd(int startingNodeQuark, String... subPath)
+ throws AttributeNotFoundException {
+ assert (startingNodeQuark >= -1);
+
+ Attribute prevNode;
+
+ /* If subPath is empty, simply return the starting quark */
+ if (subPath == null || subPath.length == 0) {
+ return startingNodeQuark;
+ }
+
+ /* Get the "starting node" */
+ if (startingNodeQuark == -1) {
+ prevNode = attributeTreeRoot;
+ } else {
+ prevNode = attributeList.get(startingNodeQuark);
+ }
+
+ int knownQuark = prevNode.getSubAttributeQuark(subPath);
+ if (knownQuark == -1) {
+ /*
+ * The attribute doesn't exist, but we have been specified to NOT
+ * add any new attributes.
+ */
+ throw new AttributeNotFoundException(ss.getSSID() + " Quark:" + startingNodeQuark + ", SubPath:" + Arrays.toString(subPath)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ /*
+ * The attribute was already existing, return the quark of that
+ * attribute
+ */
+ return knownQuark;
+ }
+
+ /**
+ * Get the quark of a given attribute path. If that specified path does not
+ * exist, it will be created (and the quark that was just created will be
+ * returned).
+ *
+ * @param startingNodeQuark
+ * The quark of the attribute from which relative queries will
+ * start. Use '-1' to start at the root node.
+ * @param subPath
+ * The path to the attribute, relative to the starting node.
+ * @return The quark of the attribute represented by the path
+ */
+ public synchronized int getQuarkAndAdd(int startingNodeQuark, String... subPath) {
+ // FIXME synchronized here is probably quite costly... maybe only locking
+ // the "for" would be enough?
+ assert (subPath != null && subPath.length > 0);
+ assert (startingNodeQuark >= -1);
+
+ Attribute nextNode = null;
+ Attribute prevNode;
+
+ /* Get the "starting node" */
+ if (startingNodeQuark == -1) {
+ prevNode = attributeTreeRoot;
+ } else {
+ prevNode = attributeList.get(startingNodeQuark);
+ }
+
+ int knownQuark = prevNode.getSubAttributeQuark(subPath);
+ if (knownQuark == -1) {
+ /*
+ * The attribute was not in the table previously, and we want to add
+ * it
+ */
+ for (String curDirectory : subPath) {
+ nextNode = prevNode.getSubAttributeNode(curDirectory);
+ if (nextNode == null) {
+ /* This is where we need to start adding */
+ nextNode = new Attribute(prevNode, checkNotNull(curDirectory), attributeList.size());
+ prevNode.addSubAttribute(nextNode);
+ attributeList.add(nextNode);
+ ss.addEmptyAttribute();
+ }
+ prevNode = nextNode;
+ }
+ return attributeList.size() - 1;
+ }
+ /*
+ * The attribute was already existing, return the quark of that
+ * attribute
+ */
+ return knownQuark;
+ }
+
+ /**
+ * Returns the sub-attributes of the quark passed in parameter
+ *
+ * @param attributeQuark
+ * The quark of the attribute to print the sub-attributes of.
+ * @param recursive
+ * Should the query be recursive or not? If false, only children
+ * one level deep will be returned. If true, all descendants will
+ * be returned (depth-first search)
+ * @return The list of quarks representing the children attributes
+ * @throws AttributeNotFoundException
+ * If 'attributeQuark' is invalid, or if there is no attrbiute
+ * associated to it.
+ */
+ public @NonNull List<Integer> getSubAttributes(int attributeQuark, boolean recursive)
+ throws AttributeNotFoundException {
+ List<Integer> listOfChildren = new ArrayList<>();
+ Attribute startingAttribute;
+
+ /* Check if the quark is valid */
+ if (attributeQuark < -1 || attributeQuark >= attributeList.size()) {
+ throw new AttributeNotFoundException(ss.getSSID() + " Quark:" + attributeQuark); //$NON-NLS-1$
+ }
+
+ /* Set up the node from which we'll start the search */
+ if (attributeQuark == -1) {
+ startingAttribute = attributeTreeRoot;
+ } else {
+ startingAttribute = attributeList.get(attributeQuark);
+ }
+
+ /* Iterate through the sub-attributes and add them to the list */
+ addSubAttributes(listOfChildren, startingAttribute, recursive);
+
+ return listOfChildren;
+ }
+
+ /**
+ * Returns the parent quark of the attribute. The root attribute has no
+ * parent and will return <code>-1</code>
+ *
+ * @param quark
+ * The quark of the attribute
+ * @return Quark of the parent attribute or <code>-1</code> for the root
+ * attribute
+ */
+ public int getParentAttributeQuark(int quark) {
+ if (quark == -1) {
+ return quark;
+ }
+ return attributeList.get(quark).getParentAttributeQuark();
+ }
+
+ private void addSubAttributes(List<Integer> list, Attribute curAttribute,
+ boolean recursive) {
+ for (Attribute childNode : curAttribute.getSubAttributes()) {
+ list.add(childNode.getQuark());
+ if (recursive) {
+ addSubAttributes(list, childNode, true);
+ }
+ }
+ }
+
+ /**
+ * Get then base name of an attribute specified by a quark.
+ *
+ * @param quark
+ * The quark of the attribute
+ * @return The (base) name of the attribute
+ */
+ public @NonNull String getAttributeName(int quark) {
+ return attributeList.get(quark).getName();
+ }
+
+ /**
+ * Get the full path name of an attribute specified by a quark.
+ *
+ * @param quark
+ * The quark of the attribute
+ * @return The full path name of the attribute
+ */
+ public @NonNull String getFullAttributeName(int quark) {
+ return attributeList.get(quark).getFullAttributeName();
+ }
+
+ /**
+ * Get the full path name (as an array of path elements) of an attribute
+ * specified by a quark.
+ *
+ * @param quark
+ * The quark of the attribute
+ * @return The path elements of the full path
+ */
+ public @NonNull String[] getFullAttributePathArray(int quark) {
+ return attributeList.get(quark).getFullAttribute();
+ }
+
+ /**
+ * Debug-print all the attributes in the tree.
+ *
+ * @param writer
+ * The writer where to print the output
+ */
+ public void debugPrint(PrintWriter writer) {
+ attributeTreeRoot.debugPrint(writer);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2015 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ * Patrick Tasse - Add message to exceptions
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.statesystem.core;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
+import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
+import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue.Type;
+import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
+
+/**
+ * This is the core class of the Generic State System. It contains all the
+ * methods to build and query a state history. It's exposed externally through
+ * the IStateSystemQuerier and IStateSystemBuilder interfaces, depending if the
+ * user needs read-only access or read-write access.
+ *
+ * When building, DON'T FORGET to call .closeHistory() when you are done
+ * inserting intervals, or the storage backend will have no way of knowing it
+ * can close and write itself to disk, and its thread will keep running.
+ *
+ * @author alexmont
+ *
+ */
+public class StateSystem implements ITmfStateSystemBuilder {
+
+ /* References to the inner structures */
+ private final AttributeTree attributeTree;
+ private final TransientState transState;
+ private final IStateHistoryBackend backend;
+
+ /* Latch tracking if the state history is done building or not */
+ private final CountDownLatch finishedLatch = new CountDownLatch(1);
+
+ private boolean buildCancelled = false;
+ private boolean isDisposed = false;
+
+ /**
+ * New-file constructor. For when you build a state system with a new file,
+ * or if the back-end does not require a file on disk.
+ *
+ * @param backend
+ * Back-end plugin to use
+ */
+ public StateSystem(@NonNull IStateHistoryBackend backend) {
+ this.backend = backend;
+ this.transState = new TransientState(backend);
+ this.attributeTree = new AttributeTree(this);
+ }
+
+ /**
+ * General constructor
+ *
+ * @param backend
+ * The "state history storage" back-end to use.
+ * @param newFile
+ * Put true if this is a new history started from scratch. It is
+ * used to tell the state system where to get its attribute tree.
+ * @throws IOException
+ * If there was a problem creating the new history file
+ */
+ public StateSystem(@NonNull IStateHistoryBackend backend, boolean newFile)
+ throws IOException {
+ this.backend = backend;
+ this.transState = new TransientState(backend);
+
+ if (newFile) {
+ attributeTree = new AttributeTree(this);
+ } else {
+ /* We're opening an existing file */
+ this.attributeTree = new AttributeTree(this, backend.supplyAttributeTreeReader());
+ transState.setInactive();
+ finishedLatch.countDown(); /* The history is already built */
+ }
+ }
+
+ @Override
+ public String getSSID() {
+ return backend.getSSID();
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return buildCancelled;
+ }
+
+ @Override
+ public void waitUntilBuilt() {
+ try {
+ finishedLatch.await();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public boolean waitUntilBuilt(long timeout) {
+ boolean ret = false;
+ try {
+ ret = finishedLatch.await(timeout, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return ret;
+ }
+
+ @Override
+ public synchronized void dispose() {
+ isDisposed = true;
+ if (transState.isActive()) {
+ transState.setInactive();
+ buildCancelled = true;
+ }
+ backend.dispose();
+ }
+
+ //--------------------------------------------------------------------------
+ // General methods related to the attribute tree
+ //--------------------------------------------------------------------------
+
+ /**
+ * Get the attribute tree associated with this state system. This should be
+ * the only way of accessing it (and if subclasses want to point to a
+ * different attribute tree than their own, they should only need to
+ * override this).
+ *
+ * @return The attribute tree
+ */
+ public AttributeTree getAttributeTree() {
+ return attributeTree;
+ }
+
+ /**
+ * Method used by the attribute tree when creating new attributes, to keep
+ * the attribute count in the transient state in sync.
+ */
+ public void addEmptyAttribute() {
+ transState.addEmptyEntry();
+ }
+
+ @Override
+ public int getNbAttributes() {
+ return getAttributeTree().getNbAttributes();
+ }
+
+ @Override
+ public String getAttributeName(int attributeQuark) {
+ return getAttributeTree().getAttributeName(attributeQuark);
+ }
+
+ @Override
+ public String getFullAttributePath(int attributeQuark) {
+ return getAttributeTree().getFullAttributeName(attributeQuark);
+ }
+
+ @Override
+ public String[] getFullAttributePathArray(int attributeQuark) {
+ return getAttributeTree().getFullAttributePathArray(attributeQuark);
+ }
+
+ //--------------------------------------------------------------------------
+ // Methods related to the storage backend
+ //--------------------------------------------------------------------------
+
+ @Override
+ public long getStartTime() {
+ return backend.getStartTime();
+ }
+
+ @Override
+ public long getCurrentEndTime() {
+ return backend.getEndTime();
+ }
+
+ @Override
+ public void closeHistory(long endTime) throws TimeRangeException {
+ File attributeTreeFile;
+ long attributeTreeFilePos;
+ long realEndTime = endTime;
+
+ if (realEndTime < backend.getEndTime()) {
+ /*
+ * This can happen (empty nodes pushing the border further, etc.)
+ * but shouldn't be too big of a deal.
+ */
+ realEndTime = backend.getEndTime();
+ }
+ transState.closeTransientState(realEndTime);
+ backend.finishedBuilding(realEndTime);
+
+ attributeTreeFile = backend.supplyAttributeTreeWriterFile();
+ attributeTreeFilePos = backend.supplyAttributeTreeWriterFilePosition();
+ if (attributeTreeFile != null) {
+ /*
+ * If null was returned, we simply won't save the attribute tree,
+ * too bad!
+ */
+ getAttributeTree().writeSelf(attributeTreeFile, attributeTreeFilePos);
+ }
+ finishedLatch.countDown(); /* Mark the history as finished building */
+ }
+
+ //--------------------------------------------------------------------------
+ // Quark-retrieving methods
+ //--------------------------------------------------------------------------
+
+ @Override
+ public int getQuarkAbsolute(String... attribute)
+ throws AttributeNotFoundException {
+ return getAttributeTree().getQuarkDontAdd(-1, attribute);
+ }
+
+ @Override
+ public int getQuarkAbsoluteAndAdd(String... attribute) {
+ return getAttributeTree().getQuarkAndAdd(-1, attribute);
+ }
+
+ @Override
+ public int getQuarkRelative(int startingNodeQuark, String... subPath)
+ throws AttributeNotFoundException {
+ return getAttributeTree().getQuarkDontAdd(startingNodeQuark, subPath);
+ }
+
+ @Override
+ public int getQuarkRelativeAndAdd(int startingNodeQuark, String... subPath) {
+ return getAttributeTree().getQuarkAndAdd(startingNodeQuark, subPath);
+ }
+
+ @Override
+ public List<Integer> getSubAttributes(int quark, boolean recursive)
+ throws AttributeNotFoundException {
+ return getAttributeTree().getSubAttributes(quark, recursive);
+ }
+
+ @Override
+ public List<Integer> getSubAttributes(int quark, boolean recursive, String pattern)
+ throws AttributeNotFoundException {
+ List<Integer> all = getSubAttributes(quark, recursive);
+ List<Integer> ret = new LinkedList<>();
+ for (Integer attQuark : all) {
+ String name = getAttributeName(attQuark.intValue());
+ if (name.matches(pattern)) {
+ ret.add(attQuark);
+ }
+ }
+ return ret;
+ }
+
+ @Override
+ public int getParentAttributeQuark(int quark) {
+ return getAttributeTree().getParentAttributeQuark(quark);
+ }
+
+ @Override
+ public List<Integer> getQuarks(String... pattern) {
+ List<Integer> quarks = new LinkedList<>();
+ List<String> prefix = new LinkedList<>();
+ List<String> suffix = new LinkedList<>();
+ boolean split = false;
+ String[] prefixStr;
+ String[] suffixStr;
+ List<Integer> directChildren;
+ int startingAttribute;
+
+ /* Fill the "prefix" and "suffix" parts of the pattern around the '*' */
+ for (String entry : pattern) {
+ if (entry.equals("*")) { //$NON-NLS-1$
+ if (split) {
+ /*
+ * Split was already true? This means there was more than
+ * one wildcard. This is not supported, return an empty
+ * list.
+ */
+ return quarks;
+ }
+ split = true;
+ continue;
+ }
+
+ if (split) {
+ suffix.add(entry);
+ } else {
+ prefix.add(entry);
+ }
+ }
+ prefixStr = prefix.toArray(new String[prefix.size()]);
+ suffixStr = suffix.toArray(new String[suffix.size()]);
+
+ /*
+ * If there was no wildcard, we'll only return the one matching
+ * attribute, if there is one.
+ */
+ if (!split) {
+ int quark;
+ try {
+ quark = getQuarkAbsolute(prefixStr);
+ } catch (AttributeNotFoundException e) {
+ /* It's fine, we'll just return the empty List */
+ return quarks;
+ }
+ quarks.add(quark);
+ return quarks;
+ }
+
+ try {
+ if (prefix.size() == 0) {
+ /*
+ * If 'prefix' is empty, this means the wildcard was the first
+ * element. Look for the root node's sub-attributes.
+ */
+ startingAttribute = -1;
+ } else {
+ startingAttribute = getQuarkAbsolute(prefixStr);
+ }
+ directChildren = getSubAttributes(startingAttribute, false);
+ } catch (AttributeNotFoundException e) {
+ /* That attribute path did not exist, return the empty array */
+ return quarks;
+ }
+
+ /*
+ * Iterate of all the sub-attributes, and only keep those who match the
+ * 'suffix' part of the initial pattern.
+ */
+ for (int childQuark : directChildren) {
+ int matchingQuark;
+ try {
+ matchingQuark = getQuarkRelative(childQuark, suffixStr);
+ } catch (AttributeNotFoundException e) {
+ continue;
+ }
+ quarks.add(matchingQuark);
+ }
+
+ return quarks;
+ }
+
+ //--------------------------------------------------------------------------
+ // Methods related to insertions in the history
+ //--------------------------------------------------------------------------
+
+ @Override
+ public void modifyAttribute(long t, ITmfStateValue value, int attributeQuark)
+ throws TimeRangeException, AttributeNotFoundException,
+ StateValueTypeException {
+ if (value == null) {
+ /*
+ * TODO Replace with @NonNull parameter (will require fixing all the
+ * state providers!)
+ */
+ throw new IllegalArgumentException();
+ }
+ transState.processStateChange(t, value, attributeQuark);
+ }
+
+ @Override
+ public void incrementAttribute(long t, int attributeQuark)
+ throws StateValueTypeException, TimeRangeException,
+ AttributeNotFoundException {
+ ITmfStateValue stateValue = queryOngoingState(attributeQuark);
+ int prevValue = 0;
+ /* if the attribute was previously null, start counting at 0 */
+ if (!stateValue.isNull()) {
+ prevValue = stateValue.unboxInt();
+ }
+ modifyAttribute(t, TmfStateValue.newValueInt(prevValue + 1),
+ attributeQuark);
+ }
+
+ @Override
+ public void pushAttribute(long t, ITmfStateValue value, int attributeQuark)
+ throws TimeRangeException, AttributeNotFoundException,
+ StateValueTypeException {
+ int stackDepth;
+ int subAttributeQuark;
+ ITmfStateValue previousSV = transState.getOngoingStateValue(attributeQuark);
+
+ if (previousSV.isNull()) {
+ /*
+ * If the StateValue was null, this means this is the first time we
+ * use this attribute. Leave stackDepth at 0.
+ */
+ stackDepth = 0;
+ } else if (previousSV.getType() == Type.INTEGER) {
+ /* Previous value was an integer, all is good, use it */
+ stackDepth = previousSV.unboxInt();
+ } else {
+ /* Previous state of this attribute was another type? Not good! */
+ throw new StateValueTypeException(getSSID() + " Quark:" + attributeQuark + ", Type:" + previousSV.getType() + ", Expected:" + Type.INTEGER); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ if (stackDepth >= 100000) {
+ /*
+ * Limit stackDepth to 100000, to avoid having Attribute Trees grow
+ * out of control due to buggy insertions
+ */
+ String message = " Stack limit reached, not pushing"; //$NON-NLS-1$
+ throw new AttributeNotFoundException(getSSID() + " Quark:" + attributeQuark + message); //$NON-NLS-1$
+ }
+
+ stackDepth++;
+ subAttributeQuark = getQuarkRelativeAndAdd(attributeQuark, String.valueOf(stackDepth));
+
+ modifyAttribute(t, TmfStateValue.newValueInt(stackDepth), attributeQuark);
+ modifyAttribute(t, value, subAttributeQuark);
+ }
+
+ @Override
+ public ITmfStateValue popAttribute(long t, int attributeQuark)
+ throws AttributeNotFoundException, TimeRangeException,
+ StateValueTypeException {
+ /* These are the state values of the stack-attribute itself */
+ ITmfStateValue previousSV = transState.getOngoingStateValue(attributeQuark);
+
+ if (previousSV.isNull()) {
+ /*
+ * Trying to pop an empty stack. This often happens at the start of
+ * traces, for example when we see a syscall_exit, without having
+ * the corresponding syscall_entry in the trace. Just ignore
+ * silently.
+ */
+ return null;
+ }
+ if (previousSV.getType() != Type.INTEGER) {
+ /*
+ * The existing value was not an integer (which is expected for
+ * stack tops), this doesn't look like a valid stack attribute.
+ */
+ throw new StateValueTypeException(getSSID() + " Quark:" + attributeQuark + ", Type:" + previousSV.getType() + ", Expected:" + Type.INTEGER); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ int stackDepth = previousSV.unboxInt();
+
+ if (stackDepth <= 0) {
+ /* This on the other hand should not happen... */
+ throw new StateValueTypeException(getSSID() + " Quark:" + attributeQuark + ", Stack depth:" + stackDepth); //$NON-NLS-1$//$NON-NLS-2$
+ }
+
+ /* The attribute should already exist at this point */
+ int subAttributeQuark = getQuarkRelative(attributeQuark, String.valueOf(stackDepth));
+ ITmfStateValue poppedValue = queryOngoingState(subAttributeQuark);
+
+ /* Update the state value of the stack-attribute */
+ ITmfStateValue nextSV;
+ if (--stackDepth == 0) {
+ /* Store a null state value */
+ nextSV = TmfStateValue.nullValue();
+ } else {
+ nextSV = TmfStateValue.newValueInt(stackDepth);
+ }
+ modifyAttribute(t, nextSV, attributeQuark);
+
+ /* Delete the sub-attribute that contained the user's state value */
+ removeAttribute(t, subAttributeQuark);
+
+ return poppedValue;
+ }
+
+ @Override
+ public void removeAttribute(long t, int attributeQuark)
+ throws TimeRangeException, AttributeNotFoundException {
+ if (attributeQuark < 0) {
+ throw new IllegalArgumentException();
+ }
+
+ /*
+ * Nullify our children first, recursively. We pass 'false' because we
+ * handle the recursion ourselves.
+ */
+ List<Integer> childAttributes = getSubAttributes(attributeQuark, false);
+ for (int childNodeQuark : childAttributes) {
+ if (attributeQuark == childNodeQuark) {
+ /* Something went very wrong when building out attribute tree */
+ throw new IllegalStateException();
+ }
+ removeAttribute(t, childNodeQuark);
+ }
+ /* Nullify ourselves */
+ try {
+ transState.processStateChange(t, TmfStateValue.nullValue(), attributeQuark);
+ } catch (StateValueTypeException e) {
+ /*
+ * Will not happen since we're inserting null values only, but poor
+ * compiler has no way of knowing this...
+ */
+ throw new IllegalStateException(e);
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ // "Current" query/update methods
+ //--------------------------------------------------------------------------
+
+ @Override
+ public ITmfStateValue queryOngoingState(int attributeQuark)
+ throws AttributeNotFoundException {
+ return transState.getOngoingStateValue(attributeQuark);
+ }
+
+ @Override
+ public long getOngoingStartTime(int attribute)
+ throws AttributeNotFoundException {
+ return transState.getOngoingStartTime(attribute);
+ }
+
+ @Override
+ public void updateOngoingState(ITmfStateValue newValue, int attributeQuark)
+ throws AttributeNotFoundException {
+ transState.changeOngoingStateValue(attributeQuark, newValue);
+ }
+
+ /**
+ * Modify the whole "ongoing state" (state values + start times). This can
+ * be used when "seeking" a state system to a different point in the trace
+ * (and restoring the known stateInfo at this location). Use with care!
+ *
+ * @param newStateIntervals
+ * The new List of state values to use as ongoing state info
+ */
+ protected void replaceOngoingState(@NonNull List<ITmfStateInterval> newStateIntervals) {
+ transState.replaceOngoingState(newStateIntervals);
+ }
+
+ //--------------------------------------------------------------------------
+ // Regular query methods (sent to the back-end)
+ //--------------------------------------------------------------------------
+
+ @Override
+ public synchronized List<ITmfStateInterval> queryFullState(long t)
+ throws TimeRangeException, StateSystemDisposedException {
+ if (isDisposed) {
+ throw new StateSystemDisposedException();
+ }
+
+ final int nbAttr = getNbAttributes();
+ List<ITmfStateInterval> stateInfo = new ArrayList<>(nbAttr);
+
+ /* Bring the size of the array to the current number of attributes */
+ for (int i = 0; i < nbAttr; i++) {
+ stateInfo.add(null);
+ }
+
+ /*
+ * If we are currently building the history, also query the "ongoing"
+ * states for stuff that might not yet be written to the history.
+ */
+ if (transState.isActive()) {
+ transState.doQuery(stateInfo, t);
+ }
+
+ /* Query the storage backend */
+ backend.doQuery(stateInfo, t);
+
+ /*
+ * We should have previously inserted an interval for every attribute.
+ */
+ for (ITmfStateInterval interval : stateInfo) {
+ if (interval == null) {
+ throw new IllegalStateException("Incoherent interval storage"); //$NON-NLS-1$
+ }
+ }
+ return stateInfo;
+ }
+
+ @Override
+ public ITmfStateInterval querySingleState(long t, int attributeQuark)
+ throws AttributeNotFoundException, TimeRangeException,
+ StateSystemDisposedException {
+ if (isDisposed) {
+ throw new StateSystemDisposedException();
+ }
+
+ ITmfStateInterval ret = transState.getIntervalAt(t, attributeQuark);
+ if (ret == null) {
+ /*
+ * The transient state did not have the information, let's look into
+ * the backend next.
+ */
+ ret = backend.doSingularQuery(t, attributeQuark);
+ }
+
+ if (ret == null) {
+ /*
+ * If we did our job correctly, there should be intervals for every
+ * possible attribute, over all the valid time range.
+ */
+ throw new IllegalStateException("Incoherent interval storage"); //$NON-NLS-1$
+ }
+ return ret;
+ }
+
+ //--------------------------------------------------------------------------
+ // Debug methods
+ //--------------------------------------------------------------------------
+
+ static void logMissingInterval(int attribute, long timestamp) {
+ Activator.getDefault().logInfo("No data found in history for attribute " + //$NON-NLS-1$
+ attribute + " at time " + timestamp + //$NON-NLS-1$
+ ", returning dummy interval"); //$NON-NLS-1$
+ }
+
+ /**
+ * Print out the contents of the inner structures.
+ *
+ * @param writer
+ * The PrintWriter in which to print the output
+ */
+ public void debugPrint(@NonNull PrintWriter writer) {
+ getAttributeTree().debugPrint(writer);
+ transState.debugPrint(writer);
+ backend.debugPrint(writer);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2015 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ * Patrick Tasse - Add message to exceptions
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.statesystem.core;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
+import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.statesystem.core.interval.TmfStateInterval;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue.Type;
+import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
+
+/**
+ * The Transient State is used to build intervals from punctual state changes.
+ * It contains a "state info" vector similar to the "current state", except here
+ * we also record the start time of every state stored in it.
+ *
+ * We can then build {@link ITmfStateInterval}'s, to be inserted in a
+ * {@link IStateHistoryBackend} when we detect state changes : the "start time"
+ * of the interval will be the recorded time we have here, and the "end time"
+ * will be the timestamp of the new state-changing event we just read.
+ *
+ * @author Alexandre Montplaisir
+ */
+@NonNullByDefault
+public class TransientState {
+
+ /* Indicates where to insert state changes that we generate */
+ private final IStateHistoryBackend fBackend;
+
+ private final ReentrantReadWriteLock fRWLock = new ReentrantReadWriteLock(false);
+
+ private volatile boolean fIsActive;
+ private volatile long fLatestTime;
+
+ /* A method accessing these arrays will have to go through the lock */
+ private List<ITmfStateValue> fOngoingStateInfo;
+ private List<Long> fOngoingStateStartTimes;
+ private List<Type> fStateValueTypes;
+
+ /**
+ * Constructor
+ *
+ * @param backend
+ * The back-end in which to insert the generated state intervals
+ */
+ public TransientState(IStateHistoryBackend backend) {
+ fBackend = backend;
+ fIsActive = true;
+ fOngoingStateInfo = new ArrayList<>();
+ fOngoingStateStartTimes = new ArrayList<>();
+ fStateValueTypes = new ArrayList<>();
+
+ fLatestTime = backend.getStartTime();
+ }
+
+ /**
+ * Get the latest time we have seen so far.
+ *
+ * @return The latest time seen in the transient state
+ */
+ public long getLatestTime() {
+ return fLatestTime;
+ }
+
+ /**
+ * Retrieve the ongoing state value for a given index (attribute quark).
+ *
+ * @param quark
+ * The quark of the attribute to look for
+ * @return The corresponding state value
+ * @throws AttributeNotFoundException
+ * If the quark is invalid
+ */
+ public ITmfStateValue getOngoingStateValue(int quark) throws AttributeNotFoundException {
+ fRWLock.readLock().lock();
+ try {
+ checkValidAttribute(quark);
+ ITmfStateValue ret = fOngoingStateInfo.get(quark);
+ if (ret == null) {
+ throw new IllegalStateException("Null interval stored in transient state"); //$NON-NLS-1$
+ }
+ return ret;
+ } finally {
+ fRWLock.readLock().unlock();
+ }
+ }
+
+ /**
+ * Retrieve the start time of the state in which the given attribute is in.
+ *
+ * @param quark
+ * The quark of the attribute to look for
+ * @return The start time of the current state for this attribute
+ * @throws AttributeNotFoundException
+ * If the quark is invalid
+ */
+ public long getOngoingStartTime(int quark) throws AttributeNotFoundException {
+ fRWLock.readLock().lock();
+ try {
+ checkValidAttribute(quark);
+ return fOngoingStateStartTimes.get(quark);
+ } finally {
+ fRWLock.readLock().unlock();
+ }
+ }
+
+ /**
+ * Modify the current state for a given attribute. This will not update the
+ * "ongoing state start time" in any way, so be careful when using this.
+ *
+ * @param quark
+ * The quark of the attribute to modify
+ * @param newValue
+ * The state value the attribute should have
+ * @throws AttributeNotFoundException
+ * If the quark is invalid
+ */
+ public void changeOngoingStateValue(int quark, ITmfStateValue newValue)
+ throws AttributeNotFoundException {
+ fRWLock.writeLock().lock();
+ try {
+ checkValidAttribute(quark);
+ fOngoingStateInfo.set(quark, newValue);
+ } finally {
+ fRWLock.writeLock().unlock();
+ }
+ }
+
+ /**
+ * Convenience method to return the "ongoing" value for a given attribute as
+ * a dummy interval whose end time = the current latest time.
+ *
+ * @param quark
+ * The quark of the attribute
+ * @return An interval representing the current state (but whose end time is
+ * the current one, and probably not the "final" one)
+ * @throws AttributeNotFoundException
+ * If the quark is invalid
+ */
+ public ITmfStateInterval getOngoingInterval(int quark) throws AttributeNotFoundException {
+ fRWLock.readLock().lock();
+ try {
+ checkValidAttribute(quark);
+ return new TmfStateInterval(fOngoingStateStartTimes.get(quark), fLatestTime,
+ quark, fOngoingStateInfo.get(quark));
+ } finally {
+ fRWLock.readLock().unlock();
+ }
+ }
+
+ /**
+ * Try to get the state interval valid for time/quark, if it is present in
+ * this transient state. If it is not (for example, a new value is active
+ * since after the specified timestamp) then null will be returned.
+ *
+ * @param time
+ * The timestamp to look for
+ * @param quark
+ * The quark of the attribute to look for
+ * @return The corresponding TmfStateInterval object if we could find it in
+ * this transient state, or null if we couldn't.
+ */
+ public @Nullable ITmfStateInterval getIntervalAt(long time, int quark) {
+ fRWLock.readLock().lock();
+ try {
+ checkValidAttribute(quark);
+ if (!isActive() || time < fOngoingStateStartTimes.get(quark)) {
+ return null;
+ }
+ return new TmfStateInterval(fOngoingStateStartTimes.get(quark),
+ fLatestTime, quark, fOngoingStateInfo.get(quark));
+ } catch (AttributeNotFoundException e) {
+ return null;
+ } finally {
+ fRWLock.readLock().unlock();
+ }
+ }
+
+ private void checkValidAttribute(int quark) throws AttributeNotFoundException {
+ if (quark > fOngoingStateInfo.size() - 1 || quark < 0) {
+ throw new AttributeNotFoundException(fBackend.getSSID() + " Quark:" + quark); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * More advanced version of {@link #changeOngoingStateValue}. Replaces the
+ * complete ongoingStateInfo in one go, and updates the
+ * ongoingStateStartTimes and #stateValuesTypes accordingly. BE VERY CAREFUL
+ * WITH THIS!
+ *
+ * @param newStateIntervals
+ * The List of intervals that will represent the new
+ * "ongoing state". Their end times don't matter, we will only
+ * check their value and start times.
+ */
+ public void replaceOngoingState(List<ITmfStateInterval> newStateIntervals) {
+ final int size = newStateIntervals.size();
+
+ fRWLock.writeLock().lock();
+ try {
+ fOngoingStateInfo = new ArrayList<>(size);
+ fOngoingStateStartTimes = new ArrayList<>(size);
+ fStateValueTypes = new ArrayList<>(size);
+
+ for (ITmfStateInterval interval : newStateIntervals) {
+ fOngoingStateInfo.add(interval.getStateValue());
+ fOngoingStateStartTimes.add(interval.getStartTime());
+ fStateValueTypes.add(interval.getStateValue().getType());
+ }
+ } finally {
+ fRWLock.writeLock().unlock();
+ }
+ }
+
+ /**
+ * Add an "empty line" to both "ongoing..." vectors. This is needed so the
+ * Ongoing... tables can stay in sync with the number of attributes in the
+ * attribute tree, namely when we add sub-path attributes.
+ */
+ public void addEmptyEntry() {
+ fRWLock.writeLock().lock();
+ try {
+ /*
+ * Since this is a new attribute, we suppose it was in the
+ * "null state" since the beginning (so we can have intervals
+ * covering for all timestamps). A null interval will then get added
+ * at the first state change.
+ */
+ fOngoingStateInfo.add(TmfStateValue.nullValue());
+ fStateValueTypes.add(Type.NULL);
+
+ fOngoingStateStartTimes.add(fBackend.getStartTime());
+ } finally {
+ fRWLock.writeLock().unlock();
+ }
+ }
+
+ /**
+ * Process a state change to be inserted in the history.
+ *
+ * @param eventTime
+ * The timestamp associated with this state change
+ * @param value
+ * The new StateValue associated to this attribute
+ * @param quark
+ * The quark of the attribute that is being modified
+ * @throws TimeRangeException
+ * If 'eventTime' is invalid
+ * @throws AttributeNotFoundException
+ * IF 'quark' does not represent an existing attribute
+ * @throws StateValueTypeException
+ * If the state value to be inserted is of a different type of
+ * what was inserted so far for this attribute.
+ */
+ public void processStateChange(long eventTime, ITmfStateValue value, int quark)
+ throws TimeRangeException, AttributeNotFoundException, StateValueTypeException {
+ if (!this.fIsActive) {
+ return;
+ }
+
+ fRWLock.writeLock().lock();
+ try {
+ Type expectedSvType = fStateValueTypes.get(quark);
+ checkValidAttribute(quark);
+
+ /*
+ * Make sure the state value type we're inserting is the same as the
+ * one registered for this attribute.
+ */
+ if (expectedSvType == Type.NULL) {
+ /*
+ * The value hasn't been used yet, set it to the value we're
+ * currently inserting (which might be null/-1 again).
+ */
+ fStateValueTypes.set(quark, value.getType());
+ } else if ((value.getType() != Type.NULL) && (value.getType() != expectedSvType)) {
+ /*
+ * We authorize inserting null values in any type of attribute,
+ * but for every other types, it needs to match our
+ * expectations!
+ */
+ throw new StateValueTypeException(fBackend.getSSID() + " Quark:" + quark + ", Type:" + value.getType() + ", Expected:" + expectedSvType); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ if (fOngoingStateInfo.get(quark).equals(value)) {
+ /*
+ * This is the case where the new value and the one already
+ * present in the Builder are the same. We do not need to create
+ * an interval, we'll just keep the current one going.
+ */
+ return;
+ }
+
+ if (fOngoingStateStartTimes.get(quark) < eventTime) {
+ /*
+ * These two conditions are necessary to create an interval and
+ * update ongoingStateInfo.
+ */
+ fBackend.insertPastState(fOngoingStateStartTimes.get(quark),
+ eventTime - 1, /* End Time */
+ quark, /* attribute quark */
+ fOngoingStateInfo.get(quark)); /* StateValue */
+
+ fOngoingStateStartTimes.set(quark, eventTime);
+ }
+ fOngoingStateInfo.set(quark, value);
+
+ /* Update the Transient State's lastestTime, if needed */
+ if (fLatestTime < eventTime) {
+ fLatestTime = eventTime;
+ }
+
+ } finally {
+ fRWLock.writeLock().unlock();
+ }
+ }
+
+ /**
+ * Run a "get state at time" query on the Transient State only.
+ *
+ * @param stateInfo
+ * The stateInfo object in which we will put our relevant
+ * information
+ * @param t
+ * The requested timestamp
+ */
+ public void doQuery(List<ITmfStateInterval> stateInfo, long t) {
+ fRWLock.readLock().lock();
+ try {
+ if (!this.fIsActive) {
+ return;
+ }
+ if (stateInfo.size() > fOngoingStateInfo.size()) {
+ throw new IllegalArgumentException();
+ }
+
+ for (int i = 0; i < stateInfo.size(); i++) {
+ /*
+ * We build a dummy interval whose end time =
+ * "current transient state end time" to put in the answer to
+ * the query.
+ */
+ final ITmfStateInterval interval = getIntervalAt(t, i);
+ if (interval != null) {
+ stateInfo.set(i, interval);
+ }
+ }
+ } finally {
+ fRWLock.readLock().unlock();
+ }
+ }
+
+ /**
+ * Close off the Transient State, used for example when we are done reading
+ * a static trace file. All the information currently contained in it will
+ * be converted to intervals and "flushed" to the state history.
+ *
+ * @param endTime
+ * The timestamp to use as end time for the state history (since
+ * it may be different than the timestamp of the last state
+ * change)
+ */
+ public void closeTransientState(long endTime) {
+ if (!this.fIsActive) {
+ return;
+ }
+
+ fRWLock.writeLock().lock();
+ try {
+ for (int i = 0; i < fOngoingStateInfo.size(); i++) {
+ if (fOngoingStateStartTimes.get(i) > endTime) {
+ /*
+ * Handle the cases where trace end > timestamp of last
+ * state change. This can happen when inserting "future"
+ * changes.
+ */
+ continue;
+ }
+ try {
+ fBackend.insertPastState(fOngoingStateStartTimes.get(i),
+ endTime, /* End Time */
+ i, /* attribute quark */
+ fOngoingStateInfo.get(i)); /* StateValue */
+
+ } catch (TimeRangeException e) {
+ /*
+ * This shouldn't happen, since we control where the
+ * interval's start time comes from
+ */
+ throw new IllegalStateException(e);
+ }
+ }
+
+ fOngoingStateInfo.clear();
+ fOngoingStateStartTimes.clear();
+ this.fIsActive = false;
+
+ } finally {
+ fRWLock.writeLock().unlock();
+ }
+ }
+
+ /**
+ * Simply returns if this Transient State is currently being used or not
+ *
+ * @return True if this transient state is active
+ */
+ public boolean isActive() {
+ return this.fIsActive;
+ }
+
+ /**
+ * Mark this transient state as inactive
+ */
+ public void setInactive() {
+ fIsActive = false;
+ }
+
+ /**
+ * Debugging method that prints the contents of the transient state
+ *
+ * @param writer
+ * The writer to which the output should be written
+ */
+ public void debugPrint(PrintWriter writer) {
+ /* Only used for debugging, shouldn't be externalized */
+ writer.println("------------------------------"); //$NON-NLS-1$
+ writer.println("Info stored in the Builder:"); //$NON-NLS-1$
+ if (!this.fIsActive) {
+ writer.println("Builder is currently inactive"); //$NON-NLS-1$
+ writer.println('\n');
+ return;
+ }
+ writer.println("\nAttribute\tStateValue\tValid since time"); //$NON-NLS-1$
+ for (int i = 0; i < fOngoingStateInfo.size(); i++) {
+ writer.format("%d\t\t", i); //$NON-NLS-1$
+ writer.print(fOngoingStateInfo.get(i).toString() + "\t\t"); //$NON-NLS-1$
+ writer.println(fOngoingStateStartTimes.get(i).toString());
+ }
+ writer.println('\n');
+ return;
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2013, 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ * Matthew Khouzam - Modified to use a TreeSet
+ * Patrick Tasse - Add message to exceptions
+ ******************************************************************************/
+
+package org.eclipse.tracecompass.internal.statesystem.core.backend;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.PrintWriter;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
+import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.statesystem.core.interval.TmfStateInterval;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
+
+/**
+ * State history back-end that stores its intervals in RAM only. It cannot be
+ * saved to disk, which means we need to rebuild it every time we re-open a
+ * trace. But it's relatively quick to build, so this shouldn't be a problem in
+ * most cases.
+ *
+ * This should only be used with very small state histories (and/or, very small
+ * traces). Since it's stored in standard Collections, it's limited to 2^31
+ * intervals.
+ *
+ * @author Alexandre Montplaisir
+ */
+public class InMemoryBackend implements IStateHistoryBackend {
+
+ /**
+ * We need to compare the end time and the attribute, because we can have 2
+ * intervals with the same end time (for different attributes). And TreeSet
+ * needs a unique "key" per element.
+ */
+ private static final Comparator<ITmfStateInterval> END_COMPARATOR =
+ new Comparator<ITmfStateInterval>() {
+ @Override
+ public int compare(ITmfStateInterval o1, ITmfStateInterval o2) {
+ final long e1 = o1.getEndTime();
+ final long e2 = o2.getEndTime();
+ final int a1 = o1.getAttribute();
+ final int a2 = o2.getAttribute();
+ if (e1 < e2) {
+ return -1;
+ } else if (e1 > e2) {
+ return 1;
+ } else if (a1 < a2) {
+ return -1;
+ } else if (a1 > a2) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ };
+
+ private final @NonNull String ssid;
+ private final TreeSet<ITmfStateInterval> intervals;
+ private final long startTime;
+
+ private volatile long latestTime;
+
+ /**
+ * Constructor
+ *
+ * @param ssid
+ * The state system's ID
+ * @param startTime
+ * The start time of this interval store
+ */
+ public InMemoryBackend(@NonNull String ssid, long startTime) {
+ this.ssid = ssid;
+ this.startTime = startTime;
+ this.latestTime = startTime;
+ this.intervals = new TreeSet<>(END_COMPARATOR);
+ }
+
+ @Override
+ public String getSSID() {
+ return ssid;
+ }
+
+ @Override
+ public long getStartTime() {
+ return startTime;
+ }
+
+ @Override
+ public long getEndTime() {
+ return latestTime;
+ }
+
+ @Override
+ public void insertPastState(long stateStartTime, long stateEndTime,
+ int quark, ITmfStateValue value) throws TimeRangeException {
+ /* Make sure the passed start/end times make sense */
+ if (stateStartTime > stateEndTime || stateStartTime < startTime) {
+ throw new TimeRangeException(ssid + " Interval Start:" + stateStartTime + ", Interval End:" + stateEndTime + ", Backend Start:" + startTime); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ ITmfStateInterval interval = new TmfStateInterval(stateStartTime, stateEndTime, quark, value);
+
+ /* Add the interval into the tree */
+ synchronized (intervals) {
+ intervals.add(interval);
+ }
+
+ /* Update the "latest seen time" */
+ if (stateEndTime > latestTime) {
+ latestTime = stateEndTime;
+ }
+ }
+
+ @Override
+ public void doQuery(List<ITmfStateInterval> currentStateInfo, long t)
+ throws TimeRangeException {
+ if (!checkValidTime(t)) {
+ throw new TimeRangeException(ssid + " Time:" + t + ", Start:" + startTime + ", End:" + latestTime); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ /*
+ * The intervals are sorted by end time, so we can binary search to get
+ * the first possible interval, then only compare their start times.
+ */
+ synchronized (intervals) {
+ Iterator<ITmfStateInterval> iter = serachforEndTime(intervals, t);
+ for (int modCount = 0; iter.hasNext() && modCount < currentStateInfo.size();) {
+ ITmfStateInterval entry = iter.next();
+ final long entryStartTime = entry.getStartTime();
+ if (entryStartTime <= t) {
+ /* Add this interval to the returned values */
+ currentStateInfo.set(entry.getAttribute(), entry);
+ modCount++;
+ }
+ }
+ }
+ }
+
+ @Override
+ public ITmfStateInterval doSingularQuery(long t, int attributeQuark)
+ throws TimeRangeException, AttributeNotFoundException {
+ if (!checkValidTime(t)) {
+ throw new TimeRangeException(ssid + " Time:" + t + ", Start:" + startTime + ", End:" + latestTime); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ /*
+ * The intervals are sorted by end time, so we can binary search to get
+ * the first possible interval, then only compare their start times.
+ */
+ synchronized (intervals) {
+ Iterator<ITmfStateInterval> iter = serachforEndTime(intervals, t);
+ while (iter.hasNext()) {
+ ITmfStateInterval entry = iter.next();
+ final boolean attributeMatches = (entry.getAttribute() == attributeQuark);
+ final long entryStartTime = entry.getStartTime();
+ if (attributeMatches) {
+ if (entryStartTime <= t) {
+ /* This is the droid we are looking for */
+ return entry;
+ }
+ }
+ }
+ }
+ throw new AttributeNotFoundException(ssid + " Quark:" + attributeQuark); //$NON-NLS-1$
+ }
+
+ private boolean checkValidTime(long t) {
+ if (t >= startTime && t <= latestTime) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void finishedBuilding(long endTime) throws TimeRangeException {
+ /* Nothing to do */
+ }
+
+ @Override
+ public FileInputStream supplyAttributeTreeReader() {
+ /* Saving to disk not supported */
+ return null;
+ }
+
+ @Override
+ public File supplyAttributeTreeWriterFile() {
+ /* Saving to disk not supported */
+ return null;
+ }
+
+ @Override
+ public long supplyAttributeTreeWriterFilePosition() {
+ /* Saving to disk not supported */
+ return -1;
+ }
+
+ @Override
+ public void removeFiles() {
+ /* Nothing to do */
+ }
+
+ @Override
+ public void dispose() {
+ /* Nothing to do */
+ }
+
+ @Override
+ public void debugPrint(PrintWriter writer) {
+ synchronized (intervals) {
+ writer.println(intervals.toString());
+ }
+ }
+
+ private static Iterator<ITmfStateInterval> serachforEndTime(TreeSet<ITmfStateInterval> tree, long time) {
+ ITmfStateInterval dummyInterval = new TmfStateInterval(-1, time, -1, null);
+ ITmfStateInterval myInterval = tree.lower(dummyInterval);
+ if (myInterval == null) {
+ return tree.iterator();
+ }
+ final SortedSet<ITmfStateInterval> tailSet = tree.tailSet(myInterval);
+ Iterator<ITmfStateInterval> retVal = tailSet.iterator();
+ retVal.next();
+ return retVal;
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2013, 2014 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.statesystem.core.backend;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.PrintWriter;
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
+
+/**
+ * An implement of a state history back-end to simply discards *all* the
+ * intervals it receives. Obviously, no queries can be done on it. It is useful
+ * for using with a StateSystem on which you will only want to do "ongoing"
+ * requests.
+ *
+ * @author Alexandre Montplaisir
+ */
+public class NullBackend implements IStateHistoryBackend {
+
+ private final @NonNull String ssid;
+
+ /**
+ * Constructor
+ *
+ * @param ssid
+ * The state system's id
+ */
+ public NullBackend(@NonNull String ssid) {
+ this.ssid = ssid;
+ }
+
+ @Override
+ public String getSSID() {
+ return ssid;
+ }
+
+ @Override
+ public long getStartTime() {
+ return 0;
+ }
+
+ @Override
+ public long getEndTime() {
+ return 0;
+ }
+
+ /**
+ * The interval will be discarded when using a null backend.
+ */
+ @Override
+ public void insertPastState(long stateStartTime, long stateEndTime,
+ int quark, ITmfStateValue value) {
+ /* The interval is always discarded. */
+ }
+
+ @Override
+ public void finishedBuilding(long endTime) {
+ /* Nothing to do */
+ }
+
+ @Override
+ public FileInputStream supplyAttributeTreeReader() {
+ return null;
+ }
+
+ @Override
+ public File supplyAttributeTreeWriterFile() {
+ return null;
+ }
+
+ @Override
+ public long supplyAttributeTreeWriterFilePosition() {
+ return -1;
+ }
+
+ @Override
+ public void removeFiles() {
+ /* Nothing to do */
+ }
+
+ @Override
+ public void dispose() {
+ /* Nothing to do */
+ }
+
+ /**
+ * Null back-ends cannot run queries. Nothing will be put in
+ * currentStateInfo.
+ */
+ @Override
+ public void doQuery(List<ITmfStateInterval> currentStateInfo, long t) {
+ /* Cannot do past queries */
+ }
+
+ /**
+ * Null back-ends cannot run queries. 'null' will be returned.
+ *
+ * @return Always returns null.
+ */
+ @Override
+ public ITmfStateInterval doSingularQuery(long t, int attributeQuark) {
+ /* Cannot do past queries */
+ return null;
+ }
+
+ @Override
+ public void debugPrint(PrintWriter writer) {
+ writer.println("Null history backend"); //$NON-NLS-1$
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2010, 2014 Ericsson, École Polytechnique de Montréal, and others
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ * Florian Wininger - Add Extension and Leaf Node
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * A Core node is a first-level node of a History Tree which is not a leaf node.
+ *
+ * It extends HTNode by adding support for child nodes, and also extensions.
+ *
+ * @author Alexandre Montplaisir
+ */
+public final class CoreNode extends HTNode {
+
+ /** Number of bytes in a int */
+ private static final int SIZE_INT = 4;
+
+ /** Number of bytes in a long */
+ private static final int SIZE_LONG = 8;
+
+ /** Nb. of children this node has */
+ private int nbChildren;
+
+ /** Seq. numbers of the children nodes (size = MAX_NB_CHILDREN) */
+ private int[] children;
+
+ /** Start times of each of the children (size = MAX_NB_CHILDREN) */
+ private long[] childStart;
+
+ /** Seq number of this node's extension. -1 if none */
+ private volatile int extension = -1;
+
+ /**
+ * Lock used to gate the accesses to the children arrays. Meant to be a
+ * different lock from the one in {@link HTNode}.
+ */
+ private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(false);
+
+ /**
+ * Initial constructor. Use this to initialize a new EMPTY node.
+ *
+ * @param config
+ * Configuration of the History Tree
+ * @param seqNumber
+ * The (unique) sequence number assigned to this particular node
+ * @param parentSeqNumber
+ * The sequence number of this node's parent node
+ * @param start
+ * The earliest timestamp stored in this node
+ */
+ public CoreNode(HTConfig config, int seqNumber, int parentSeqNumber,
+ long start) {
+ super(config, seqNumber, parentSeqNumber, start);
+ this.nbChildren = 0;
+ int size = config.getMaxChildren();
+
+ /*
+ * We instantiate the two following arrays at full size right away,
+ * since we want to reserve that space in the node's header.
+ * "this.nbChildren" will tell us how many relevant entries there are in
+ * those tables.
+ */
+ this.children = new int[size];
+ this.childStart = new long[size];
+ }
+
+ @Override
+ protected void readSpecificHeader(ByteBuffer buffer) {
+ int size = getConfig().getMaxChildren();
+
+ extension = buffer.getInt();
+ nbChildren = buffer.getInt();
+
+ children = new int[size];
+ for (int i = 0; i < nbChildren; i++) {
+ children[i] = buffer.getInt();
+ }
+ for (int i = nbChildren; i < size; i++) {
+ buffer.getInt();
+ }
+
+ this.childStart = new long[size];
+ for (int i = 0; i < nbChildren; i++) {
+ childStart[i] = buffer.getLong();
+ }
+ for (int i = nbChildren; i < size; i++) {
+ buffer.getLong();
+ }
+ }
+
+ @Override
+ protected void writeSpecificHeader(ByteBuffer buffer) {
+ int size = getConfig().getMaxChildren();
+
+ buffer.putInt(extension);
+ buffer.putInt(nbChildren);
+
+ /* Write the "children's seq number" array */
+ for (int i = 0; i < nbChildren; i++) {
+ buffer.putInt(children[i]);
+ }
+ for (int i = nbChildren; i < size; i++) {
+ buffer.putInt(0);
+ }
+
+ /* Write the "children's start times" array */
+ for (int i = 0; i < nbChildren; i++) {
+ buffer.putLong(childStart[i]);
+ }
+ for (int i = nbChildren; i < size; i++) {
+ buffer.putLong(0);
+ }
+ }
+
+ /**
+ * Return the number of child nodes this node has.
+ *
+ * @return The number of child nodes
+ */
+ public int getNbChildren() {
+ rwl.readLock().lock();
+ int ret = nbChildren;
+ rwl.readLock().unlock();
+ return ret;
+ }
+
+ /**
+ * Get the child node corresponding to the specified index
+ *
+ * @param index The index of the child to lookup
+ * @return The child node
+ */
+ public int getChild(int index) {
+ rwl.readLock().lock();
+ try {
+ return children[index];
+ } finally {
+ rwl.readLock().unlock();
+ }
+ }
+
+ /**
+ * Get the latest (right-most) child node of this node.
+ *
+ * @return The latest child node
+ */
+ public int getLatestChild() {
+ rwl.readLock().lock();
+ try {
+ return children[nbChildren - 1];
+ } finally {
+ rwl.readLock().unlock();
+ }
+ }
+
+ /**
+ * Get the start time of the specified child node.
+ *
+ * @param index
+ * The index of the child node
+ * @return The start time of the that child node.
+ */
+ public long getChildStart(int index) {
+ rwl.readLock().lock();
+ try {
+ return childStart[index];
+ } finally {
+ rwl.readLock().unlock();
+ }
+ }
+
+ /**
+ * Get the start time of the latest (right-most) child node.
+ *
+ * @return The start time of the latest child
+ */
+ public long getLatestChildStart() {
+ rwl.readLock().lock();
+ try {
+ return childStart[nbChildren - 1];
+ } finally {
+ rwl.readLock().unlock();
+ }
+ }
+
+ /**
+ * Get the sequence number of the extension to this node (if there is one).
+ *
+ * @return The sequence number of the extended node. '-1' is returned if
+ * there is no extension node.
+ */
+ public int getExtensionSequenceNumber() {
+ return extension;
+ }
+
+ /**
+ * Tell this node that it has a new child (Congrats!)
+ *
+ * @param childNode
+ * The SHTNode object of the new child
+ */
+ public void linkNewChild(HTNode childNode) {
+ rwl.writeLock().lock();
+ try {
+ assert (nbChildren < getConfig().getMaxChildren());
+
+ children[nbChildren] = childNode.getSequenceNumber();
+ childStart[nbChildren] = childNode.getNodeStart();
+ nbChildren++;
+
+ } finally {
+ rwl.writeLock().unlock();
+ }
+ }
+
+ @Override
+ public NodeType getNodeType() {
+ return NodeType.CORE;
+ }
+
+ @Override
+ protected int getSpecificHeaderSize() {
+ int maxChildren = getConfig().getMaxChildren();
+ int specificSize =
+ SIZE_INT /* 1x int (extension node) */
+ + SIZE_INT /* 1x int (nbChildren) */
+
+ /* MAX_NB * int ('children' table) */
+ + SIZE_INT * maxChildren
+
+ /* MAX_NB * Timevalue ('childStart' table) */
+ + SIZE_LONG * maxChildren;
+
+ return specificSize;
+ }
+
+ @Override
+ public String toStringSpecific() {
+ /* Only used for debugging, shouldn't be externalized */
+ return "Core Node, " + nbChildren + " children, "; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2014 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;
+
+import java.io.File;
+
+/**
+ * Configuration object for the {@link HistoryTree}.
+ *
+ * @author Alexandre Montplaisir
+ */
+public final class HTConfig {
+
+ private static final int DEFAULT_BLOCKSIZE = 64 * 1024;
+ private static final int DEFAULT_MAXCHILDREN = 50;
+
+ private final File stateFile;
+ private final int blockSize;
+ private final int maxChildren;
+ private final int providerVersion;
+ private final long treeStart;
+
+ /**
+ * Full constructor.
+ *
+ * @param newStateFile
+ * The name of the history file
+ * @param blockSize
+ * The size of each "block" on disk. One node will always fit in
+ * one block.
+ * @param maxChildren
+ * The maximum number of children allowed per core (non-leaf)
+ * node.
+ * @param providerVersion
+ * The version of the state provider. If a file already exists,
+ * and their versions match, the history file will not be rebuilt
+ * uselessly.
+ * @param startTime
+ * The start time of the history
+ */
+ public HTConfig(File newStateFile, int blockSize, int maxChildren,
+ int providerVersion, long startTime) {
+ this.stateFile = newStateFile;
+ this.blockSize = blockSize;
+ this.maxChildren = maxChildren;
+ this.providerVersion = providerVersion;
+ this.treeStart = startTime;
+ }
+
+ /**
+ * Version of the constructor using default values for 'blockSize' and
+ * 'maxChildren'.
+ *
+ * @param newStateFile
+ * The name of the history file
+ * @param providerVersion
+ * The version of the state provider. If a file already exists,
+ * and their versions match, the history file will not be rebuilt
+ * uselessly.
+ * @param startTime
+ * The start time of the history
+ */
+ public HTConfig(File newStateFile, int providerVersion, long startTime) {
+ this(newStateFile, DEFAULT_BLOCKSIZE, DEFAULT_MAXCHILDREN, providerVersion, startTime);
+ }
+
+ // ------------------------------------------------------------------------
+ // Getters
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get the history file.
+ *
+ * @return The history file
+ */
+ public File getStateFile() {
+ return stateFile;
+ }
+
+ /**
+ * Get the configure block size.
+ *
+ * @return The block size
+ */
+ public int getBlockSize() {
+ return blockSize;
+ }
+
+ /**
+ * Get the maximum amount of children allowed.
+ *
+ * @return The maximum amount of children
+ */
+ public int getMaxChildren() {
+ return maxChildren;
+ }
+
+ /**
+ * Get the state provider's version.
+ *
+ * @return The state provider's version
+ */
+ public int getProviderVersion() {
+ return providerVersion;
+ }
+
+ /**
+ * Get the start time of the history
+ *
+ * @return The start time
+ */
+ public long getTreeStart() {
+ return treeStart;
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2015 Ericsson, École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ * Florian Wininger - Allow to change the size of a interval
+ * Patrick Tasse - Add message to exceptions
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
+import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
+
+/**
+ * The interval component, which will be contained in a node of the History
+ * Tree.
+ *
+ * @author Alexandre Montplaisir
+ */
+public final class HTInterval implements ITmfStateInterval, Comparable<HTInterval> {
+
+ private static final String errMsg = "Invalid interval data. Maybe your file is corrupt?"; //$NON-NLS-1$
+
+ /**
+ * Size of an entry in the data section.
+ *
+ * <pre>
+ * 16 2 x Timevalue/long (interval start + end)
+ * + 4 int (key)
+ * + 1 byte (type)
+ * + 4 int (valueOffset)
+ * </pre>
+ */
+ private static final int DATA_ENTRY_SIZE = 25;
+
+ /* 'Byte' equivalent for state values types */
+ private static final byte TYPE_NULL = -1;
+ private static final byte TYPE_INTEGER = 0;
+ private static final byte TYPE_STRING = 1;
+ private static final byte TYPE_LONG = 2;
+ private static final byte TYPE_DOUBLE = 3;
+
+ /* String entry sizes of different state values */
+ private static final int NO_ENTRY_SIZE = 0;
+ private static final int LONG_ENTRY_SIZE = 8;
+ private static final int DOUBLE_ENTRY_SIZE = 8;
+ // sizes of string values depend on the string itself
+
+ private final long start;
+ private final long end;
+ private final int attribute;
+ private final TmfStateValue sv;
+
+ /*
+ * Size of the strings section entry used by this interval (= 0 if not used)
+ */
+ private final int stringsEntrySize;
+
+ /**
+ * Standard constructor
+ *
+ * @param intervalStart
+ * Start time of the interval
+ * @param intervalEnd
+ * End time of the interval
+ * @param attribute
+ * Attribute (quark) to which the state represented by this
+ * interval belongs
+ * @param value
+ * State value represented by this interval
+ * @throws TimeRangeException
+ * If the start time or end time are invalid
+ */
+ public HTInterval(long intervalStart, long intervalEnd, int attribute,
+ TmfStateValue value) throws TimeRangeException {
+ if (intervalStart > intervalEnd) {
+ throw new TimeRangeException("Start:" + intervalStart + ", End:" + intervalEnd); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ this.start = intervalStart;
+ this.end = intervalEnd;
+ this.attribute = attribute;
+ this.sv = value;
+ this.stringsEntrySize = computeStringsEntrySize();
+ }
+
+ /**
+ * "Faster" constructor for inner use only. When we build an interval when
+ * reading it from disk (with {@link #readFrom}), we already know the size
+ * of the strings entry, so there is no need to call
+ * {@link #computeStringsEntrySize()} and do an extra copy.
+ */
+ private HTInterval(long intervalStart, long intervalEnd, int attribute,
+ TmfStateValue value, int size) throws TimeRangeException {
+ if (intervalStart > intervalEnd) {
+ throw new TimeRangeException("Start:" + intervalStart + ", End:" + intervalEnd); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ this.start = intervalStart;
+ this.end = intervalEnd;
+ this.attribute = attribute;
+ this.sv = value;
+ this.stringsEntrySize = size;
+ }
+
+ /**
+ * Reader factory method. Builds the interval using an already-allocated
+ * ByteBuffer, which normally comes from a NIO FileChannel.
+ *
+ * @param buffer
+ * The ByteBuffer from which to read the information
+ * @return The interval object
+ * @throws IOException
+ * If there was an error reading from the buffer
+ */
+ public static final HTInterval readFrom(ByteBuffer buffer) throws IOException {
+ HTInterval interval;
+ long intervalStart, intervalEnd;
+ int attribute;
+ TmfStateValue value;
+ int valueOrOffset, valueSize, res;
+ byte valueType;
+ byte array[];
+
+ /* Read the Data Section entry */
+ intervalStart = buffer.getLong();
+ intervalEnd = buffer.getLong();
+ attribute = buffer.getInt();
+
+ /* Read the 'type' of the value, then react accordingly */
+ valueType = buffer.get();
+ valueOrOffset = buffer.getInt();
+ switch (valueType) {
+
+ case TYPE_NULL:
+ value = TmfStateValue.nullValue();
+ valueSize = NO_ENTRY_SIZE;
+ break;
+
+ case TYPE_INTEGER:
+ /* "ValueOrOffset" is the straight value */
+ value = TmfStateValue.newValueInt(valueOrOffset);
+ valueSize = NO_ENTRY_SIZE;
+ break;
+
+ case TYPE_STRING:
+ /* Go read the matching entry in the Strings section of the block */
+ buffer.mark();
+ buffer.position(valueOrOffset);
+
+ /* the first byte = the size to read */
+ valueSize = buffer.get();
+
+ /*
+ * Careful though, 'valueSize' is the total size of the entry,
+ * including the 'size' byte at the start and end (0'ed) byte at the
+ * end. Here we want 'array' to only contain the real payload of the
+ * value.
+ */
+ array = new byte[valueSize - 2];
+ buffer.get(array);
+ value = TmfStateValue.newValueString(new String(array));
+
+ /* Confirm the 0'ed byte at the end */
+ res = buffer.get();
+ if (res != 0) {
+ throw new IOException(errMsg);
+ }
+
+ /*
+ * Restore the file pointer's position (so we can read the next
+ * interval)
+ */
+ buffer.reset();
+ break;
+
+ case TYPE_LONG:
+ /* Go read the matching entry in the Strings section of the block */
+ buffer.mark();
+ buffer.position(valueOrOffset);
+ value = TmfStateValue.newValueLong(buffer.getLong());
+ valueSize = LONG_ENTRY_SIZE;
+
+ /*
+ * Restore the file pointer's position (so we can read the next
+ * interval)
+ */
+ buffer.reset();
+ break;
+
+ case TYPE_DOUBLE:
+ /* Go read the matching entry in the Strings section of the block */
+ buffer.mark();
+ buffer.position(valueOrOffset);
+ value = TmfStateValue.newValueDouble(buffer.getDouble());
+ valueSize = DOUBLE_ENTRY_SIZE;
+
+ /*
+ * Restore the file pointer's position (so we can read the next
+ * interval)
+ */
+ buffer.reset();
+ break;
+
+ default:
+ /* Unknown data, better to not make anything up... */
+ throw new IOException(errMsg);
+ }
+
+ try {
+ interval = new HTInterval(intervalStart, intervalEnd, attribute, value, valueSize);
+ } catch (TimeRangeException e) {
+ throw new IOException(errMsg);
+ }
+ return interval;
+ }
+
+ /**
+ * Antagonist of the previous constructor, write the Data entry
+ * corresponding to this interval in a ByteBuffer (mapped to a block in the
+ * history-file, hopefully)
+ *
+ * @param buffer
+ * The already-allocated ByteBuffer corresponding to a SHT Node
+ * @param endPosOfStringEntry
+ * The initial (before calling this function for this interval)
+ * position of the Strings Entry for this node. This will change
+ * from one call to the other if we're writing String
+ * StateValues.
+ * @return The size of the Strings Entry that was written, if any.
+ */
+ public int writeInterval(ByteBuffer buffer, int endPosOfStringEntry) {
+ buffer.putLong(start);
+ buffer.putLong(end);
+ buffer.putInt(attribute);
+ buffer.put(getByteFromType(sv.getType()));
+
+ switch (getByteFromType(sv.getType())) {
+
+ case TYPE_NULL:
+ case TYPE_INTEGER:
+ /* We write the 'valueOffset' field as a straight value. */
+ try {
+ buffer.putInt(sv.unboxInt());
+ } catch (StateValueTypeException e) {
+ /*
+ * This should not happen, since the value told us it was of
+ * type Null or Integer (corrupted value?)
+ */
+ e.printStackTrace();
+ }
+ break;
+
+ case TYPE_STRING:
+ byte[] byteArrayToWrite;
+ try {
+ byteArrayToWrite = sv.unboxStr().getBytes();
+ } catch (StateValueTypeException e1) {
+ /* Should not happen, we're in a switch/case for string type */
+ throw new RuntimeException();
+ }
+
+ /* we use the valueOffset as an offset. */
+ buffer.putInt(endPosOfStringEntry - stringsEntrySize);
+ buffer.mark();
+ buffer.position(endPosOfStringEntry - stringsEntrySize);
+
+ /*
+ * write the Strings entry (1st byte = size, then the bytes, then the 0)
+ */
+ buffer.put((byte) stringsEntrySize);
+ buffer.put(byteArrayToWrite);
+ buffer.put((byte) 0);
+ assert (buffer.position() == endPosOfStringEntry);
+ buffer.reset();
+ break;
+
+ case TYPE_LONG:
+ /* we use the valueOffset as an offset. */
+ buffer.putInt(endPosOfStringEntry - stringsEntrySize);
+ buffer.mark();
+ buffer.position(endPosOfStringEntry - stringsEntrySize);
+
+ /*
+ * write the Long in the Strings section
+ */
+ try {
+ buffer.putLong(sv.unboxLong());
+ } catch (StateValueTypeException e) {
+ /*
+ * This should not happen, since the value told us it was of
+ * type Long (corrupted value?)
+ */
+ e.printStackTrace();
+ }
+ assert (buffer.position() == endPosOfStringEntry);
+ buffer.reset();
+ break;
+
+ case TYPE_DOUBLE:
+ /* we use the valueOffset as an offset. */
+ buffer.putInt(endPosOfStringEntry - stringsEntrySize);
+ buffer.mark();
+ buffer.position(endPosOfStringEntry - stringsEntrySize);
+
+ /* Write the Double in the Strings section */
+ try {
+ buffer.putDouble(sv.unboxDouble());
+ } catch (StateValueTypeException e) {
+ /*
+ * This should not happen, since the value told us it was of
+ * type Double (corrupted value?)
+ */
+ e.printStackTrace();
+ }
+ if (buffer.position() != endPosOfStringEntry) {
+ throw new IllegalStateException();
+ }
+ buffer.reset();
+ break;
+
+ default:
+ break;
+ }
+ return stringsEntrySize;
+ }
+
+ @Override
+ public long getStartTime() {
+ return start;
+ }
+
+ @Override
+ public long getEndTime() {
+ return end;
+ }
+
+ @Override
+ public long getViewerEndTime() {
+ return end + 1;
+ }
+
+ @Override
+ public int getAttribute() {
+ return attribute;
+ }
+
+ @Override
+ public ITmfStateValue getStateValue() {
+ return sv;
+ }
+
+ @Override
+ public boolean intersects(long timestamp) {
+ if (start <= timestamp) {
+ if (end >= timestamp) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ int getStringsEntrySize() {
+ return stringsEntrySize;
+ }
+
+ /**
+ * Total serialized size of this interval
+ *
+ * @return The interval size
+ */
+ public int getIntervalSize() {
+ return stringsEntrySize + DATA_ENTRY_SIZE;
+ }
+
+ private int computeStringsEntrySize() {
+ switch(sv.getType()) {
+ case NULL:
+ case INTEGER:
+ /* Those don't use the strings section at all */
+ return NO_ENTRY_SIZE;
+ case LONG:
+ /* The value's bytes are written directly into the strings section */
+ return LONG_ENTRY_SIZE;
+ case DOUBLE:
+ /* The value is also written directly into the strings section */
+ return DOUBLE_ENTRY_SIZE;
+ case STRING:
+ try {
+ /* String's length + 2 (1 byte for size, 1 byte for \0 at the end */
+ return sv.unboxStr().getBytes().length + 2;
+ } catch (StateValueTypeException e) {
+ /* We're inside a switch/case for the string type, can't happen */
+ throw new IllegalStateException(e);
+ }
+ default:
+ /* It's very important that we know how to write the state value in
+ * the file!! */
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Compare the END TIMES of different intervals. This is used to sort the
+ * intervals when we close down a node.
+ */
+ @Override
+ public int compareTo(HTInterval other) {
+ if (this.end < other.end) {
+ return -1;
+ } else if (this.end > other.end) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other instanceof HTInterval &&
+ this.compareTo((HTInterval) other) == 0) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ /* Only for debug, should not be externalized */
+ StringBuilder sb = new StringBuilder();
+ sb.append('[');
+ sb.append(start);
+ sb.append(", "); //$NON-NLS-1$
+ sb.append(end);
+ sb.append(']');
+
+ sb.append(", attribute = "); //$NON-NLS-1$
+ sb.append(attribute);
+
+ sb.append(", value = "); //$NON-NLS-1$
+ sb.append(sv.toString());
+
+ return sb.toString();
+ }
+
+ /**
+ * Here we determine how state values "types" are written in the 8-bit
+ * field that indicates the value type in the file.
+ */
+ private static byte getByteFromType(ITmfStateValue.Type type) {
+ switch(type) {
+ case NULL:
+ return TYPE_NULL;
+ case INTEGER:
+ return TYPE_INTEGER;
+ case STRING:
+ return TYPE_STRING;
+ case LONG:
+ return TYPE_LONG;
+ case DOUBLE:
+ return TYPE_DOUBLE;
+ default:
+ /* Should not happen if the switch is fully covered */
+ throw new IllegalStateException();
+ }
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2010, 2015 Ericsson, École Polytechnique de Montréal, and others
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ * Florian Wininger - Add Extension and Leaf Node
+ * Patrick Tasse - Keep interval list sorted on insert
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
+
+/**
+ * The base class for all the types of nodes that go in the History Tree.
+ *
+ * @author Alexandre Montplaisir
+ */
+public abstract class HTNode {
+
+ // ------------------------------------------------------------------------
+ // Class fields
+ // ------------------------------------------------------------------------
+
+ /**
+ * The type of node
+ */
+ public static enum NodeType {
+ /**
+ * Core node, which is a "front" node, at any level of the tree except
+ * the bottom-most one. It has children, and may have extensions.
+ */
+ CORE,
+ /**
+ * Leaf node, which is a node at the last bottom level of the tree. It
+ * cannot have any children or extensions.
+ */
+ LEAF;
+
+ /**
+ * Determine a node type by reading a serialized byte.
+ *
+ * @param rep
+ * The byte representation of the node type
+ * @return The corresponding NodeType
+ * @throws IOException
+ * If the NodeType is unrecognized
+ */
+ public static NodeType fromByte(byte rep) throws IOException {
+ switch (rep) {
+ case 1:
+ return CORE;
+ case 2:
+ return LEAF;
+ default:
+ throw new IOException();
+ }
+ }
+
+ /**
+ * Get the byte representation of this node type. It can then be read
+ * with {@link #fromByte}.
+ *
+ * @return The byte matching this node type
+ */
+ public byte toByte() {
+ switch (this) {
+ case CORE:
+ return 1;
+ case LEAF:
+ return 2;
+ default:
+ throw new IllegalStateException();
+ }
+ }
+ }
+
+ // ------------------------------------------------------------------------
+ // Attributes
+ // ------------------------------------------------------------------------
+
+ /* Configuration of the History Tree to which belongs this node */
+ private final HTConfig config;
+
+ /* Time range of this node */
+ private final long nodeStart;
+ private long nodeEnd;
+
+ /* Sequence number = position in the node section of the file */
+ private final int sequenceNumber;
+ private int parentSequenceNumber; /* = -1 if this node is the root node */
+
+ /* Where the Strings section begins (from the start of the node */
+ private int stringSectionOffset;
+
+ /* Sum of bytes of all intervals in the node */
+ private int sizeOfIntervalSection;
+
+ /* True if this node was read from disk (meaning its end time is now fixed) */
+ private volatile boolean isOnDisk;
+
+ /* Vector containing all the intervals contained in this node */
+ private final List<HTInterval> intervals;
+
+ /* Lock used to protect the accesses to intervals, nodeEnd and such */
+ private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(false);
+
+ /**
+ * Constructor
+ *
+ * @param config
+ * Configuration of the History Tree
+ * @param seqNumber
+ * The (unique) sequence number assigned to this particular node
+ * @param parentSeqNumber
+ * The sequence number of this node's parent node
+ * @param start
+ * The earliest timestamp stored in this node
+ */
+ protected HTNode(HTConfig config, int seqNumber, int parentSeqNumber, long start) {
+ this.config = config;
+ this.nodeStart = start;
+ this.sequenceNumber = seqNumber;
+ this.parentSequenceNumber = parentSeqNumber;
+
+ this.stringSectionOffset = config.getBlockSize();
+ this.sizeOfIntervalSection = 0;
+ this.isOnDisk = false;
+ this.intervals = new ArrayList<>();
+ }
+
+ /**
+ * Reader factory method. Build a Node object (of the right type) by reading
+ * a block in the file.
+ *
+ * @param config
+ * Configuration of the History Tree
+ * @param fc
+ * FileChannel to the history file, ALREADY SEEKED at the start
+ * of the node.
+ * @return The node object
+ * @throws IOException
+ * If there was an error reading from the file channel
+ */
+ public static final HTNode readNode(HTConfig config, FileChannel fc)
+ throws IOException {
+ HTNode newNode = null;
+ int res, i;
+
+ ByteBuffer buffer = ByteBuffer.allocate(config.getBlockSize());
+ buffer.order(ByteOrder.LITTLE_ENDIAN);
+ buffer.clear();
+ res = fc.read(buffer);
+ assert (res == config.getBlockSize());
+ buffer.flip();
+
+ /* Read the common header part */
+ byte typeByte = buffer.get();
+ NodeType type = NodeType.fromByte(typeByte);
+ long start = buffer.getLong();
+ long end = buffer.getLong();
+ int seqNb = buffer.getInt();
+ int parentSeqNb = buffer.getInt();
+ int intervalCount = buffer.getInt();
+ int stringSectionOffset = buffer.getInt();
+ buffer.get(); // TODO Used to be "isDone", to be removed from the header
+
+ /* Now the rest of the header depends on the node type */
+ switch (type) {
+ case CORE:
+ /* Core nodes */
+ newNode = new CoreNode(config, seqNb, parentSeqNb, start);
+ newNode.readSpecificHeader(buffer);
+ break;
+
+ case LEAF:
+ /* Leaf nodes */
+ newNode = new LeafNode(config, seqNb, parentSeqNb, start);
+ newNode.readSpecificHeader(buffer);
+ break;
+
+ default:
+ /* Unrecognized node type */
+ throw new IOException();
+ }
+
+ /*
+ * At this point, we should be done reading the header and 'buffer'
+ * should only have the intervals left
+ */
+ for (i = 0; i < intervalCount; i++) {
+ newNode.intervals.add(HTInterval.readFrom(buffer));
+ }
+
+ /* Assign the node's other information we have read previously */
+ newNode.nodeEnd = end;
+ newNode.stringSectionOffset = stringSectionOffset;
+ newNode.isOnDisk = true;
+
+ return newNode;
+ }
+
+ /**
+ * Write this node to the given file channel.
+ *
+ * @param fc
+ * The file channel to write to (should be sought to be correct
+ * position)
+ * @throws IOException
+ * If there was an error writing
+ */
+ public final void writeSelf(FileChannel fc) throws IOException {
+ /*
+ * Yes, we are taking the *read* lock here, because we are reading the
+ * information in the node to write it to disk.
+ */
+ rwl.readLock().lock();
+ try {
+ final int blockSize = config.getBlockSize();
+ int curStringsEntryEndPos = blockSize;
+
+ ByteBuffer buffer = ByteBuffer.allocate(blockSize);
+ buffer.order(ByteOrder.LITTLE_ENDIAN);
+ buffer.clear();
+
+ /* Write the common header part */
+ buffer.put(this.getNodeType().toByte());
+ buffer.putLong(nodeStart);
+ buffer.putLong(nodeEnd);
+ buffer.putInt(sequenceNumber);
+ buffer.putInt(parentSequenceNumber);
+ buffer.putInt(intervals.size());
+ buffer.putInt(stringSectionOffset);
+ buffer.put((byte) 1); // TODO Used to be "isDone", to be removed from header
+
+ /* Now call the inner method to write the specific header part */
+ this.writeSpecificHeader(buffer);
+
+ /* Back to us, we write the intervals */
+ for (HTInterval interval : intervals) {
+ int size = interval.writeInterval(buffer, curStringsEntryEndPos);
+ curStringsEntryEndPos -= size;
+ }
+
+ /*
+ * Write padding between the end of the Data section and the start
+ * of the Strings section (needed to fill the node in case there is
+ * no Strings section)
+ */
+ while (buffer.position() < stringSectionOffset) {
+ buffer.put((byte) 0);
+ }
+
+ /*
+ * If the offsets were right, the size of the Strings section should
+ * be == to the expected size
+ */
+ assert (curStringsEntryEndPos == stringSectionOffset);
+
+ /* Finally, write everything in the Buffer to disk */
+
+ // if we don't do this, flip() will lose what's after.
+ buffer.position(blockSize);
+
+ buffer.flip();
+ int res = fc.write(buffer);
+ assert (res == blockSize);
+
+ } finally {
+ rwl.readLock().unlock();
+ }
+ isOnDisk = true;
+ }
+
+ // ------------------------------------------------------------------------
+ // Accessors
+ // ------------------------------------------------------------------------
+
+ /**
+ * Retrieve the history tree configuration used for this node.
+ *
+ * @return The history tree config
+ */
+ protected HTConfig getConfig() {
+ return config;
+ }
+
+ /**
+ * Get the start time of this node.
+ *
+ * @return The start time of this node
+ */
+ public long getNodeStart() {
+ return nodeStart;
+ }
+
+ /**
+ * Get the end time of this node.
+ *
+ * @return The end time of this node
+ */
+ public long getNodeEnd() {
+ if (this.isOnDisk) {
+ return nodeEnd;
+ }
+ return 0;
+ }
+
+ /**
+ * Get the sequence number of this node.
+ *
+ * @return The sequence number of this node
+ */
+ public int getSequenceNumber() {
+ return sequenceNumber;
+ }
+
+ /**
+ * Get the sequence number of this node's parent.
+ *
+ * @return The parent sequence number
+ */
+ public int getParentSequenceNumber() {
+ return parentSequenceNumber;
+ }
+
+ /**
+ * Change this node's parent. Used when we create a new root node for
+ * example.
+ *
+ * @param newParent
+ * The sequence number of the node that is the new parent
+ */
+ public void setParentSequenceNumber(int newParent) {
+ parentSequenceNumber = newParent;
+ }
+
+ /**
+ * Return if this node is "done" (full and written to disk).
+ *
+ * @return If this node is done or not
+ */
+ public boolean isOnDisk() {
+ return isOnDisk;
+ }
+
+ /**
+ * Add an interval to this node
+ *
+ * @param newInterval
+ * Interval to add to this node
+ */
+ public void addInterval(HTInterval newInterval) {
+ rwl.writeLock().lock();
+ try {
+ /* Just in case, should be checked before even calling this function */
+ assert (newInterval.getIntervalSize() <= this.getNodeFreeSpace());
+
+ /* Find the insert position to keep the list sorted */
+ int index = intervals.size();
+ while (index > 0 && newInterval.compareTo(intervals.get(index - 1)) < 0) {
+ index--;
+ }
+
+ intervals.add(index, newInterval);
+ sizeOfIntervalSection += newInterval.getIntervalSize();
+
+ /* Update the in-node offset "pointer" */
+ stringSectionOffset -= (newInterval.getStringsEntrySize());
+ } finally {
+ rwl.writeLock().unlock();
+ }
+ }
+
+ /**
+ * We've received word from the containerTree that newest nodes now exist to
+ * our right. (Puts isDone = true and sets the endtime)
+ *
+ * @param endtime
+ * The nodeEnd time that the node will have
+ */
+ public void closeThisNode(long endtime) {
+ rwl.writeLock().lock();
+ try {
+ assert (endtime >= this.nodeStart);
+
+ if (!intervals.isEmpty()) {
+ /*
+ * Make sure there are no intervals in this node with their
+ * EndTime > the one requested. Only need to check the last one
+ * since they are sorted
+ */
+ assert (endtime >= intervals.get(intervals.size() - 1).getEndTime());
+ }
+
+ this.nodeEnd = endtime;
+ } finally {
+ rwl.writeLock().unlock();
+ }
+ }
+
+ /**
+ * The method to fill up the stateInfo (passed on from the Current State
+ * Tree when it does a query on the SHT). We'll replace the data in that
+ * vector with whatever relevant we can find from this node
+ *
+ * @param stateInfo
+ * The same stateInfo that comes from SHT's doQuery()
+ * @param t
+ * The timestamp for which the query is for. Only return
+ * intervals that intersect t.
+ * @throws TimeRangeException
+ * If 't' is invalid
+ */
+ public void writeInfoFromNode(List<ITmfStateInterval> stateInfo, long t)
+ throws TimeRangeException {
+ /* This is from a state system query, we are "reading" this node */
+ rwl.readLock().lock();
+ try {
+ for (int i = getStartIndexFor(t); i < intervals.size(); i++) {
+ /*
+ * Now we only have to compare the Start times, since we now the
+ * End times necessarily fit.
+ *
+ * Second condition is to ignore new attributes that might have
+ * been created after stateInfo was instantiated (they would be
+ * null anyway).
+ */
+ ITmfStateInterval interval = intervals.get(i);
+ if (interval.getStartTime() <= t &&
+ interval.getAttribute() < stateInfo.size()) {
+ stateInfo.set(interval.getAttribute(), interval);
+ }
+ }
+ } finally {
+ rwl.readLock().unlock();
+ }
+ }
+
+ /**
+ * Get a single Interval from the information in this node If the
+ * key/timestamp pair cannot be found, we return null.
+ *
+ * @param key
+ * The attribute quark to look for
+ * @param t
+ * The timestamp
+ * @return The Interval containing the information we want, or null if it
+ * wasn't found
+ * @throws TimeRangeException
+ * If 't' is invalid
+ */
+ public HTInterval getRelevantInterval(int key, long t) throws TimeRangeException {
+ rwl.readLock().lock();
+ try {
+ for (int i = getStartIndexFor(t); i < intervals.size(); i++) {
+ HTInterval curInterval = intervals.get(i);
+ if (curInterval.getAttribute() == key
+ && curInterval.getStartTime() <= t
+ && curInterval.getEndTime() >= t) {
+ return curInterval;
+ }
+ }
+
+ /* We didn't find the relevant information in this node */
+ return null;
+
+ } finally {
+ rwl.readLock().unlock();
+ }
+ }
+
+ private int getStartIndexFor(long t) throws TimeRangeException {
+ /* Should only be called by methods with the readLock taken */
+
+ if (intervals.isEmpty()) {
+ return 0;
+ }
+ /*
+ * Since the intervals are sorted by end time, we can skip all the ones
+ * at the beginning whose end times are smaller than 't'. Java does
+ * provides a .binarySearch method, but its API is quite weird...
+ */
+ HTInterval dummy = new HTInterval(0, t, 0, TmfStateValue.nullValue());
+ int index = Collections.binarySearch(intervals, dummy);
+
+ if (index < 0) {
+ /*
+ * .binarySearch returns a negative number if the exact value was
+ * not found. Here we just want to know where to start searching, we
+ * don't care if the value is exact or not.
+ */
+ index = -index - 1;
+
+ }
+
+ /* Sometimes binarySearch yields weird stuff... */
+ if (index < 0) {
+ index = 0;
+ }
+ if (index >= intervals.size()) {
+ index = intervals.size() - 1;
+ }
+
+ /*
+ * Another API quirkiness, the returned index is the one of the *last*
+ * element of a series of equal endtimes, which happens sometimes. We
+ * want the *first* element of such a series, to read through them
+ * again.
+ */
+ while (index > 0
+ && intervals.get(index - 1).compareTo(intervals.get(index)) == 0) {
+ index--;
+ }
+
+ return index;
+ }
+
+ /**
+ * <pre>
+ * 1 - byte (type)
+ * 16 - 2x long (start time, end time)
+ * 16 - 4x int (seq number, parent seq number, intervalcount,
+ * strings section pos.)
+ * 1 - byte (done or not)
+ * </pre>
+ */
+ private static final int COMMON_HEADER_SIZE = 34;
+
+ /**
+ * Return the total header size of this node (will depend on the node type).
+ *
+ * @return The total header size
+ */
+ public final int getTotalHeaderSize() {
+ return COMMON_HEADER_SIZE + getSpecificHeaderSize();
+ }
+
+ /**
+ * @return The offset, within the node, where the Data section ends
+ */
+ private int getDataSectionEndOffset() {
+ return this.getTotalHeaderSize() + sizeOfIntervalSection;
+ }
+
+ /**
+ * Returns the free space in the node, which is simply put, the
+ * stringSectionOffset - dataSectionOffset
+ *
+ * @return The amount of free space in the node (in bytes)
+ */
+ public int getNodeFreeSpace() {
+ rwl.readLock().lock();
+ int ret = stringSectionOffset - this.getDataSectionEndOffset();
+ rwl.readLock().unlock();
+
+ return ret;
+ }
+
+ /**
+ * Returns the current space utilization of this node, as a percentage.
+ * (used space / total usable space, which excludes the header)
+ *
+ * @return The percentage (value between 0 and 100) of space utilization in
+ * in this node.
+ */
+ public long getNodeUsagePercent() {
+ rwl.readLock().lock();
+ try {
+ final int blockSize = config.getBlockSize();
+ float freePercent = (float) this.getNodeFreeSpace()
+ / (float) (blockSize - this.getTotalHeaderSize())
+ * 100F;
+ return (long) (100L - freePercent);
+
+ } finally {
+ rwl.readLock().unlock();
+ }
+ }
+
+ /**
+ * @name Debugging functions
+ */
+
+ @SuppressWarnings("nls")
+ @Override
+ public String toString() {
+ /* Only used for debugging, shouldn't be externalized */
+ StringBuffer buf = new StringBuffer("Node #" + sequenceNumber + ", ");
+ buf.append(this.toStringSpecific());
+ buf.append(intervals.size() + " intervals (" + this.getNodeUsagePercent()
+ + "% used), ");
+
+ buf.append("[" + this.nodeStart + " - ");
+ if (this.isOnDisk) {
+ buf = buf.append("" + this.nodeEnd + "]");
+ } else {
+ buf = buf.append("...]");
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Debugging function that prints out the contents of this node
+ *
+ * @param writer
+ * PrintWriter in which we will print the debug output
+ */
+ @SuppressWarnings("nls")
+ public void debugPrintIntervals(PrintWriter writer) {
+ /* Only used for debugging, shouldn't be externalized */
+ writer.println("Node #" + sequenceNumber + ":");
+
+ /* Array of children */
+ if (this.getNodeType() == NodeType.CORE) { /* Only Core Nodes can have children */
+ CoreNode thisNode = (CoreNode) this;
+ writer.print(" " + thisNode.getNbChildren() + " children");
+ if (thisNode.getNbChildren() >= 1) {
+ writer.print(": [ " + thisNode.getChild(0));
+ for (int i = 1; i < thisNode.getNbChildren(); i++) {
+ writer.print(", " + thisNode.getChild(i));
+ }
+ writer.print(']');
+ }
+ writer.print('\n');
+ }
+
+ /* List of intervals in the node */
+ writer.println(" Intervals contained:");
+ for (int i = 0; i < intervals.size(); i++) {
+ writer.println(intervals.get(i).toString());
+ }
+ writer.println('\n');
+ }
+
+ // ------------------------------------------------------------------------
+ // Abstract methods
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get the byte value representing the node type.
+ *
+ * @return The node type
+ */
+ public abstract NodeType getNodeType();
+
+ /**
+ * Return the specific header size of this node. This means the size
+ * occupied by the type-specific section of the header (not counting the
+ * common part).
+ *
+ * @return The specific header size
+ */
+ protected abstract int getSpecificHeaderSize();
+
+ /**
+ * Read the type-specific part of the node header from a byte buffer.
+ *
+ * @param buffer
+ * The byte buffer to read from. It should be already positioned
+ * correctly.
+ */
+ protected abstract void readSpecificHeader(ByteBuffer buffer);
+
+ /**
+ * Write the type-specific part of the header in a byte buffer.
+ *
+ * @param buffer
+ * The buffer to write to. It should already be at the correct
+ * position.
+ */
+ protected abstract void writeSpecificHeader(ByteBuffer buffer);
+
+ /**
+ * Node-type-specific toString method. Used for debugging.
+ *
+ * @return A string representing the node
+ */
+ protected abstract String toStringSpecific();
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2014 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.FileChannel;
+
+import org.eclipse.tracecompass.internal.statesystem.core.Activator;
+
+/**
+ * This class abstracts inputs/outputs of the HistoryTree nodes.
+ *
+ * It contains all the methods and descriptors to handle reading/writing nodes
+ * to the tree-file on disk and all the caching mechanisms.
+ *
+ * This abstraction is mainly for code isolation/clarification purposes. Every
+ * HistoryTree must contain 1 and only 1 HT_IO element.
+ *
+ * @author Alexandre Montplaisir
+ *
+ */
+class HT_IO {
+ /* Configuration of the History Tree */
+ private final HTConfig fConfig;
+
+ /* Fields related to the file I/O */
+ private final FileInputStream fis;
+ private final FileOutputStream fos;
+ private final FileChannel fcIn;
+ private final FileChannel fcOut;
+
+ // TODO test/benchmark optimal cache size
+ private static final int CACHE_SIZE = 256;
+ private final HTNode fNodeCache[] = new HTNode[CACHE_SIZE];
+
+ /**
+ * Standard constructor
+ *
+ * @param config
+ * The configuration object for the StateHistoryTree
+ * @param newFile
+ * Flag indicating that the file must be created from scratch
+ *
+ * @throws IOException
+ * An exception can be thrown when file cannot be accessed
+ */
+ public HT_IO(HTConfig config, boolean newFile) throws IOException {
+ fConfig = config;
+
+ File historyTreeFile = config.getStateFile();
+ if (newFile) {
+ boolean success1 = true;
+ /* Create a new empty History Tree file */
+ if (historyTreeFile.exists()) {
+ success1 = historyTreeFile.delete();
+ }
+ boolean success2 = historyTreeFile.createNewFile();
+ if (!(success1 && success2)) {
+ /* It seems we do not have permission to create the new file */
+ throw new IOException("Cannot create new file at " + //$NON-NLS-1$
+ historyTreeFile.getName());
+ }
+ fis = new FileInputStream(historyTreeFile);
+ fos = new FileOutputStream(historyTreeFile, false);
+ } else {
+ /*
+ * We want to open an existing file, make sure we don't squash the
+ * existing content when opening the fos!
+ */
+ this.fis = new FileInputStream(historyTreeFile);
+ this.fos = new FileOutputStream(historyTreeFile, true);
+ }
+ this.fcIn = fis.getChannel();
+ this.fcOut = fos.getChannel();
+ }
+
+ /**
+ * Read a node from the file on disk.
+ *
+ * @param seqNumber
+ * The sequence number of the node to read.
+ * @return The object representing the node
+ * @throws ClosedChannelException
+ * Usually happens because the file was closed while we were
+ * reading. Instead of using a big reader-writer lock, we'll
+ * just catch this exception.
+ */
+ public synchronized HTNode readNode(int seqNumber) throws ClosedChannelException {
+ /* Do a cache lookup */
+ int offset = seqNumber & (CACHE_SIZE - 1);
+ HTNode readNode = fNodeCache[offset];
+ if (readNode != null && readNode.getSequenceNumber() == seqNumber) {
+ return readNode;
+ }
+
+ /* Lookup on disk */
+ try {
+ seekFCToNodePos(fcIn, seqNumber);
+ readNode = HTNode.readNode(fConfig, fcIn);
+
+ /* Put the node in the cache. */
+ fNodeCache[offset] = readNode;
+ return readNode;
+ } catch (ClosedChannelException e) {
+ throw e;
+ } catch (IOException e) {
+ /* Other types of IOExceptions shouldn't happen at this point though */
+ Activator.getDefault().logError(e.getMessage(), e);
+ return null;
+ }
+ }
+
+ public synchronized void writeNode(HTNode node) {
+ try {
+ /* Insert the node into the cache. */
+ int seqNumber = node.getSequenceNumber();
+ int offset = seqNumber & (CACHE_SIZE - 1);
+ fNodeCache[offset] = node;
+
+ /* Position ourselves at the start of the node and write it */
+ seekFCToNodePos(fcOut, seqNumber);
+ node.writeSelf(fcOut);
+ } catch (IOException e) {
+ /* If we were able to open the file, we should be fine now... */
+ Activator.getDefault().logError(e.getMessage(), e);
+ }
+ }
+
+ public FileChannel getFcOut() {
+ return this.fcOut;
+ }
+
+ public FileInputStream supplyATReader(int nodeOffset) {
+ try {
+ /*
+ * Position ourselves at the start of the Mapping section in the
+ * file (which is right after the Blocks)
+ */
+ seekFCToNodePos(fcIn, nodeOffset);
+ } catch (IOException e) {
+ Activator.getDefault().logError(e.getMessage(), e);
+ }
+ return fis;
+ }
+
+ public synchronized void closeFile() {
+ try {
+ fis.close();
+ fos.close();
+ } catch (IOException e) {
+ Activator.getDefault().logError(e.getMessage(), e);
+ }
+ }
+
+ public synchronized void deleteFile() {
+ closeFile();
+
+ File historyTreeFile = fConfig.getStateFile();
+ if (!historyTreeFile.delete()) {
+ /* We didn't succeed in deleting the file */
+ Activator.getDefault().logError("Failed to delete" + historyTreeFile.getName()); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Seek the given FileChannel to the position corresponding to the node that
+ * has seqNumber
+ *
+ * @param fc
+ * the channel to seek
+ * @param seqNumber
+ * the node sequence number to seek the channel to
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ private void seekFCToNodePos(FileChannel fc, int seqNumber)
+ throws IOException {
+ /*
+ * Cast to (long) is needed to make sure the result is a long too and
+ * doesn't get truncated
+ */
+ fc.position(HistoryTree.TREE_HEADER_SIZE
+ + ((long) seqNumber) * fConfig.getBlockSize());
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2010, 2015 Ericsson, École Polytechnique de Montréal, and others
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ * Florian Wininger - Add Extension and Leaf Node
+ * Patrick Tasse - Add message to exceptions
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.tracecompass.internal.statesystem.core.Activator;
+import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
+import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
+
+/**
+ * Meta-container for the History Tree. This structure contains all the
+ * high-level data relevant to the tree.
+ *
+ * @author Alexandre Montplaisir
+ */
+public class HistoryTree {
+
+ /**
+ * Size of the "tree header" in the tree-file The nodes will use this offset
+ * to know where they should be in the file. This should always be a
+ * multiple of 4K.
+ */
+ public static final int TREE_HEADER_SIZE = 4096;
+
+ private static final int HISTORY_FILE_MAGIC_NUMBER = 0x05FFA900;
+
+ /** File format version. Increment when breaking compatibility. */
+ private static final int FILE_VERSION = 5;
+
+ // ------------------------------------------------------------------------
+ // Tree-specific configuration
+ // ------------------------------------------------------------------------
+
+ /** Container for all the configuration constants */
+ private final HTConfig config;
+
+ /** Reader/writer object */
+ private final HT_IO treeIO;
+
+ // ------------------------------------------------------------------------
+ // Variable Fields (will change throughout the existence of the SHT)
+ // ------------------------------------------------------------------------
+
+ /** Latest timestamp found in the tree (at any given moment) */
+ private long treeEnd;
+
+ /** The total number of nodes that exists in this tree */
+ private int nodeCount;
+
+ /** "Cache" to keep the active nodes in memory */
+ private final List<HTNode> latestBranch;
+
+ // ------------------------------------------------------------------------
+ // Constructors/"Destructors"
+ // ------------------------------------------------------------------------
+
+ /**
+ * Create a new State History from scratch, using a {@link HTConfig} object
+ * for configuration.
+ *
+ * @param conf
+ * The config to use for this History Tree.
+ * @throws IOException
+ * If an error happens trying to open/write to the file
+ * specified in the config
+ */
+ public HistoryTree(HTConfig conf) throws IOException {
+ /*
+ * Simple check to make sure we have enough place in the 0th block for
+ * the tree configuration
+ */
+ if (conf.getBlockSize() < TREE_HEADER_SIZE) {
+ throw new IllegalArgumentException();
+ }
+
+ config = conf;
+ treeEnd = conf.getTreeStart();
+ nodeCount = 0;
+ latestBranch = Collections.synchronizedList(new ArrayList<HTNode>());
+
+ /* Prepare the IO object */
+ treeIO = new HT_IO(config, true);
+
+ /* Add the first node to the tree */
+ LeafNode firstNode = initNewLeafNode(-1, conf.getTreeStart());
+ latestBranch.add(firstNode);
+ }
+
+ /**
+ * "Reader" constructor : instantiate a SHTree from an existing tree file on
+ * disk
+ *
+ * @param existingStateFile
+ * Path/filename of the history-file we are to open
+ * @param expProviderVersion
+ * The expected version of the state provider
+ * @throws IOException
+ * If an error happens reading the file
+ */
+ public HistoryTree(File existingStateFile, int expProviderVersion) throws IOException {
+ /*
+ * Open the file ourselves, get the tree header information we need,
+ * then pass on the descriptor to the TreeIO object.
+ */
+ int rootNodeSeqNb, res;
+ int bs, maxc;
+ long startTime;
+
+ /* Java I/O mumbo jumbo... */
+ if (!existingStateFile.exists()) {
+ throw new IOException("Selected state file does not exist"); //$NON-NLS-1$
+ }
+ if (existingStateFile.length() <= 0) {
+ throw new IOException("Empty target file"); //$NON-NLS-1$
+ }
+
+ try (FileInputStream fis = new FileInputStream(existingStateFile);
+ FileChannel fc = fis.getChannel();) {
+
+ ByteBuffer buffer = ByteBuffer.allocate(TREE_HEADER_SIZE);
+
+ buffer.order(ByteOrder.LITTLE_ENDIAN);
+ buffer.clear();
+ fc.read(buffer);
+ buffer.flip();
+
+ /*
+ * Check the magic number to make sure we're opening the right type
+ * of file
+ */
+ res = buffer.getInt();
+ if (res != HISTORY_FILE_MAGIC_NUMBER) {
+ throw new IOException("Wrong magic number"); //$NON-NLS-1$
+ }
+
+ res = buffer.getInt(); /* File format version number */
+ if (res != FILE_VERSION) {
+ throw new IOException("Mismatching History Tree file format versions"); //$NON-NLS-1$
+ }
+
+ res = buffer.getInt(); /* Event handler's version number */
+ if (res != expProviderVersion &&
+ expProviderVersion != ITmfStateSystemBuilder.IGNORE_PROVIDER_VERSION) {
+ /*
+ * The existing history was built using an event handler that
+ * doesn't match the current one in the framework.
+ *
+ * Information could be all wrong. Instead of keeping an
+ * incorrect history file, a rebuild is done.
+ */
+ throw new IOException("Mismatching event handler versions"); //$NON-NLS-1$
+ }
+
+ bs = buffer.getInt(); /* Block Size */
+ maxc = buffer.getInt(); /* Max nb of children per node */
+
+ this.nodeCount = buffer.getInt();
+ rootNodeSeqNb = buffer.getInt();
+ startTime = buffer.getLong();
+
+ this.config = new HTConfig(existingStateFile, bs, maxc, expProviderVersion, startTime);
+ }
+
+ /*
+ * FIXME We close fis here and the TreeIO will then reopen the same
+ * file, not extremely elegant. But how to pass the information here to
+ * the SHT otherwise?
+ */
+ this.treeIO = new HT_IO(config, false);
+
+ this.latestBranch = buildLatestBranch(rootNodeSeqNb);
+ this.treeEnd = getRootNode().getNodeEnd();
+
+ /*
+ * Make sure the history start time we read previously is consistent
+ * with was is actually in the root node.
+ */
+ if (startTime != getRootNode().getNodeStart()) {
+ throw new IOException("Inconsistent start times in the" + //$NON-NLS-1$
+ "history file, it might be corrupted."); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Rebuild the latestBranch "cache" object by reading the nodes from disk
+ * (When we are opening an existing file on disk and want to append to it,
+ * for example).
+ *
+ * @param rootNodeSeqNb
+ * The sequence number of the root node, so we know where to
+ * start
+ * @throws ClosedChannelException
+ */
+ private List<HTNode> buildLatestBranch(int rootNodeSeqNb) throws ClosedChannelException {
+ List<HTNode> list = new ArrayList<>();
+
+ HTNode nextChildNode = treeIO.readNode(rootNodeSeqNb);
+ list.add(nextChildNode);
+
+ /* Follow the last branch up to the leaf */
+ while (nextChildNode.getNodeType() == HTNode.NodeType.CORE) {
+ nextChildNode = treeIO.readNode(((CoreNode) nextChildNode).getLatestChild());
+ list.add(nextChildNode);
+ }
+ return Collections.synchronizedList(list);
+ }
+
+ /**
+ * "Save" the tree to disk. This method will cause the treeIO object to
+ * commit all nodes to disk and then return the RandomAccessFile descriptor
+ * so the Tree object can save its configuration into the header of the
+ * file.
+ *
+ * @param requestedEndTime
+ * The greatest timestamp present in the history tree
+ */
+ public void closeTree(long requestedEndTime) {
+ /* This is an important operation, queries can wait */
+ synchronized (latestBranch) {
+ /*
+ * Work-around the "empty branches" that get created when the root
+ * node becomes full. Overwrite the tree's end time with the
+ * original wanted end-time, to ensure no queries are sent into
+ * those empty nodes.
+ *
+ * This won't be needed once extended nodes are implemented.
+ */
+ this.treeEnd = requestedEndTime;
+
+ /* Close off the latest branch of the tree */
+ for (int i = 0; i < latestBranch.size(); i++) {
+ latestBranch.get(i).closeThisNode(treeEnd);
+ treeIO.writeNode(latestBranch.get(i));
+ }
+
+ try (FileChannel fc = treeIO.getFcOut();) {
+ ByteBuffer buffer = ByteBuffer.allocate(TREE_HEADER_SIZE);
+ buffer.order(ByteOrder.LITTLE_ENDIAN);
+ buffer.clear();
+
+ /* Save the config of the tree to the header of the file */
+ fc.position(0);
+
+ buffer.putInt(HISTORY_FILE_MAGIC_NUMBER);
+
+ buffer.putInt(FILE_VERSION);
+ buffer.putInt(config.getProviderVersion());
+
+ buffer.putInt(config.getBlockSize());
+ buffer.putInt(config.getMaxChildren());
+
+ buffer.putInt(nodeCount);
+
+ /* root node seq. nb */
+ buffer.putInt(latestBranch.get(0).getSequenceNumber());
+
+ /* start time of this history */
+ buffer.putLong(latestBranch.get(0).getNodeStart());
+
+ buffer.flip();
+ int res = fc.write(buffer);
+ assert (res <= TREE_HEADER_SIZE);
+ /* done writing the file header */
+
+ } catch (IOException e) {
+ /*
+ * If we were able to write so far, there should not be any
+ * problem at this point...
+ */
+ throw new RuntimeException("State system write error"); //$NON-NLS-1$
+ }
+ }
+ }
+
+ // ------------------------------------------------------------------------
+ // Accessors
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get the start time of this tree.
+ *
+ * @return The start time
+ */
+ public long getTreeStart() {
+ return config.getTreeStart();
+ }
+
+ /**
+ * Get the current end time of this tree.
+ *
+ * @return The end time
+ */
+ public long getTreeEnd() {
+ return treeEnd;
+ }
+
+ /**
+ * Get the number of nodes in this tree.
+ *
+ * @return The number of nodes
+ */
+ public int getNodeCount() {
+ return nodeCount;
+ }
+
+ /**
+ * Get the current root node of this tree
+ *
+ * @return The root node
+ */
+ public HTNode getRootNode() {
+ return latestBranch.get(0);
+ }
+
+ // ------------------------------------------------------------------------
+ // HT_IO interface
+ // ------------------------------------------------------------------------
+
+ /**
+ * Return the FileInputStream reader with which we will read an attribute
+ * tree (it will be sought to the correct position).
+ *
+ * @return The FileInputStream indicating the file and position from which
+ * the attribute tree can be read.
+ */
+ public FileInputStream supplyATReader() {
+ return treeIO.supplyATReader(getNodeCount());
+ }
+
+ /**
+ * Return the file to which we will write the attribute tree.
+ *
+ * @return The file to which we will write the attribute tree
+ */
+ public File supplyATWriterFile() {
+ return config.getStateFile();
+ }
+
+ /**
+ * Return the position in the file (given by {@link #supplyATWriterFile})
+ * where to start writing the attribute tree.
+ *
+ * @return The position in the file where to start writing
+ */
+ public long supplyATWriterFilePos() {
+ return HistoryTree.TREE_HEADER_SIZE
+ + ((long) getNodeCount() * config.getBlockSize());
+ }
+
+ /**
+ * Read a node from the tree.
+ *
+ * @param seqNumber
+ * The sequence number of the node to read
+ * @return The node
+ * @throws ClosedChannelException
+ * If the tree IO is unavailable
+ */
+ public HTNode readNode(int seqNumber) throws ClosedChannelException {
+ /* Try to read the node from memory */
+ synchronized (latestBranch) {
+ for (HTNode node : latestBranch) {
+ if (node.getSequenceNumber() == seqNumber) {
+ return node;
+ }
+ }
+ }
+
+ /* Read the node from disk */
+ return treeIO.readNode(seqNumber);
+ }
+
+ /**
+ * Write a node object to the history file.
+ *
+ * @param node
+ * The node to write to disk
+ */
+ public void writeNode(HTNode node) {
+ treeIO.writeNode(node);
+ }
+
+ /**
+ * Close the history file.
+ */
+ public void closeFile() {
+ treeIO.closeFile();
+ }
+
+ /**
+ * Delete the history file.
+ */
+ public void deleteFile() {
+ treeIO.deleteFile();
+ }
+
+ // ------------------------------------------------------------------------
+ // Operations
+ // ------------------------------------------------------------------------
+
+ /**
+ * Insert an interval in the tree.
+ *
+ * @param interval
+ * The interval to be inserted
+ * @throws TimeRangeException
+ * If the start of end time of the interval are invalid
+ */
+ public void insertInterval(HTInterval interval) throws TimeRangeException {
+ if (interval.getStartTime() < config.getTreeStart()) {
+ throw new TimeRangeException("Interval Start:" + interval.getStartTime() + ", Config Start:" + config.getTreeStart()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ tryInsertAtNode(interval, latestBranch.size() - 1);
+ }
+
+ /**
+ * Inner method to find in which node we should add the interval.
+ *
+ * @param interval
+ * The interval to add to the tree
+ * @param indexOfNode
+ * The index *in the latestBranch* where we are trying the
+ * insertion
+ */
+ private void tryInsertAtNode(HTInterval interval, int indexOfNode) {
+ HTNode targetNode = latestBranch.get(indexOfNode);
+
+ /* Verify if there is enough room in this node to store this interval */
+ if (interval.getIntervalSize() > targetNode.getNodeFreeSpace()) {
+ /* Nope, not enough room. Insert in a new sibling instead. */
+ addSiblingNode(indexOfNode);
+ tryInsertAtNode(interval, latestBranch.size() - 1);
+ return;
+ }
+
+ /* Make sure the interval time range fits this node */
+ if (interval.getStartTime() < targetNode.getNodeStart()) {
+ /*
+ * No, this interval starts before the startTime of this node. We
+ * need to check recursively in parents if it can fit.
+ */
+ assert (indexOfNode >= 1);
+ tryInsertAtNode(interval, indexOfNode - 1);
+ return;
+ }
+
+ /*
+ * Ok, there is room, and the interval fits in this time slot. Let's add
+ * it.
+ */
+ targetNode.addInterval(interval);
+
+ /* Update treeEnd if needed */
+ if (interval.getEndTime() > this.treeEnd) {
+ this.treeEnd = interval.getEndTime();
+ }
+ }
+
+ /**
+ * Method to add a sibling to any node in the latest branch. This will add
+ * children back down to the leaf level, if needed.
+ *
+ * @param indexOfNode
+ * The index in latestBranch where we start adding
+ */
+ private void addSiblingNode(int indexOfNode) {
+ synchronized (latestBranch) {
+ final long splitTime = treeEnd;
+
+ if (indexOfNode >= latestBranch.size()) {
+ /*
+ * We need to make sure (indexOfNode - 1) doesn't get the last
+ * node in the branch, because that one is a Leaf Node.
+ */
+ throw new IllegalStateException();
+ }
+
+ /* Check if we need to add a new root node */
+ if (indexOfNode == 0) {
+ addNewRootNode();
+ return;
+ }
+
+ /* Check if we can indeed add a child to the target parent */
+ if (((CoreNode) latestBranch.get(indexOfNode - 1)).getNbChildren() == config.getMaxChildren()) {
+ /* If not, add a branch starting one level higher instead */
+ addSiblingNode(indexOfNode - 1);
+ return;
+ }
+
+ /* Split off the new branch from the old one */
+ for (int i = indexOfNode; i < latestBranch.size(); i++) {
+ latestBranch.get(i).closeThisNode(splitTime);
+ treeIO.writeNode(latestBranch.get(i));
+
+ CoreNode prevNode = (CoreNode) latestBranch.get(i - 1);
+ HTNode newNode;
+
+ switch (latestBranch.get(i).getNodeType()) {
+ case CORE:
+ newNode = initNewCoreNode(prevNode.getSequenceNumber(), splitTime + 1);
+ break;
+ case LEAF:
+ newNode = initNewLeafNode(prevNode.getSequenceNumber(), splitTime + 1);
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+
+ prevNode.linkNewChild(newNode);
+ latestBranch.set(i, newNode);
+ }
+ }
+ }
+
+ /**
+ * Similar to the previous method, except here we rebuild a completely new
+ * latestBranch
+ */
+ private void addNewRootNode() {
+ final long splitTime = this.treeEnd;
+
+ HTNode oldRootNode = latestBranch.get(0);
+ CoreNode newRootNode = initNewCoreNode(-1, config.getTreeStart());
+
+ /* Tell the old root node that it isn't root anymore */
+ oldRootNode.setParentSequenceNumber(newRootNode.getSequenceNumber());
+
+ /* Close off the whole current latestBranch */
+
+ for (int i = 0; i < latestBranch.size(); i++) {
+ latestBranch.get(i).closeThisNode(splitTime);
+ treeIO.writeNode(latestBranch.get(i));
+ }
+
+ /* Link the new root to its first child (the previous root node) */
+ newRootNode.linkNewChild(oldRootNode);
+
+ /* Rebuild a new latestBranch */
+ int depth = latestBranch.size();
+ latestBranch.clear();
+ latestBranch.add(newRootNode);
+
+ // Create new coreNode
+ for (int i = 1; i < depth + 1; i++) {
+ CoreNode prevNode = (CoreNode) latestBranch.get(i - 1);
+ CoreNode newNode = initNewCoreNode(prevNode.getParentSequenceNumber(),
+ splitTime + 1);
+ prevNode.linkNewChild(newNode);
+ latestBranch.add(newNode);
+ }
+
+ // Create the new leafNode
+ CoreNode prevNode = (CoreNode) latestBranch.get(depth);
+ LeafNode newNode = initNewLeafNode(prevNode.getParentSequenceNumber(), splitTime + 1);
+ prevNode.linkNewChild(newNode);
+ latestBranch.add(newNode);
+ }
+
+ /**
+ * Add a new empty core node to the tree.
+ *
+ * @param parentSeqNumber
+ * Sequence number of this node's parent
+ * @param startTime
+ * Start time of the new node
+ * @return The newly created node
+ */
+ private CoreNode initNewCoreNode(int parentSeqNumber, long startTime) {
+ CoreNode newNode = new CoreNode(config, this.nodeCount, parentSeqNumber,
+ startTime);
+ this.nodeCount++;
+
+ /* Update the treeEnd if needed */
+ if (startTime >= this.treeEnd) {
+ this.treeEnd = startTime + 1;
+ }
+ return newNode;
+ }
+
+ /**
+ * Add a new empty leaf node to the tree.
+ *
+ * @param parentSeqNumber
+ * Sequence number of this node's parent
+ * @param startTime
+ * Start time of the new node
+ * @return The newly created node
+ */
+ private LeafNode initNewLeafNode(int parentSeqNumber, long startTime) {
+ LeafNode newNode = new LeafNode(config, this.nodeCount, parentSeqNumber,
+ startTime);
+ this.nodeCount++;
+
+ /* Update the treeEnd if needed */
+ if (startTime >= this.treeEnd) {
+ this.treeEnd = startTime + 1;
+ }
+ return newNode;
+ }
+
+ /**
+ * Inner method to select the next child of the current node intersecting
+ * the given timestamp. Useful for moving down the tree following one
+ * branch.
+ *
+ * @param currentNode
+ * The node on which the request is made
+ * @param t
+ * The timestamp to choose which child is the next one
+ * @return The child node intersecting t
+ * @throws ClosedChannelException
+ * If the file channel was closed while we were reading the tree
+ */
+ public HTNode selectNextChild(CoreNode currentNode, long t) throws ClosedChannelException {
+ assert (currentNode.getNbChildren() > 0);
+ int potentialNextSeqNb = currentNode.getSequenceNumber();
+
+ for (int i = 0; i < currentNode.getNbChildren(); i++) {
+ if (t >= currentNode.getChildStart(i)) {
+ potentialNextSeqNb = currentNode.getChild(i);
+ } else {
+ break;
+ }
+ }
+
+ /*
+ * Once we exit this loop, we should have found a children to follow. If
+ * we didn't, there's a problem.
+ */
+ assert (potentialNextSeqNb != currentNode.getSequenceNumber());
+
+ /*
+ * Since this code path is quite performance-critical, avoid iterating
+ * through the whole latestBranch array if we know for sure the next
+ * node has to be on disk
+ */
+ if (currentNode.isOnDisk()) {
+ return treeIO.readNode(potentialNextSeqNb);
+ }
+ return readNode(potentialNextSeqNb);
+ }
+
+ /**
+ * Get the current size of the history file.
+ *
+ * @return The history file size
+ */
+ public long getFileSize() {
+ return config.getStateFile().length();
+ }
+
+ // ------------------------------------------------------------------------
+ // Test/debugging methods
+ // ------------------------------------------------------------------------
+
+ /**
+ * Debugging method to make sure all intervals contained in the given node
+ * have valid start and end times.
+ *
+ * @param zenode
+ * The node to check
+ * @return True if everything is fine, false if there is at least one
+ * invalid timestamp (end time < start time, time outside of the
+ * range of the node, etc.)
+ */
+ @SuppressWarnings("nls")
+ public boolean checkNodeIntegrity(HTNode zenode) {
+ /* Only used for debugging, shouldn't be externalized */
+ HTNode otherNode;
+ CoreNode node;
+ StringBuffer buf = new StringBuffer();
+ boolean ret = true;
+
+ // FIXME /* Only testing Core Nodes for now */
+ if (!(zenode instanceof CoreNode)) {
+ return true;
+ }
+
+ node = (CoreNode) zenode;
+
+ try {
+ /*
+ * Test that this node's start and end times match the start of the
+ * first child and the end of the last child, respectively
+ */
+ if (node.getNbChildren() > 0) {
+ otherNode = treeIO.readNode(node.getChild(0));
+ if (node.getNodeStart() != otherNode.getNodeStart()) {
+ buf.append("Start time of node (" + node.getNodeStart() + ") "
+ + "does not match start time of first child " + "("
+ + otherNode.getNodeStart() + "), " + "node #"
+ + otherNode.getSequenceNumber() + ")\n");
+ ret = false;
+ }
+ if (node.isOnDisk()) {
+ otherNode = treeIO.readNode(node.getLatestChild());
+ if (node.getNodeEnd() != otherNode.getNodeEnd()) {
+ buf.append("End time of node (" + node.getNodeEnd()
+ + ") does not match end time of last child ("
+ + otherNode.getNodeEnd() + ", node #"
+ + otherNode.getSequenceNumber() + ")\n");
+ ret = false;
+ }
+ }
+ }
+
+ /*
+ * Test that the childStartTimes[] array matches the real nodes'
+ * start times
+ */
+ for (int i = 0; i < node.getNbChildren(); i++) {
+ otherNode = treeIO.readNode(node.getChild(i));
+ if (otherNode.getNodeStart() != node.getChildStart(i)) {
+ buf.append(" Expected start time of child node #"
+ + node.getChild(i) + ": " + node.getChildStart(i)
+ + "\n" + " Actual start time of node #"
+ + otherNode.getSequenceNumber() + ": "
+ + otherNode.getNodeStart() + "\n");
+ ret = false;
+ }
+ }
+
+ } catch (ClosedChannelException e) {
+ e.printStackTrace();
+ }
+
+ if (!ret) {
+ System.out.println("");
+ System.out.println("SHT: Integrity check failed for node #"
+ + node.getSequenceNumber() + ":");
+ System.out.println(buf.toString());
+ }
+ return ret;
+ }
+
+ /**
+ * Check the integrity of all the nodes in the tree. Calls
+ * {@link #checkNodeIntegrity} for every node in the tree.
+ */
+ public void checkIntegrity() {
+ try {
+ for (int i = 0; i < nodeCount; i++) {
+ checkNodeIntegrity(treeIO.readNode(i));
+ }
+ } catch (ClosedChannelException e) {
+ }
+ }
+
+ /* Only used for debugging, shouldn't be externalized */
+ @SuppressWarnings("nls")
+ @Override
+ public String toString() {
+ return "Information on the current tree:\n\n" + "Blocksize: "
+ + config.getBlockSize() + "\n" + "Max nb. of children per node: "
+ + config.getMaxChildren() + "\n" + "Number of nodes: " + nodeCount
+ + "\n" + "Depth of the tree: " + latestBranch.size() + "\n"
+ + "Size of the treefile: " + this.getFileSize() + "\n"
+ + "Root node has sequence number: "
+ + latestBranch.get(0).getSequenceNumber() + "\n"
+ + "'Latest leaf' has sequence number: "
+ + latestBranch.get(latestBranch.size() - 1).getSequenceNumber();
+ }
+
+ /**
+ * Start at currentNode and print the contents of all its children, in
+ * pre-order. Give the root node in parameter to visit the whole tree, and
+ * have a nice overview.
+ */
+ /* Only used for debugging, shouldn't be externalized */
+ @SuppressWarnings("nls")
+ private void preOrderPrint(PrintWriter writer, boolean printIntervals,
+ HTNode currentNode, int curDepth) {
+
+ writer.println(currentNode.toString());
+ if (printIntervals) {
+ currentNode.debugPrintIntervals(writer);
+ }
+
+ switch (currentNode.getNodeType()) {
+ case LEAF:
+ /* Stop if it's the leaf node */
+ return;
+
+ case CORE:
+ try {
+ final CoreNode node = (CoreNode) currentNode;
+ /* Print the extensions, if any */
+ int extension = node.getExtensionSequenceNumber();
+ while (extension != -1) {
+ HTNode nextNode = treeIO.readNode(extension);
+ preOrderPrint(writer, printIntervals, nextNode, curDepth);
+ }
+
+ /* Print the child nodes */
+ for (int i = 0; i < node.getNbChildren(); i++) {
+ HTNode nextNode = treeIO.readNode(node.getChild(i));
+ for (int j = 0; j < curDepth; j++) {
+ writer.print(" ");
+ }
+ writer.print("+-");
+ preOrderPrint(writer, printIntervals, nextNode, curDepth + 1);
+ }
+ } catch (ClosedChannelException e) {
+ Activator.getDefault().logError(e.getMessage());
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /**
+ * Print out the full tree for debugging purposes
+ *
+ * @param writer
+ * PrintWriter in which to write the output
+ * @param printIntervals
+ * Flag to enable full output of the interval information
+ */
+ public void debugPrintFullTree(PrintWriter writer, boolean printIntervals) {
+ /* Only used for debugging, shouldn't be externalized */
+
+ this.preOrderPrint(writer, false, latestBranch.get(0), 0);
+
+ if (printIntervals) {
+ writer.println("\nDetails of intervals:"); //$NON-NLS-1$
+ this.preOrderPrint(writer, true, latestBranch.get(0), 0);
+ }
+ writer.println('\n');
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2015 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ * Patrick Tasse - Add message to exceptions
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.channels.ClosedChannelException;
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.CoreNode;
+import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTConfig;
+import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTInterval;
+import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTNode;
+import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HistoryTree;
+import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
+import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
+
+/**
+ * History Tree backend for storing a state history. This is the basic version
+ * that runs in the same thread as the class creating it.
+ *
+ * @author Alexandre Montplaisir
+ */
+public class HistoryTreeBackend implements IStateHistoryBackend {
+
+ private final @NonNull String ssid;
+
+ /**
+ * The history tree that sits underneath.
+ */
+ private final HistoryTree sht;
+
+ /** Indicates if the history tree construction is done */
+ private volatile boolean fFinishedBuilding = false;
+
+ /**
+ * Indicates if the history tree construction is done
+ *
+ * @return if the history tree construction is done
+ */
+ protected boolean isFinishedBuilding() {
+ return fFinishedBuilding;
+ }
+
+ /**
+ * Sets if the history tree is finished building
+ *
+ * @param isFinishedBuilding
+ * is the history tree finished building
+ */
+ protected void setFinishedBuilding(boolean isFinishedBuilding) {
+ this.fFinishedBuilding = isFinishedBuilding;
+ }
+
+ /**
+ * Constructor for new history files. Use this when creating a new history
+ * from scratch.
+ *
+ * @param ssid
+ * The state system's ID
+ * @param newStateFile
+ * The filename/location where to store the state history (Should
+ * end in .ht)
+ * @param providerVersion
+ * Version of of the state provider. We will only try to reopen
+ * existing files if this version matches the one in the
+ * framework.
+ * @param startTime
+ * The earliest time stamp that will be stored in the history
+ * @param blockSize
+ * The size of the blocks in the history file. This should be a
+ * multiple of 4096.
+ * @param maxChildren
+ * The maximum number of children each core node can have
+ * @throws IOException
+ * Thrown if we can't create the file for some reason
+ */
+ public HistoryTreeBackend(@NonNull String ssid,
+ File newStateFile,
+ int providerVersion,
+ long startTime,
+ int blockSize,
+ int maxChildren) throws IOException {
+ this.ssid = ssid;
+ final HTConfig conf = new HTConfig(newStateFile, blockSize, maxChildren,
+ providerVersion, startTime);
+ sht = new HistoryTree(conf);
+ }
+
+ /**
+ * Constructor for new history files. Use this when creating a new history
+ * from scratch. This version supplies sane defaults for the configuration
+ * parameters.
+ *
+ * @param ssid
+ * The state system's id
+ * @param newStateFile
+ * The filename/location where to store the state history (Should
+ * end in .ht)
+ * @param providerVersion
+ * Version of of the state provider. We will only try to reopen
+ * existing files if this version matches the one in the
+ * framework.
+ * @param startTime
+ * The earliest time stamp that will be stored in the history
+ * @throws IOException
+ * Thrown if we can't create the file for some reason
+ * @since 1.0
+ */
+ public HistoryTreeBackend(@NonNull String ssid, File newStateFile, int providerVersion, long startTime)
+ throws IOException {
+ this(ssid, newStateFile, providerVersion, startTime, 64 * 1024, 50);
+ }
+
+ /**
+ * Existing history constructor. Use this to open an existing state-file.
+ *
+ * @param ssid
+ * The state system's id
+ * @param existingStateFile
+ * Filename/location of the history we want to load
+ * @param providerVersion
+ * Expected version of of the state provider plugin.
+ * @throws IOException
+ * If we can't read the file, if it doesn't exist, is not
+ * recognized, or if the version of the file does not match the
+ * expected providerVersion.
+ */
+ public HistoryTreeBackend(@NonNull String ssid, File existingStateFile, int providerVersion)
+ throws IOException {
+ this.ssid = ssid;
+ sht = new HistoryTree(existingStateFile, providerVersion);
+ fFinishedBuilding = true;
+ }
+
+ /**
+ * Get the History Tree built by this backend.
+ *
+ * @return The history tree
+ */
+ protected HistoryTree getSHT() {
+ return sht;
+ }
+
+ @Override
+ public String getSSID() {
+ return ssid;
+ }
+
+ @Override
+ public long getStartTime() {
+ return sht.getTreeStart();
+ }
+
+ @Override
+ public long getEndTime() {
+ return sht.getTreeEnd();
+ }
+
+ @Override
+ public void insertPastState(long stateStartTime, long stateEndTime,
+ int quark, ITmfStateValue value) throws TimeRangeException {
+ HTInterval interval = new HTInterval(stateStartTime, stateEndTime,
+ quark, (TmfStateValue) value);
+
+ /* Start insertions at the "latest leaf" */
+ sht.insertInterval(interval);
+ }
+
+ @Override
+ public void finishedBuilding(long endTime) {
+ sht.closeTree(endTime);
+ fFinishedBuilding = true;
+ }
+
+ @Override
+ public FileInputStream supplyAttributeTreeReader() {
+ return sht.supplyATReader();
+ }
+
+ @Override
+ public File supplyAttributeTreeWriterFile() {
+ return sht.supplyATWriterFile();
+ }
+
+ @Override
+ public long supplyAttributeTreeWriterFilePosition() {
+ return sht.supplyATWriterFilePos();
+ }
+
+ @Override
+ public void removeFiles() {
+ sht.deleteFile();
+ }
+
+ @Override
+ public void dispose() {
+ if (fFinishedBuilding) {
+ sht.closeFile();
+ } else {
+ /*
+ * The build is being interrupted, delete the file we partially
+ * built since it won't be complete, so shouldn't be re-used in the
+ * future (.deleteFile() will close the file first)
+ */
+ sht.deleteFile();
+ }
+ }
+
+ @Override
+ public void doQuery(List<ITmfStateInterval> stateInfo, long t)
+ throws TimeRangeException, StateSystemDisposedException {
+ checkValidTime(t);
+
+ /* We start by reading the information in the root node */
+ HTNode currentNode = sht.getRootNode();
+ currentNode.writeInfoFromNode(stateInfo, t);
+
+ /* Then we follow the branch down in the relevant children */
+ try {
+ while (currentNode.getNodeType() == HTNode.NodeType.CORE) {
+ currentNode = sht.selectNextChild((CoreNode) currentNode, t);
+ currentNode.writeInfoFromNode(stateInfo, t);
+ }
+ } catch (ClosedChannelException e) {
+ throw new StateSystemDisposedException(e);
+ }
+
+ /*
+ * The stateInfo should now be filled with everything needed, we pass
+ * the control back to the State System.
+ */
+ return;
+ }
+
+ @Override
+ public ITmfStateInterval doSingularQuery(long t, int attributeQuark)
+ throws TimeRangeException, StateSystemDisposedException {
+ return getRelevantInterval(t, attributeQuark);
+ }
+
+ private void checkValidTime(long t) {
+ long treeStart = sht.getTreeStart();
+ long treeEnd = sht.getTreeEnd();
+ if (t < treeStart || t > treeEnd) {
+ throw new TimeRangeException(ssid + " Time:" + t + ", Start:" + treeStart + ", End:" + treeEnd); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ }
+
+ /**
+ * Inner method to find the interval in the tree containing the requested
+ * key/timestamp pair, wherever in which node it is.
+ *
+ * @param t
+ * @param key
+ * @return The node containing the information we want
+ */
+ private HTInterval getRelevantInterval(long t, int key)
+ throws TimeRangeException, StateSystemDisposedException {
+ checkValidTime(t);
+
+ HTNode currentNode = sht.getRootNode();
+ HTInterval interval = currentNode.getRelevantInterval(key, t);
+
+ try {
+ while (interval == null && currentNode.getNodeType() == HTNode.NodeType.CORE) {
+ currentNode = sht.selectNextChild((CoreNode) currentNode, t);
+ interval = currentNode.getRelevantInterval(key, t);
+ }
+ } catch (ClosedChannelException e) {
+ throw new StateSystemDisposedException(e);
+ }
+ return interval;
+ }
+
+ /**
+ * Return the size of the tree history file
+ *
+ * @return The current size of the history file in bytes
+ */
+ public long getFileSize() {
+ return sht.getFileSize();
+ }
+
+ /**
+ * Return the average node usage as a percentage (between 0 and 100)
+ *
+ * @return Average node usage %
+ */
+ public int getAverageNodeUsage() {
+ HTNode node;
+ long total = 0;
+ long ret;
+
+ try {
+ for (int seq = 0; seq < sht.getNodeCount(); seq++) {
+ node = sht.readNode(seq);
+ total += node.getNodeUsagePercent();
+ }
+ } catch (ClosedChannelException e) {
+ e.printStackTrace();
+ }
+
+ ret = total / sht.getNodeCount();
+ assert (ret >= 0 && ret <= 100);
+ return (int) ret;
+ }
+
+ @Override
+ public void debugPrint(PrintWriter writer) {
+ /* By default don't print out all the intervals */
+ this.debugPrint(writer, false);
+ }
+
+ /**
+ * The basic debugPrint method will print the tree structure, but not their
+ * contents.
+ *
+ * This method here print the contents (the intervals) as well.
+ *
+ * @param writer
+ * The PrintWriter to which the debug info will be written
+ * @param printIntervals
+ * Should we also print every contained interval individually?
+ */
+ public void debugPrint(PrintWriter writer, boolean printIntervals) {
+ /* Only used for debugging, shouldn't be externalized */
+ writer.println("------------------------------"); //$NON-NLS-1$
+ writer.println("State History Tree:\n"); //$NON-NLS-1$
+ writer.println(sht.toString());
+ writer.println("Average node utilization: " //$NON-NLS-1$
+ + this.getAverageNodeUsage());
+ writer.println(""); //$NON-NLS-1$
+
+ sht.debugPrintFullTree(writer, printIntervals);
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2014 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Florian Wininger - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;
+
+import java.nio.ByteBuffer;
+
+/**
+ * A Leaf node is a last-level node of a History Tree.
+ *
+ * A leaf node cannot have children, so it extends HTNode without adding
+ * anything in particular.
+ *
+ * @author Florian Wininger
+ */
+public final class LeafNode extends HTNode {
+
+ /**
+ * Initial constructor. Use this to initialize a new EMPTY node.
+ *
+ * @param config
+ * Configuration of the History Tree
+ * @param seqNumber
+ * The (unique) sequence number assigned to this particular node
+ * @param parentSeqNumber
+ * The sequence number of this node's parent node
+ * @param start
+ * The earliest timestamp stored in this node
+ */
+ public LeafNode(HTConfig config, int seqNumber, int parentSeqNumber,
+ long start) {
+ super(config, seqNumber, parentSeqNumber, start);
+ }
+
+ @Override
+ protected void readSpecificHeader(ByteBuffer buffer) {
+ /* No specific header part */
+ }
+
+ @Override
+ protected void writeSpecificHeader(ByteBuffer buffer) {
+ /* No specific header part */
+ }
+
+ @Override
+ public NodeType getNodeType() {
+ return NodeType.LEAF;
+ }
+
+ @Override
+ protected int getSpecificHeaderSize() {
+ /* Empty */
+ return 0;
+ }
+
+ @Override
+ public String toStringSpecific() {
+ /* Only used for debugging, shouldn't be externalized */
+ return "Leaf Node, "; //$NON-NLS-1$;
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2015 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.common.core.collect.BufferedBlockingQueue;
+import org.eclipse.tracecompass.internal.statesystem.core.Activator;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
+import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
+
+/**
+ * Variant of the HistoryTreeBackend which runs all the interval-insertion logic
+ * in a separate thread.
+ *
+ * @author Alexandre Montplaisir
+ */
+public final class ThreadedHistoryTreeBackend extends HistoryTreeBackend
+ implements Runnable {
+
+ private static final int CHUNK_SIZE = 127;
+ private final @NonNull BufferedBlockingQueue<HTInterval> intervalQueue;
+ private final @NonNull Thread shtThread;
+
+ /**
+ * New state history constructor
+ *
+ * Note that it usually doesn't make sense to use a Threaded HT if you're
+ * opening an existing state-file, but you know what you're doing...
+ *
+ * @param ssid
+ * The state system's id
+ * @param newStateFile
+ * The name of the history file that will be created. Should end
+ * in ".ht"
+ * @param providerVersion
+ * Version of of the state provider. We will only try to reopen
+ * existing files if this version matches the one in the
+ * framework.
+ * @param startTime
+ * The earliest timestamp stored in the history
+ * @param queueSize
+ * The size of the interval insertion queue. 2000 - 10000 usually
+ * works well
+ * @param blockSize
+ * The size of the blocks in the file
+ * @param maxChildren
+ * The maximum number of children allowed for each core node
+ * @throws IOException
+ * If there was a problem opening the history file for writing
+ */
+ public ThreadedHistoryTreeBackend(@NonNull String ssid,
+ File newStateFile,
+ int providerVersion,
+ long startTime,
+ int queueSize,
+ int blockSize,
+ int maxChildren)
+ throws IOException {
+ super(ssid, newStateFile, providerVersion, startTime, blockSize, maxChildren);
+
+ intervalQueue = new BufferedBlockingQueue<>(queueSize / CHUNK_SIZE, CHUNK_SIZE);
+ shtThread = new Thread(this, "History Tree Thread"); //$NON-NLS-1$
+ shtThread.start();
+ }
+
+ /**
+ * New State History constructor. This version provides default values for
+ * blockSize and maxChildren.
+ *
+ * @param ssid
+ * The state system's id
+ * @param newStateFile
+ * The name of the history file that will be created. Should end
+ * in ".ht"
+ * @param providerVersion
+ * Version of of the state provider. We will only try to reopen
+ * existing files if this version matches the one in the
+ * framework.
+ * @param startTime
+ * The earliest timestamp stored in the history
+ * @param queueSize
+ * The size of the interval insertion queue. 2000 - 10000 usually
+ * works well
+ * @throws IOException
+ * If there was a problem opening the history file for writing
+ */
+ public ThreadedHistoryTreeBackend(@NonNull String ssid,
+ File newStateFile,
+ int providerVersion,
+ long startTime,
+ int queueSize)
+ throws IOException {
+ super(ssid, newStateFile, providerVersion, startTime);
+
+ intervalQueue = new BufferedBlockingQueue<>(queueSize / CHUNK_SIZE, CHUNK_SIZE);
+ shtThread = new Thread(this, "History Tree Thread"); //$NON-NLS-1$
+ shtThread.start();
+ }
+
+ /*
+ * The Threaded version does not specify an "existing file" constructor,
+ * since the history is already built (and we only use the other thread
+ * during building). Just use a plain HistoryTreeProvider in this case.
+ *
+ * TODO but what about streaming??
+ */
+
+ @Override
+ public void insertPastState(long stateStartTime, long stateEndTime,
+ int quark, ITmfStateValue value) throws TimeRangeException {
+ /*
+ * Here, instead of directly inserting the elements in the History Tree
+ * underneath, we'll put them in the Queue. They will then be taken and
+ * processed by the other thread executing the run() method.
+ */
+ HTInterval interval = new HTInterval(stateStartTime, stateEndTime,
+ quark, (TmfStateValue) value);
+ intervalQueue.put(interval);
+ }
+
+ @Override
+ public void finishedBuilding(long endTime) {
+ /*
+ * We need to commit everything in the History Tree and stop the
+ * standalone thread before returning to the StateHistorySystem. (SHS
+ * will then write the Attribute Tree to the file, that must not happen
+ * at the same time we are writing the last nodes!)
+ */
+
+ stopRunningThread(endTime);
+ setFinishedBuilding(true);
+ return;
+ }
+
+ @Override
+ public void dispose() {
+ if (!isFinishedBuilding()) {
+ stopRunningThread(Long.MAX_VALUE);
+ }
+ /*
+ * isFinishedBuilding remains false, so the superclass will ask the
+ * back-end to delete the file.
+ */
+ super.dispose();
+ }
+
+ private void stopRunningThread(long endTime) {
+ if (!shtThread.isAlive()) {
+ return;
+ }
+
+ /*
+ * Send a "poison pill" in the queue, then wait for the HT to finish its
+ * closeTree()
+ */
+ try {
+ HTInterval pill = new HTInterval(-1, endTime, -1, TmfStateValue.nullValue());
+ intervalQueue.put(pill);
+ intervalQueue.flushInputBuffer();
+ shtThread.join();
+ } catch (TimeRangeException e) {
+ Activator.getDefault().logError("Error closing state system", e); //$NON-NLS-1$
+ } catch (InterruptedException e) {
+ Activator.getDefault().logError("State system interrupted", e); //$NON-NLS-1$
+ }
+ }
+
+ @Override
+ public void run() {
+ HTInterval currentInterval;
+ try {
+ currentInterval = intervalQueue.take();
+ while (currentInterval.getStartTime() != -1) {
+ /* Send the interval to the History Tree */
+ getSHT().insertInterval(currentInterval);
+ currentInterval = intervalQueue.take();
+ }
+ if (currentInterval.getAttribute() != -1) {
+ /* Make sure this is the "poison pill" we are waiting for */
+ throw new IllegalStateException();
+ }
+ /*
+ * We've been told we're done, let's write down everything and quit.
+ * The end time of this "signal interval" is actually correct.
+ */
+ getSHT().closeTree(currentInterval.getEndTime());
+ return;
+ } catch (TimeRangeException e) {
+ /* This should not happen */
+ Activator.getDefault().logError("Error starting the state system", e); //$NON-NLS-1$
+ }
+ }
+
+ // ------------------------------------------------------------------------
+ // Query methods
+ // ------------------------------------------------------------------------
+
+ @Override
+ public void doQuery(List<ITmfStateInterval> currentStateInfo, long t)
+ throws TimeRangeException, StateSystemDisposedException {
+ super.doQuery(currentStateInfo, t);
+
+ if (isFinishedBuilding()) {
+ /*
+ * The history tree is the only place to look for intervals once
+ * construction is finished.
+ */
+ return;
+ }
+
+ /*
+ * It is possible we may have missed some intervals due to them being in
+ * the queue while the query was ongoing. Go over the results to see if
+ * we missed any.
+ */
+ for (int i = 0; i < currentStateInfo.size(); i++) {
+ if (currentStateInfo.get(i) == null) {
+ /* Query the missing interval via "unicast" */
+ ITmfStateInterval interval = doSingularQuery(t, i);
+ currentStateInfo.set(i, interval);
+ }
+ }
+ }
+
+ @Override
+ public ITmfStateInterval doSingularQuery(long t, int attributeQuark)
+ throws TimeRangeException, StateSystemDisposedException {
+ ITmfStateInterval ret = super.doSingularQuery(t, attributeQuark);
+ if (ret != null) {
+ return ret;
+ }
+
+ /*
+ * We couldn't find the interval in the history tree. It's possible that
+ * it is currently in the intervalQueue. Look for it there. Note that
+ * BufferedBlockingQueue's iterator() is thread-safe (no need to lock
+ * the queue).
+ */
+ for (ITmfStateInterval interval : intervalQueue) {
+ if (interval.getAttribute() == attributeQuark && interval.intersects(t)) {
+ return interval;
+ }
+ }
+
+ /*
+ * If we missed it again, it's because it got inserted in the tree
+ * *while we were iterating* on the queue. One last pass in the tree
+ * should find it.
+ *
+ * This case is really rare, which is why we do a second pass at the end
+ * if needed, instead of systematically checking in the queue first
+ * (which is slow).
+ */
+ return super.doSingularQuery(t, attributeQuark);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2015 Ericsson and others.
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API
+ ******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core;
+
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
+
+
+/**
+ * This is the read-only interface to the generic state system. It contains all
+ * the read-only quark-getting methods, as well as the history-querying ones.
+ *
+ * @author Alexandre Montplaisir
+ * @noimplement Only the internal StateSystem class should implement this
+ * interface.
+ */
+public interface ITmfStateSystem {
+
+ /**
+ * Get the ID of this state system.
+ *
+ * @return The state system's ID
+ */
+ String getSSID();
+
+ /**
+ * Return the start time of this history. It usually matches the start time
+ * of the original trace.
+ *
+ * @return The history's registered start time
+ */
+ long getStartTime();
+
+ /**
+ * Return the current end time of the history.
+ *
+ * @return The current end time of this state history
+ */
+ long getCurrentEndTime();
+
+ /**
+ * Check if the construction of this state system was cancelled or not. If
+ * false is returned, it can mean that the building was finished
+ * successfully, or that it is still ongoing. You can check independently
+ * with {@link #waitUntilBuilt()} if it is finished or not.
+ *
+ * @return If the construction was cancelled or not. In true is returned, no
+ * queries should be run afterwards.
+ */
+ boolean isCancelled();
+
+ /**
+ * While it's possible to query a state history that is being built,
+ * sometimes we might want to wait until the construction is finished before
+ * we start doing queries.
+ *
+ * This method blocks the calling thread until the history back-end is done
+ * building. If it's already built (ie, opening a pre-existing file) this
+ * should return immediately.
+ *
+ * You should always check with {@link #isCancelled()} if it is safe to
+ * query this state system before doing queries.
+ */
+ void waitUntilBuilt();
+
+ /**
+ * Wait until the state system construction is finished. Similar to
+ * {@link #waitUntilBuilt()}, but we also specify a timeout. If the timeout
+ * elapses before the construction is finished, the method will return.
+ *
+ * The return value determines if the return was due to the construction
+ * finishing (true), or the timeout elapsing (false).
+ *
+ * This can be useful, for example, for a component doing queries
+ * periodically to the system while it is being built.
+ *
+ * @param timeout
+ * Timeout value in milliseconds
+ * @return True if the return was due to the construction finishing, false
+ * if it was because the timeout elapsed. Same logic as
+ * {@link java.util.concurrent.CountDownLatch#await(long, java.util.concurrent.TimeUnit)}
+ */
+ boolean waitUntilBuilt(long timeout);
+
+ /**
+ * Notify the state system that the trace is being closed, so it should
+ * clean up, close its files, etc.
+ */
+ void dispose();
+
+ // ------------------------------------------------------------------------
+ // Read-only quark-getting methods
+ // ------------------------------------------------------------------------
+
+ /**
+ * Return the current total amount of attributes in the system. This is also
+ * equal to the quark that will be assigned to the next attribute that's
+ * created.
+ *
+ * @return The current number of attributes in the system
+ */
+ int getNbAttributes();
+
+ /**
+ * Basic quark-retrieving method. Pass an attribute in parameter as an array
+ * of strings, the matching quark will be returned.
+ *
+ * This version will NOT create any new attributes. If an invalid attribute
+ * is requested, an exception will be thrown.
+ *
+ * @param attribute
+ * Attribute given as its full path in the Attribute Tree
+ * @return The quark of the requested attribute, if it existed.
+ * @throws AttributeNotFoundException
+ * This exception is thrown if the requested attribute simply
+ * did not exist in the system.
+ */
+ int getQuarkAbsolute(String... attribute)
+ throws AttributeNotFoundException;
+
+ /**
+ * "Relative path" quark-getting method. Instead of specifying a full path,
+ * if you know the path is relative to another attribute for which you
+ * already have the quark, use this for better performance.
+ *
+ * This is useful for cases where a lot of modifications or queries will
+ * originate from the same branch of the attribute tree : the common part of
+ * the path won't have to be re-hashed for every access.
+ *
+ * This version will NOT create any new attributes. If an invalid attribute
+ * is requested, an exception will be thrown.
+ *
+ * @param startingNodeQuark
+ * The quark of the attribute from which 'subPath' originates.
+ * @param subPath
+ * "Rest" of the path to get to the final attribute
+ * @return The matching quark, if it existed
+ * @throws IndexOutOfBoundsException
+ * If the starting node quark is out of range
+ * @throws AttributeNotFoundException
+ * If the sub-attribute does not exist
+ */
+ int getQuarkRelative(int startingNodeQuark, String... subPath)
+ throws AttributeNotFoundException;
+
+ /**
+ * Return the sub-attributes of the target attribute, as a List of quarks.
+ *
+ * @param quark
+ * The attribute of which you want to sub-attributes. You can use
+ * "-1" here to specify the root node.
+ * @param recursive
+ * True if you want all recursive sub-attributes, false if you
+ * only want the first level.
+ * @return A List of integers, matching the quarks of the sub-attributes.
+ * @throws AttributeNotFoundException
+ * If the quark was not existing or invalid.
+ */
+ @NonNull List<Integer> getSubAttributes(int quark, boolean recursive)
+ throws AttributeNotFoundException;
+
+ /**
+ * Return the sub-attributes of the target attribute, as a List of quarks,
+ * similarly to {@link #getSubAttributes(int, boolean)}, but with an added
+ * regex pattern to filter on the return attributes.
+ *
+ * @param quark
+ * The attribute of which you want to sub-attributes. You can use
+ * "-1" here to specify the root node.
+ * @param recursive
+ * True if you want all recursive sub-attributes, false if you
+ * only want the first level. Note that the returned value will
+ * be flattened.
+ * @param pattern
+ * The regular expression to match the attribute base name.
+ * @return A List of integers, matching the quarks of the sub-attributes
+ * that match the regex. An empty list is returned if there is no
+ * matching attribute.
+ * @throws AttributeNotFoundException
+ * If the 'quark' was not existing or invalid.
+ */
+ List<Integer> getSubAttributes(int quark, boolean recursive, String pattern)
+ throws AttributeNotFoundException;
+
+ /**
+ * Batch quark-retrieving method. This method allows you to specify a path
+ * pattern which includes a wildcard "*" somewhere. It will check all the
+ * existing attributes in the attribute tree and return those who match the
+ * pattern.
+ *
+ * For example, passing ("Threads", "*", "Exec_mode") will return the list
+ * of quarks for attributes "Threads/1000/Exec_mode",
+ * "Threads/1500/Exec_mode", and so on, depending on what exists at this
+ * time in the attribute tree.
+ *
+ * If no wildcard is specified, the behavior is the same as
+ * getQuarkAbsolute() (except it will return a List with one entry). This
+ * method will never create new attributes.
+ *
+ * Only one wildcard "*" is supported at this time.
+ *
+ * @param pattern
+ * The array of strings representing the pattern to look for. It
+ * should ideally contain one entry that is only a "*".
+ * @return A List of attribute quarks, representing attributes that matched
+ * the pattern. If no attribute matched, the list will be empty (but
+ * not null).
+ */
+ List<Integer> getQuarks(String... pattern);
+
+ /**
+ * Return the name assigned to this quark. This returns only the "basename",
+ * not the complete path to this attribute.
+ *
+ * @param attributeQuark
+ * The quark for which we want the name
+ * @return The name of the quark
+ * @throws IndexOutOfBoundsException
+ * If the attribute quark is out of range
+ */
+ @NonNull String getAttributeName(int attributeQuark);
+
+ /**
+ * This returns the slash-separated path of an attribute by providing its
+ * quark
+ *
+ * @param attributeQuark
+ * The quark of the attribute we want
+ * @return One single string separated with '/', like a filesystem path
+ * @throws IndexOutOfBoundsException
+ * If the attribute quark is out of range
+ */
+ @NonNull String getFullAttributePath(int attributeQuark);
+
+ /**
+ * Return the full attribute path, as an array of strings representing each
+ * element.
+ *
+ * @param attributeQuark
+ * The quark of the attribute we want.
+ * @return The array of path elements
+ * @throws IndexOutOfBoundsException
+ * If the attribute quark is out of range
+ * @since 1.0
+ */
+ @NonNull String[] getFullAttributePathArray(int attributeQuark);
+
+ /**
+ * Returns the parent quark of the attribute.
+ *
+ * @param attributeQuark
+ * The quark of the attribute
+ * @return Quark of the parent attribute or <code>-1</code> if root quark or
+ * no parent.
+ * @throws IndexOutOfBoundsException
+ * If the attribute quark is out of range
+ */
+ int getParentAttributeQuark(int attributeQuark);
+
+ // ------------------------------------------------------------------------
+ // Query methods
+ // ------------------------------------------------------------------------
+
+ /**
+ * Returns the current state value we have (in the Transient State) for the
+ * given attribute.
+ *
+ * This is useful even for a StateHistorySystem, as we are guaranteed it
+ * will only do a memory access and not go look on disk (and we don't even
+ * have to provide a timestamp!)
+ *
+ * @param attributeQuark
+ * For which attribute we want the current state
+ * @return The State value that's "current" for this attribute
+ * @throws AttributeNotFoundException
+ * If the requested attribute is invalid
+ */
+ ITmfStateValue queryOngoingState(int attributeQuark)
+ throws AttributeNotFoundException;
+
+ /**
+ * Get the start time of the current ongoing state, for the specified
+ * attribute.
+ *
+ * @param attribute
+ * Quark of the attribute
+ * @return The current start time of the ongoing state
+ * @throws AttributeNotFoundException
+ * If the attribute is invalid
+ */
+ long getOngoingStartTime(int attribute)
+ throws AttributeNotFoundException;
+
+ /**
+ * Load the complete state information at time 't' into the returned List.
+ * You can then get the intervals for single attributes by using
+ * List.get(n), where 'n' is the quark of the attribute.
+ *
+ * On average if you need around 10 or more queries for the same timestamps,
+ * use this method. If you need less than 10 (for example, running many
+ * queries for the same attributes but at different timestamps), you might
+ * be better using the querySingleState() methods instead.
+ *
+ * @param t
+ * We will recreate the state information to what it was at time
+ * t.
+ * @return The List of intervals, where the offset = the quark
+ * @throws TimeRangeException
+ * If the 't' parameter is outside of the range of the state
+ * history.
+ * @throws StateSystemDisposedException
+ * If the query is sent after the state system has been disposed
+ */
+ @NonNull List<ITmfStateInterval> queryFullState(long t)
+ throws StateSystemDisposedException;
+
+ /**
+ * Singular query method. This one does not update the whole stateInfo
+ * vector, like queryFullState() does. It only searches for one specific
+ * entry in the state history.
+ *
+ * It should be used when you only want very few entries, instead of the
+ * whole state (or many entries, but all at different timestamps). If you do
+ * request many entries all at the same time, you should use the
+ * conventional queryFullState() + List.get() method.
+ *
+ * @param t
+ * The timestamp at which we want the state
+ * @param attributeQuark
+ * Which attribute we want to get the state of
+ * @return The StateInterval representing the state
+ * @throws TimeRangeException
+ * If 't' is invalid
+ * @throws AttributeNotFoundException
+ * If the requested quark does not exist in the model
+ * @throws StateSystemDisposedException
+ * If the query is sent after the state system has been disposed
+ */
+ @NonNull ITmfStateInterval querySingleState(long t, int attributeQuark)
+ throws AttributeNotFoundException, StateSystemDisposedException;
+}
\ No newline at end of file
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2014 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API
+ ******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
+
+/**
+ * This is the external interface to build or modify an existing state history.
+ *
+ * It extends ITmfStateSystem, so you can still use it for reading the history,
+ * but it also provides write-access to it with the quark-creating and
+ * state-change insertion methods.
+ *
+ * This should only be used by classes that need to build or modify the state
+ * history. Views, etc. (who will only be reading from it) should use the
+ * ITmfStateSystem interface instead.
+ *
+ * @author Alexandre Montplaisir
+ * @noimplement Only the internal StateSystem class should implement this
+ * interface.
+ */
+public interface ITmfStateSystemBuilder extends ITmfStateSystem {
+
+ /**
+ * Special state provider version number that will tell the backend to
+ * ignore the version check and open an existing file even if the versions
+ * don't match.
+ */
+ int IGNORE_PROVIDER_VERSION = -42;
+
+ /**
+ * @name Read/write quark-getting methods
+ */
+
+ /**
+ * Basic quark-retrieving method. Pass an attribute in parameter as an array
+ * of strings, the matching quark will be returned.
+ *
+ * This version WILL create new attributes: if the attribute passed in
+ * parameter is new in the system, it will be added and its new quark will
+ * be returned.
+ *
+ * @param attribute
+ * Attribute given as its full path in the Attribute Tree
+ * @return The quark of the attribute (which either existed or just got
+ * created)
+ */
+ int getQuarkAbsoluteAndAdd(String... attribute);
+
+ /**
+ * "Relative path" quark-getting method. Instead of specifying a full path,
+ * if you know the path is relative to another attribute for which you
+ * already have the quark, use this for better performance.
+ *
+ * This is useful for cases where a lot of modifications or queries will
+ * originate from the same branch of the attribute tree : the common part of
+ * the path won't have to be re-hashed for every access.
+ *
+ * This version WILL create new attributes: if the attribute passed in
+ * parameter is new in the system, it will be added and its new quark will
+ * be returned.
+ *
+ * @param startingNodeQuark
+ * The quark of the attribute from which 'subPath' originates.
+ * @param subPath
+ * "Rest" of the path to get to the final attribute
+ * @return The matching quark, either if it's new of just got created.
+ */
+ int getQuarkRelativeAndAdd(int startingNodeQuark, String... subPath);
+
+ /**
+ * @name State-changing methods
+ */
+
+ /**
+ * Modify a current "ongoing" state (instead of inserting a state change,
+ * like modifyAttribute() and others).
+ *
+ * This can be used to update the value of a previous state change, for
+ * example when we get information at the end of the state and not at the
+ * beginning. (return values of system calls, etc.)
+ *
+ * Note that past states can only be modified while they are still in
+ * memory, so only the "current state" can be updated. Once they get
+ * committed to disk (by inserting a new state change) it becomes too late.
+ *
+ * @param newValue
+ * The new value that will overwrite the "current" one.
+ * @param attributeQuark
+ * For which attribute in the system
+ * @throws AttributeNotFoundException
+ * If the requested attribute is invalid
+ */
+ void updateOngoingState(@NonNull ITmfStateValue newValue, int attributeQuark)
+ throws AttributeNotFoundException;
+
+ /**
+ * Basic attribute modification method, we simply specify a new value, for a
+ * given attribute, effective at the given timestamp.
+ *
+ * @param t
+ * Timestamp of the state change
+ * @param value
+ * The State Value we want to assign to the attribute
+ * @param attributeQuark
+ * Integer value of the quark corresponding to the attribute we
+ * want to modify
+ * @throws TimeRangeException
+ * If the requested time is outside of the trace's range
+ * @throws AttributeNotFoundException
+ * If the requested attribute quark is invalid
+ * @throws StateValueTypeException
+ * If the inserted state value's type does not match what is
+ * already assigned to this attribute.
+ */
+ void modifyAttribute(long t, ITmfStateValue value, int attributeQuark)
+ throws AttributeNotFoundException, StateValueTypeException;
+
+ /**
+ * Increment attribute method. Reads the current value of a given integer
+ * attribute (this value is right now in the Transient State), and increment
+ * it by 1. Useful for statistics.
+ *
+ * @param t
+ * Timestamp of the state change
+ * @param attributeQuark
+ * Attribute to increment. If it doesn't exist it will be added,
+ * with a new value of 1.
+ * @throws StateValueTypeException
+ * If the attribute already exists but is not of type Integer
+ * @throws TimeRangeException
+ * If the given timestamp is invalid
+ * @throws AttributeNotFoundException
+ * If the quark is invalid
+ */
+ void incrementAttribute(long t, int attributeQuark)
+ throws AttributeNotFoundException, StateValueTypeException;
+
+ /**
+ * "Push" helper method. This uses the given integer attribute as a stack:
+ * The value of that attribute will represent the stack depth (always >= 1).
+ * Sub-attributes will be created, their base-name will be the position in
+ * the stack (1, 2, etc.) and their value will be the state value 'value'
+ * that was pushed to this position.
+ *
+ * @param t
+ * Timestamp of the state change
+ * @param value
+ * State value to assign to this stack position.
+ * @param attributeQuark
+ * The base attribute to use as a stack. If it does not exist if
+ * will be created (with depth = 1)
+ * @throws TimeRangeException
+ * If the requested timestamp is invalid
+ * @throws AttributeNotFoundException
+ * If the attribute is invalid
+ * @throws StateValueTypeException
+ * If the attribute 'attributeQuark' already exists, but is not
+ * of integer type.
+ */
+ void pushAttribute(long t, ITmfStateValue value, int attributeQuark)
+ throws AttributeNotFoundException, StateValueTypeException;
+
+ /**
+ * Antagonist of the pushAttribute(), pops the top-most attribute on the
+ * stack-attribute. If this brings it back to depth = 0, the attribute is
+ * kept with depth = 0. If the value is already 0, or if the attribute
+ * doesn't exist, nothing is done.
+ *
+ * @param t
+ * Timestamp of the state change
+ * @param attributeQuark
+ * Quark of the stack-attribute to pop
+ * @return The state value that was popped, or 'null' if nothing was
+ * actually removed from the stack.
+ * @throws AttributeNotFoundException
+ * If the attribute is invalid
+ * @throws TimeRangeException
+ * If the timestamp is invalid
+ * @throws StateValueTypeException
+ * If the target attribute already exists, but its state value
+ * type is invalid (not an integer)
+ */
+ ITmfStateValue popAttribute(long t, int attributeQuark)
+ throws AttributeNotFoundException, StateValueTypeException;
+
+ /**
+ * Remove attribute method. Similar to the above modify- methods, with value
+ * = 0 / null, except we will also "nullify" all the sub-contents of the
+ * requested path (a bit like "rm -rf")
+ *
+ * @param t
+ * Timestamp of the state change
+ * @param attributeQuark
+ * Attribute to remove
+ * @throws TimeRangeException
+ * If the timestamp is invalid
+ * @throws AttributeNotFoundException
+ * If the quark is invalid
+ */
+ void removeAttribute(long t, int attributeQuark)
+ throws AttributeNotFoundException;
+
+ /**
+ * Method to close off the History Provider. This happens for example when
+ * we are done reading an off-line trace. First we close the TransientState,
+ * commit it to the Provider, mark it as inactive, then we write the
+ * Attribute Tree somewhere so we can reopen it later.
+ *
+ * @param endTime
+ * The requested End Time of the history, since it could be
+ * bigger than the timestamp of the last event or state change we
+ * have seen. All "ongoing" states will be extended until this
+ * 'endTime'.
+ * @throws TimeRangeException
+ * If the passed endTime doesn't make sense (for example, if
+ * it's earlier than the latest time) and the backend doesn't
+ * know how to handle it.
+ */
+ void closeHistory(long endTime);
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2014 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core;
+
+import java.io.IOException;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.tracecompass.internal.statesystem.core.StateSystem;
+import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
+
+/**
+ * Factory to create state systems.
+ *
+ * Since state system are meant to be accessed using the {@link ITmfStateSystem}
+ * and {@link ITmfStateSystemBuilder} interfaces, you can use this factory to
+ * instantiate new ones.
+ *
+ * @author Alexandre Montplaisir
+ */
+@NonNullByDefault
+public final class StateSystemFactory {
+
+ private StateSystemFactory() {}
+
+ /**
+ * New-file factory method. For when you build a state system with a new
+ * file, or if the back-end does not require a file on disk.
+ *
+ * @param backend
+ * Back-end plugin to use
+ * @return The new state system
+ * @since 1.0
+ */
+ public static ITmfStateSystemBuilder newStateSystem(IStateHistoryBackend backend) {
+ return new StateSystem(backend);
+ }
+
+ /**
+ * General factory method. The backend may try to open or create a file on
+ * disk (the file contents and location are defined by the backend).
+ *
+ * @param backend
+ * The "state history storage" back-end to use.
+ * @param newFile
+ * Put true if this is a new history started from scratch (any
+ * existing file will be overwritten).
+ * @return The new state system
+ * @throws IOException
+ * If there was a problem creating the new history file
+ * @since 1.0
+ */
+ public static ITmfStateSystemBuilder newStateSystem(IStateHistoryBackend backend,
+ boolean newFile) throws IOException {
+ return new StateSystem(backend, newFile);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2014, 2015 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Geneviève Bastien - Initial API and implementation
+ * Alexandre Montplaisir - Initial API and implementation
+ * Patrick Tasse - Add message to exceptions
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
+
+/**
+ * Provide utility methods for the state system
+ *
+ * @author Geneviève Bastien
+ */
+@NonNullByDefault
+public final class StateSystemUtils {
+
+ private StateSystemUtils() {
+ }
+
+ /**
+ * Convenience method to query attribute stacks (created with
+ * pushAttribute()/popAttribute()). This will return the interval that is
+ * currently at the top of the stack, or 'null' if that stack is currently
+ * empty. It works similarly to querySingleState().
+ *
+ * To retrieve the other values in a stack, you can query the sub-attributes
+ * manually.
+ *
+ * @param ss
+ * The state system to query
+ * @param t
+ * The timestamp of the query
+ * @param stackAttributeQuark
+ * The top-level stack-attribute (that was the target of
+ * pushAttribute() at creation time)
+ * @return The interval that was at the top of the stack, or 'null' if the
+ * stack was empty.
+ * @throws StateValueTypeException
+ * If the target attribute is not a valid stack attribute (if it
+ * has a string value for example)
+ * @throws AttributeNotFoundException
+ * If the attribute was simply not found
+ * @throws TimeRangeException
+ * If the given timestamp is invalid
+ * @throws StateSystemDisposedException
+ * If the query is sent after the state system has been disposed
+ */
+ public static @Nullable ITmfStateInterval querySingleStackTop(ITmfStateSystem ss,
+ long t, int stackAttributeQuark)
+ throws AttributeNotFoundException, StateSystemDisposedException {
+ ITmfStateValue curStackStateValue = ss.querySingleState(t, stackAttributeQuark).getStateValue();
+
+ if (curStackStateValue.isNull()) {
+ /* There is nothing stored in this stack at this moment */
+ return null;
+ }
+ int curStackDepth = curStackStateValue.unboxInt();
+ if (curStackDepth <= 0) {
+ /*
+ * This attribute is an integer attribute, but it doesn't seem like
+ * it's used as a stack-attribute...
+ */
+ throw new StateValueTypeException(ss.getSSID() + " Quark:" + stackAttributeQuark + ", Stack depth:" + curStackDepth); //$NON-NLS-1$//$NON-NLS-2$
+ }
+
+ int subAttribQuark = ss.getQuarkRelative(stackAttributeQuark, String.valueOf(curStackDepth));
+ return ss.querySingleState(t, subAttribQuark);
+ }
+
+ /**
+ * Return a list of state intervals, containing the "history" of a given
+ * attribute between timestamps t1 and t2. The list will be ordered by
+ * ascending time.
+ *
+ * Note that contrary to queryFullState(), the returned list here is in the
+ * "direction" of time (and not in the direction of attributes, as is the
+ * case with queryFullState()).
+ *
+ * @param ss
+ * The state system to query
+ * @param attributeQuark
+ * Which attribute this query is interested in
+ * @param t1
+ * Start time of the range query
+ * @param t2
+ * Target end time of the query. If t2 is greater than the end of
+ * the trace, we will return what we have up to the end of the
+ * history.
+ * @return The List of state intervals that happened between t1 and t2
+ * @throws TimeRangeException
+ * If t1 is invalid, or if t2 <= t1
+ * @throws AttributeNotFoundException
+ * If the requested quark does not exist in the model.
+ * @throws StateSystemDisposedException
+ * If the query is sent after the state system has been disposed
+ */
+ public static List<ITmfStateInterval> queryHistoryRange(ITmfStateSystem ss,
+ int attributeQuark, long t1, long t2)
+ throws AttributeNotFoundException, StateSystemDisposedException {
+
+ List<ITmfStateInterval> intervals;
+ ITmfStateInterval currentInterval;
+ long ts, tEnd;
+
+ /* Make sure the time range makes sense */
+ if (t2 < t1) {
+ throw new TimeRangeException(ss.getSSID() + " Start:" + t1 + ", End:" + t2); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /* Set the actual, valid end time of the range query */
+ if (t2 > ss.getCurrentEndTime()) {
+ tEnd = ss.getCurrentEndTime();
+ } else {
+ tEnd = t2;
+ }
+
+ /* Get the initial state at time T1 */
+ intervals = new ArrayList<>();
+ currentInterval = ss.querySingleState(t1, attributeQuark);
+ intervals.add(currentInterval);
+
+ /* Get the following state changes */
+ ts = currentInterval.getEndTime();
+ while (ts != -1 && ts < tEnd) {
+ ts++; /* To "jump over" to the next state in the history */
+ currentInterval = ss.querySingleState(ts, attributeQuark);
+ intervals.add(currentInterval);
+ ts = currentInterval.getEndTime();
+ }
+ return intervals;
+ }
+
+ /**
+ * Return the state history of a given attribute, but with at most one
+ * update per "resolution". This can be useful for populating views (where
+ * it's useless to have more than one query per pixel, for example). A
+ * progress monitor can be used to cancel the query before completion.
+ *
+ * @param ss
+ * The state system to query
+ * @param attributeQuark
+ * Which attribute this query is interested in
+ * @param t1
+ * Start time of the range query
+ * @param t2
+ * Target end time of the query. If t2 is greater than the end of
+ * the trace, we will return what we have up to the end of the
+ * history.
+ * @param resolution
+ * The "step" of this query
+ * @param monitor
+ * A progress monitor. If the monitor is canceled during a query,
+ * we will return what has been found up to that point. You can
+ * use "null" if you do not want to use one.
+ * @return The List of states that happened between t1 and t2
+ * @throws TimeRangeException
+ * If t1 is invalid, if t2 <= t1, or if the resolution isn't
+ * greater than zero.
+ * @throws AttributeNotFoundException
+ * If the attribute doesn't exist
+ * @throws StateSystemDisposedException
+ * If the query is sent after the state system has been disposed
+ */
+ public static List<ITmfStateInterval> queryHistoryRange(ITmfStateSystem ss,
+ int attributeQuark, long t1, long t2, long resolution,
+ @Nullable IProgressMonitor monitor)
+ throws AttributeNotFoundException, StateSystemDisposedException {
+ List<ITmfStateInterval> intervals = new LinkedList<>();
+ ITmfStateInterval currentInterval = null;
+ long ts, tEnd;
+
+ /* Make sure the time range makes sense */
+ if (t2 < t1 || resolution <= 0) {
+ throw new TimeRangeException(ss.getSSID() + " Start:" + t1 + ", End:" + t2 + ", Resolution:" + resolution); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ /* Set the actual, valid end time of the range query */
+ if (t2 > ss.getCurrentEndTime()) {
+ tEnd = ss.getCurrentEndTime();
+ } else {
+ tEnd = t2;
+ }
+
+ IProgressMonitor mon = monitor;
+ if (mon == null) {
+ mon = new NullProgressMonitor();
+ }
+
+ /*
+ * Iterate over the "resolution points". We skip unneeded queries in the
+ * case the current interval is longer than the resolution.
+ */
+ for (ts = t1; ts <= tEnd; ts += ((currentInterval.getEndTime() - ts) / resolution + 1) * resolution) {
+ if (mon.isCanceled()) {
+ return intervals;
+ }
+ currentInterval = ss.querySingleState(ts, attributeQuark);
+ intervals.add(currentInterval);
+ }
+
+ /* Add the interval at t2, if it wasn't included already. */
+ if (currentInterval != null && currentInterval.getEndTime() < tEnd) {
+ currentInterval = ss.querySingleState(tEnd, attributeQuark);
+ intervals.add(currentInterval);
+ }
+ return intervals;
+ }
+
+ /**
+ * Queries intervals in the state system for a given attribute, starting at
+ * time t1, until we obtain a non-null value.
+ *
+ * @param ss
+ * The state system on which to query intervals
+ * @param attributeQuark
+ * The attribute quark to query
+ * @param t1
+ * Start time of the query
+ * @param t2
+ * Time limit of the query. Use {@link Long#MAX_VALUE} for no
+ * limit.
+ * @return The first interval from t1 for which the value is not a null
+ * value, or <code>null</code> if no interval was found once we
+ * reach either t2 or the end time of the state system.
+ */
+ public static @Nullable ITmfStateInterval queryUntilNonNullValue(ITmfStateSystem ss,
+ int attributeQuark, long t1, long t2) {
+
+ long current = t1;
+ /* Make sure the range is ok */
+ if (t1 < ss.getStartTime()) {
+ current = ss.getStartTime();
+ }
+ long end = t2;
+ if (end < ss.getCurrentEndTime()) {
+ end = ss.getCurrentEndTime();
+ }
+ /* Make sure the time range makes sense */
+ if (end < current) {
+ return null;
+ }
+
+ try {
+ while (current < t2) {
+ ITmfStateInterval currentInterval = ss.querySingleState(current, attributeQuark);
+ ITmfStateValue value = currentInterval.getStateValue();
+
+ if (!value.isNull()) {
+ return currentInterval;
+ }
+ current = currentInterval.getEndTime() + 1;
+ }
+ } catch (AttributeNotFoundException | StateSystemDisposedException | TimeRangeException e) {
+ /* Nothing to do */
+ }
+ return null;
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2014 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.backend;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.PrintWriter;
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
+
+/**
+ * The main difference between StateSystem and StateHistorySystem is that SHS
+ * allows 'seeking' back in time to reload a Current State at a previous time.
+ * "How to go back in time" is defined by the implementation of the
+ * HistoryBackend.
+ *
+ * A StateHistorySystem contains one and only one HistoryBackend. If you want to
+ * use a paradigm with more than one provider (eg. more or less precision
+ * depending on what's asked by the user), implement one wrapper HistoryBackend
+ * which can then contain your 2-3 other backends underneath.
+ *
+ * @author Alexandre Montplaisir
+ */
+public interface IStateHistoryBackend {
+
+ /**
+ * Get the ID of the state system that populates this backend.
+ *
+ * @return The state system's ID.
+ * @since 1.0
+ */
+ @NonNull String getSSID();
+
+ /**
+ * Get the start time of this state history. This is usually the same as the
+ * start time of the originating trace.
+ *
+ * @return The start time
+ */
+ long getStartTime();
+
+ /**
+ * Get the current end time of the state history. It will change as the
+ * history is being built.
+ *
+ * @return The end time
+ */
+ long getEndTime();
+
+ /**
+ * Main method to insert state intervals into the history.
+ *
+ * @param stateStartTime
+ * The start time of the interval
+ * @param stateEndTime
+ * The end time of the interval
+ * @param quark
+ * The quark of the attribute this interval refers to
+ * @param value
+ * The StateValue represented by this interval
+ * @throws TimeRangeException
+ * If the start or end time are invalid
+ */
+ // FIXME change to IStateInterval?
+ void insertPastState(long stateStartTime, long stateEndTime,
+ int quark, ITmfStateValue value) throws TimeRangeException;
+
+ /**
+ * Indicate to the provider that we are done building the history (so it can
+ * close off, stop threads, etc.)
+ *
+ * @param endTime
+ * The end time to assign to this state history. It could be
+ * farther in time than the last state inserted, for example.
+ * @throws TimeRangeException
+ * If the requested time makes no sense.
+ */
+ void finishedBuilding(long endTime) throws TimeRangeException;
+
+ /**
+ * It is the responsibility of the backend to define where to save the
+ * Attribute Tree (since it's only useful to "reopen" an Attribute Tree if
+ * we have the matching History).
+ *
+ * This method defines where to read for the attribute tree when opening an
+ * already-existing history. Refer to the file format documentation.
+ *
+ * @return A FileInputStream object pointing to the correct file/location in
+ * the file where to read the attribute tree information.
+ */
+ FileInputStream supplyAttributeTreeReader();
+
+ // FIXME change to FOS too?
+ /**
+ * Supply the File object to which we will write the attribute tree. The
+ * position in this file is supplied by -TreeWriterFilePosition.
+ *
+ * @return The target File
+ */
+ File supplyAttributeTreeWriterFile();
+
+ /**
+ * Supply the position in the file where we should write the attribute tree
+ * when asked to.
+ *
+ * @return The file position (we will seek() to it)
+ */
+ long supplyAttributeTreeWriterFilePosition();
+
+ /**
+ * Delete any generated files or anything that might have been created by
+ * the history backend (either temporary or save files). By calling this, we
+ * return to the state as it was before ever building the history.
+ *
+ * You might not want to call automatically if, for example, you want an
+ * index file to persist on disk. This could be limited to actions
+ * originating from the user.
+ */
+ void removeFiles();
+
+ /**
+ * Notify the state history back-end that the trace is being closed, so it
+ * should release its file descriptors, close its connections, etc.
+ */
+ void dispose();
+
+ // ------------------------------------------------------------------------
+ // Query methods
+ // ------------------------------------------------------------------------
+
+ /**
+ * Complete "give me the state at a given time" method 'currentStateInfo' is
+ * an "out" parameter, that is, write to it the needed information and
+ * return. DO NOT 'new' currentStateInfo, it will be lost and nothing will
+ * be returned!
+ *
+ * @param currentStateInfo
+ * List of StateValues (index == quark) to fill up
+ * @param t
+ * Target timestamp of the query
+ * @throws TimeRangeException
+ * If the timestamp is outside of the history/trace
+ * @throws StateSystemDisposedException
+ * If the state system is disposed while a request is ongoing.
+ */
+ void doQuery(@NonNull List<ITmfStateInterval> currentStateInfo, long t)
+ throws TimeRangeException, StateSystemDisposedException;
+
+ /**
+ * Some providers might want to specify a different way to obtain just a
+ * single StateValue instead of updating the whole list. If the method to
+ * use is the same, then feel free to just implement this as a wrapper using
+ * doQuery().
+ *
+ * @param t
+ * The target timestamp of the query.
+ * @param attributeQuark
+ * The single attribute for which you want the state interval
+ * @return The state interval matching this timestamp/attribute pair
+ * @throws TimeRangeException
+ * If the timestamp was invalid
+ * @throws AttributeNotFoundException
+ * If the quark was invalid
+ * @throws StateSystemDisposedException
+ * If the state system is disposed while a request is ongoing.
+ */
+ ITmfStateInterval doSingularQuery(long t, int attributeQuark)
+ throws TimeRangeException, AttributeNotFoundException,
+ StateSystemDisposedException;
+
+ /**
+ * Debug method to print the contents of the history backend.
+ *
+ * @param writer
+ * The PrintWriter where to write the output
+ */
+ void debugPrint(PrintWriter writer);
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 EfficiOS Inc., Alexandre Montplaisir
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.backend;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.tracecompass.internal.statesystem.core.backend.InMemoryBackend;
+import org.eclipse.tracecompass.internal.statesystem.core.backend.NullBackend;
+import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HistoryTreeBackend;
+import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.ThreadedHistoryTreeBackend;
+
+/**
+ * Factory for the various types {@link IStateHistoryBackend} supplied by this
+ * plugin.
+ *
+ * @author Alexandre Montplaisir
+ * @since 1.0
+ */
+@NonNullByDefault
+public final class StateHistoryBackendFactory {
+
+ private StateHistoryBackendFactory() {}
+
+ /**
+ * Create a new null-backend, which will not store any history intervals
+ * (only the current state can be queried).
+ *
+ * @param ssid
+ * The ID for this state system
+ * @return The state system backend
+ */
+ public static IStateHistoryBackend createNullBackend(String ssid) {
+ return new NullBackend(ssid);
+ }
+
+ /**
+ * Create a new in-memory backend. This backend will store all the history
+ * intervals in memory, so it should not be used for anything serious.
+ *
+ * @param ssid
+ * The ID for this state system
+ * @param startTime
+ * The start time of the state system and backend
+ * @return The state system backend
+ */
+ public static IStateHistoryBackend createInMemoryBackend(String ssid, long startTime) {
+ return new InMemoryBackend(ssid, startTime);
+ }
+
+ /**
+ * Create a new backend using a History Tree. This backend stores all its
+ * intervals on disk.
+ *
+ * By specifying a 'queueSize' parameter, the implementation that runs in a
+ * separate thread can be used.
+ *
+ * @param ssid
+ * The state system's id
+ * @param stateFile
+ * The filename/location where to store the state history (Should
+ * end in .ht)
+ * @param providerVersion
+ * Version of of the state provider. We will only try to reopen
+ * existing files if this version matches the one in the
+ * framework.
+ * @param startTime
+ * The earliest time stamp that will be stored in the history
+ * @param queueSize
+ * The size of the interval insertion queue between the receiver
+ * and writer threads. 2000 - 10000 usually works well. If 0 is
+ * specified, no queue is used and the writes happen in the same
+ * thread.
+ * @return The state system backend
+ * @throws IOException
+ * Thrown if we can't create the file for some reason
+ */
+ public static IStateHistoryBackend createHistoryTreeBackendNewFile(String ssid,
+ File stateFile, int providerVersion, long startTime, int queueSize) throws IOException {
+ if (queueSize > 0) {
+ return new ThreadedHistoryTreeBackend(ssid, stateFile, providerVersion, startTime, queueSize);
+ }
+ return new HistoryTreeBackend(ssid, stateFile, providerVersion, startTime);
+ }
+
+ /**
+ * Create a new History Tree backend, but attempt to open an existing file
+ * on disk. If the file cannot be found or recognized, an IOException will
+ * be thrown.
+ *
+ * @param ssid
+ * The state system's id
+ * @param stateFile
+ * Filename/location of the history we want to load
+ * @param providerVersion
+ * Expected version of of the state provider plugin.
+ * @return The state system backend
+ * @throws IOException
+ * If we can't read the file, if it doesn't exist, is not
+ * recognized, or if the version of the file does not match the
+ * expected providerVersion.
+ */
+ public static IStateHistoryBackend createHistoryTreeBackendExistingFile(String ssid, File stateFile,
+ int providerVersion) throws IOException {
+ return new HistoryTreeBackend(ssid, stateFile, providerVersion);
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2015 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ * Patrick Tasse - Add message to exceptions
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.exceptions;
+
+/**
+ * This exception gets thrown when the user tries to access an attribute which
+ * doesn't exist in the system, of if the quark is simply invalid (ie, < 0).
+ *
+ * @author Alexandre Montplaisir
+ */
+public class AttributeNotFoundException extends Exception {
+
+ private static final long serialVersionUID = 7964275803369706145L;
+
+ /**
+ * Default constructor
+ */
+ public AttributeNotFoundException() {
+ super();
+ }
+
+ /**
+ * Constructor with a message
+ *
+ * @param message
+ * Message to attach to this exception
+ */
+ public AttributeNotFoundException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructor with both a message and a cause.
+ *
+ * @param message
+ * Message to attach to this exception
+ * @param e
+ * Cause of this exception
+ * @since 1.0
+ */
+ public AttributeNotFoundException(String message, Throwable e) {
+ super(message, e);
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2014 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.exceptions;
+
+/**
+ * Exception thrown by the state system if a query is done on it after it has
+ * been disposed.
+ *
+ * @author Alexandre Montplaisir
+ */
+public class StateSystemDisposedException extends Exception {
+
+ private static final long serialVersionUID = 7896041701818620084L;
+
+ /**
+ * Create a new simple StateSystemDisposedException.
+ */
+ public StateSystemDisposedException() {
+ super();
+ }
+
+ /**
+ * Create a new StateSystemDisposedException based on a previous one.
+ *
+ * @param e
+ * The previous exception
+ */
+ public StateSystemDisposedException(Throwable e) {
+ super(e);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2014 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.exceptions;
+
+/**
+ * The StateValue is a wrapper around the different type of values that can be
+ * used and stored in the state system and history. "Unboxing" the value means
+ * retrieving the base type (int, String, etc.) inside it.
+ *
+ * This exception is thrown if the user tries to unbox a StateValue with an
+ * incorrect type (for example, tries to read a String value as an Int).
+ *
+ * To avoid it, always check for the state value's type before attempting to
+ * unbox it, via
+ * {@link org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue#getType()}.
+ *
+ * @author Alexandre Montplaisir
+ */
+public class StateValueTypeException extends RuntimeException {
+
+ private static final long serialVersionUID = -4548793451746144513L;
+
+ /**
+ * Default constructor
+ */
+ public StateValueTypeException() {
+ super();
+ }
+
+ /**
+ * Constructor with a message
+ *
+ * @param message
+ * Message to attach to this exception
+ */
+ public StateValueTypeException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructor with both a message and a cause.
+ *
+ * @param message
+ * Message to attach to this exception
+ * @param e
+ * Cause of this exception
+ */
+ public StateValueTypeException(String message, Throwable e) {
+ super(message, e);
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2015 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ * Patrick Tasse - Add message to exceptions
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.exceptions;
+
+/**
+ * Generic exception for when the user specifies an invalid time stamp. Usually
+ * timestamps must be within the range of the trace or state history being
+ * queried.
+ *
+ * For insertions, it's forbidden to insert new states "in the past" (before where
+ * the cursor is), so this exception is also thrown in that case.
+ *
+ * @author Alexandre Montplaisir
+ */
+public class TimeRangeException extends RuntimeException {
+
+ private static final long serialVersionUID = -4067685227260254532L;
+
+ /**
+ * Default constructor
+ */
+ public TimeRangeException() {
+ }
+
+ /**
+ * Constructor with a message
+ *
+ * @param message
+ * Message to attach to this exception
+ * @since 1.0
+ */
+ public TimeRangeException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructor with both a message and a cause.
+ *
+ * @param message
+ * Message to attach to this exception
+ * @param e
+ * Cause of this exception
+ * @since 1.0
+ */
+ public TimeRangeException(String message, Throwable e) {
+ super(message, e);
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2014 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API
+ ******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.interval;
+
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
+
+/**
+ * This is the basic interface for accessing state intervals. See
+ * StateInterval.java for a basic implementation.
+ *
+ * A StateInterval is meant to be immutable. All implementing (non-abstract)
+ * classes should ideally be marked as 'final'.
+ *
+ * @author Alexandre Montplaisir
+ */
+public interface ITmfStateInterval {
+
+ /**
+ * Retrieve the start time of the interval
+ *
+ * @return the start time of the interval
+ */
+ long getStartTime();
+
+ /**
+ * Retrieve the end time of the interval
+ *
+ * @return the end time of the interval
+ */
+ long getEndTime();
+
+ /**
+ * In case the "real" end time of the interval is not exactly the same as
+ * the end time you want to show in views, you can implement this method to
+ * assign a different value that the viewer can use.
+ *
+ * If not, you can simply have it return the same as getEndTime().
+ *
+ * @return The end time that views should use
+ */
+ long getViewerEndTime();
+
+ /**
+ * Retrieve the quark of the attribute this state interval refers to
+ *
+ * @return the quark of the attribute this state interval refers to
+ */
+ int getAttribute();
+
+ /**
+ * Retrieve the state value represented by this interval
+ *
+ * @return the state value represented by this interval
+ */
+ ITmfStateValue getStateValue();
+
+ /**
+ * Test if this interval intersects another timestamp, inclusively.
+ *
+ * @param timestamp
+ * The target timestamp
+ * @return True if the interval and timestamp intersect, false if they don't
+ */
+ boolean intersects(long timestamp);
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2013, 2014 Ericsson
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.interval;
+
+import java.util.Comparator;
+
+/**
+ * Comparator for ITmfStateInterval, using their *end times*. Making intervals
+ * Comparable wouldn't be clear if it's using their start or end times (or maybe
+ * even values), so separate comparators are provided.
+ *
+ * @author Alexandre Montplaisir
+ */
+public class TmfIntervalEndComparator implements Comparator<ITmfStateInterval> {
+
+ @Override
+ public int compare(ITmfStateInterval o1, ITmfStateInterval o2) {
+ long e1 = o1.getEndTime();
+ long e2 = o2.getEndTime();
+
+ if (e1 < e2) {
+ return -1;
+ } else if (e1 > e2) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2014 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.interval;
+
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
+
+/**
+ * The StateInterval represents the "state" a particular attribute was in, at a
+ * given time. It is the main object being returned from queries to the state
+ * system.
+ *
+ * @author Alexandre Montplaisir
+ */
+public final class TmfStateInterval implements ITmfStateInterval {
+
+ private final long start;
+ private final long end;
+ private final int attribute;
+ private final ITmfStateValue sv;
+
+ /**
+ * Construct an interval from its given parameters
+ *
+ * @param start
+ * Start time
+ * @param end
+ * End time
+ * @param attribute
+ * Attribute linked to this interval
+ * @param sv
+ * State value this interval will contain
+ */
+ public TmfStateInterval(long start, long end, int attribute,
+ ITmfStateValue sv) {
+ this.start = start;
+ this.end = end;
+ this.attribute = attribute;
+ this.sv = sv;
+ }
+
+ @Override
+ public long getStartTime() {
+ return start;
+ }
+
+ @Override
+ public long getEndTime() {
+ return end;
+ }
+
+ @Override
+ public long getViewerEndTime() {
+ return end + 1;
+ }
+
+ @Override
+ public int getAttribute() {
+ return attribute;
+ }
+
+ @Override
+ public ITmfStateValue getStateValue() {
+ return sv;
+ }
+
+ @Override
+ public boolean intersects(long timestamp) {
+ if (start <= timestamp) {
+ if (end >= timestamp) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ /* Only used for debugging */
+ StringBuffer buf = new StringBuffer(start + " to "); //$NON-NLS-1$
+ buf.append(end + ", "); //$NON-NLS-1$
+ buf.append(String.format("key = %4d, ", attribute)); //$NON-NLS-1$
+ buf.append("value = " + sv.toString()); //$NON-NLS-1$
+ return buf.toString();
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2013, 2014 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.statevalue;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
+
+/**
+ * A state value containing a double primitive.
+ *
+ * @author Alexandre Montplaisir
+ */
+final class DoubleStateValue extends TmfStateValue {
+
+ private final double value;
+
+ public DoubleStateValue(double value) {
+ this.value = value;
+ }
+
+ @Override
+ public Type getType() {
+ return Type.DOUBLE;
+ }
+
+ @Override
+ public boolean isNull() {
+ return false;
+ }
+
+ @Override
+ public boolean equals(@Nullable Object object) {
+ if (!(object instanceof DoubleStateValue)) {
+ return false;
+ }
+ DoubleStateValue other = (DoubleStateValue) object;
+ return (Double.compare(this.value, other.value) == 0);
+ }
+
+ @Override
+ public int hashCode() {
+ long bits = Double.doubleToLongBits(value);
+ return ((int) bits) ^ ((int) (bits >>> 32));
+ }
+
+ @Override
+ public @Nullable String toString() {
+ return String.format("%3f", value); //$NON-NLS-1$
+ }
+
+ // ------------------------------------------------------------------------
+ // Unboxing methods
+ // ------------------------------------------------------------------------
+
+ @Override
+ public double unboxDouble() {
+ return value;
+ }
+
+ @Override
+ public int compareTo(@Nullable ITmfStateValue other) {
+ if (other == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (other.getType()) {
+ case INTEGER:
+ double otherDoubleValue = ((IntegerStateValue) other).unboxInt();
+ return Double.compare(this.value, otherDoubleValue);
+ case DOUBLE:
+ otherDoubleValue = ((DoubleStateValue) other).unboxDouble();
+ return Double.compare(this.value, otherDoubleValue);
+ case LONG:
+ otherDoubleValue = ((LongStateValue) other).unboxLong();
+ return Double.compare(this.value, otherDoubleValue);
+ case NULL:
+ return Double.compare(this.value, other.unboxDouble());
+ case STRING:
+ throw new StateValueTypeException("A Double state value cannot be compared to a String state value."); //$NON-NLS-1$
+ default:
+ throw new StateValueTypeException("A Double state value cannot be compared to the type " + other.getType()); //$NON-NLS-1$
+ }
+
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2014 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API
+ ******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.statevalue;
+
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
+
+/**
+ * This is the interface for using state values and reading their contents.
+ *
+ * @author Alexandre Montplaisir
+ */
+public interface ITmfStateValue extends Comparable<ITmfStateValue> {
+
+ /**
+ * The supported types of state values
+ */
+ public enum Type {
+ /** Null value, for an interval not carrying any information */
+ NULL,
+ /** 32-bit integer value */
+ INTEGER,
+ /** 64-bit integer value */
+ LONG,
+ /** IEEE 754 double precision number */
+ DOUBLE,
+ /** Variable-length string value */
+ STRING,
+ }
+
+ /**
+ * Each implementation has to define which one (among the supported types)
+ * they implement. There could be more than one implementation of each type,
+ * depending on the needs of the different users.
+ *
+ * @return The ITmfStateValue.Type enum representing the type of this value
+ */
+ Type getType();
+
+ /**
+ * Only "null values" should return true here
+ *
+ * @return True if this type of SV is considered "null", false if it
+ * contains a real value.
+ */
+ boolean isNull();
+
+ /**
+ * Read the contained value as an 'int' primitive
+ *
+ * @return The integer contained in the state value
+ * @throws StateValueTypeException
+ * If the contained value cannot be read as an integer
+ */
+ int unboxInt();
+
+ /**
+ * Read the contained value as a 'long' primitive
+ *
+ * @return The long contained in the state value
+ * @throws StateValueTypeException
+ * If the contained value cannot be read as a long
+ */
+ long unboxLong();
+
+ /**
+ * Read the contained value as a 'double' primitive
+ *
+ * @return The double contained in the state value
+ * @throws StateValueTypeException
+ * If the contained value cannot be read as a double
+ */
+ double unboxDouble();
+
+ /**
+ * Read the contained value as a String
+ *
+ * @return The String contained in the state value
+ * @throws StateValueTypeException
+ * If the contained value cannot be read as a String
+ */
+ String unboxStr();
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2014 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.statevalue;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
+
+/**
+ * A state value containing a simple integer.
+ *
+ * @version 1.0
+ * @author Alexandre Montplaisir
+ */
+final class IntegerStateValue extends TmfStateValue {
+
+ private final int value;
+
+ public IntegerStateValue(int valueAsInt) {
+ this.value = valueAsInt;
+ }
+
+ @Override
+ public Type getType() {
+ return Type.INTEGER;
+ }
+
+ @Override
+ public boolean isNull() {
+ return false;
+ }
+
+ @Override
+ public boolean equals(@Nullable Object object) {
+ if (!(object instanceof IntegerStateValue)) {
+ return false;
+ }
+ IntegerStateValue other = (IntegerStateValue) object;
+ return (this.value == other.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return value;
+ }
+
+ @Override
+ public @Nullable String toString() {
+ return String.format("%3d", value); //$NON-NLS-1$
+ }
+
+ // ------------------------------------------------------------------------
+ // Unboxing methods
+ // ------------------------------------------------------------------------
+
+ @Override
+ public int unboxInt() {
+ return value;
+ }
+
+ @Override
+ public long unboxLong() {
+ /* It's always safe to up-cast an int into a long */
+ return value;
+ }
+
+ @Override
+ public int compareTo(@Nullable ITmfStateValue other) {
+ if (other == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (other.getType()) {
+ case INTEGER:
+ IntegerStateValue otherIntValue = (IntegerStateValue) other;
+ return Integer.compare(this.value, otherIntValue.value);
+ case DOUBLE:
+ double otherDoubleValue = ((DoubleStateValue) other).unboxDouble();
+ return Double.compare(this.value, otherDoubleValue);
+ case LONG:
+ long otherLongValue = ((LongStateValue) other).unboxLong();
+ return Long.compare(this.value, otherLongValue);
+ case NULL:
+ return Integer.compare(this.value, other.unboxInt());
+ case STRING:
+ throw new StateValueTypeException("An Integer state value cannot be compared to a String state value."); //$NON-NLS-1$
+ default:
+ throw new StateValueTypeException("An Integer state value cannot be compared to the type " + other.getType()); //$NON-NLS-1$
+ }
+
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2013, 2014 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+
+ * Contributors:
+ * François Rajotte - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.statevalue;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
+
+/**
+ * A state value containing a long integer (8 bytes).
+ *
+ * @version 1.0
+ * @author François Rajotte
+ */
+final class LongStateValue extends TmfStateValue {
+
+ private final long value;
+
+ public LongStateValue(long valueAsLong) {
+ this.value = valueAsLong;
+ }
+
+ @Override
+ public Type getType() {
+ return Type.LONG;
+ }
+
+ @Override
+ public boolean isNull() {
+ return false;
+ }
+
+ @Override
+ public boolean equals(@Nullable Object object) {
+ if (!(object instanceof LongStateValue)) {
+ return false;
+ }
+ LongStateValue other = (LongStateValue) object;
+ return (this.value == other.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return ((int) value) ^ ((int) (value >>> 32));
+ }
+
+ @Override
+ public @Nullable String toString() {
+ return String.format("%3d", value); //$NON-NLS-1$
+ }
+
+ // ------------------------------------------------------------------------
+ // Unboxing methods
+ // ------------------------------------------------------------------------
+
+ @Override
+ public long unboxLong() {
+ return value;
+ }
+
+ @Override
+ public int compareTo(@Nullable ITmfStateValue other) {
+ if (other == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (other.getType()) {
+ case INTEGER:
+ long otherLongValue = ((IntegerStateValue) other).unboxInt();
+ return Long.compare(this.value, otherLongValue);
+ case DOUBLE:
+ double otherDoubleValue = ((DoubleStateValue) other).unboxDouble();
+ return Double.compare(this.value, otherDoubleValue);
+ case LONG:
+ otherLongValue = ((LongStateValue) other).unboxLong();
+ return Long.compare(this.value, otherLongValue);
+ case NULL:
+ return Long.compare(this.value, other.unboxLong());
+ case STRING:
+ throw new StateValueTypeException("A Long state value cannot be compared to a String state value."); //$NON-NLS-1$
+ default:
+ throw new StateValueTypeException("A Long state value cannot be compared to the type " + other.getType()); //$NON-NLS-1$
+ }
+
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2014 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.statevalue;
+
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * A state value that contains no particular value. It is sometimes needed over
+ * a "null" reference, since we avoid NPE's this way.
+ *
+ * It can also be read either as a String ("nullValue") or an Integer (-1).
+ *
+ * @version 1.0
+ * @author Alexandre Montplaisir
+ */
+final class NullStateValue extends TmfStateValue {
+
+ private final String value = "nullValue"; //$NON-NLS-1$
+
+ @Override
+ public Type getType() {
+ return Type.NULL;
+ }
+
+ @Override
+ public boolean isNull() {
+ return true;
+ }
+
+ @Override
+ public boolean equals(@Nullable Object object) {
+ return (object instanceof NullStateValue);
+ }
+
+ @Override
+ public int hashCode() {
+ return 0;
+ }
+
+ @Override
+ public String toString() {
+ return value;
+ }
+
+ // ------------------------------------------------------------------------
+ // Unboxing methods. Null values can be unboxed into any type.
+ // ------------------------------------------------------------------------
+
+ @Override
+ public int unboxInt() {
+ return -1;
+ }
+
+ @Override
+ public long unboxLong() {
+ return -1;
+ }
+
+ @Override
+ public double unboxDouble() {
+ return Double.NaN;
+ }
+
+ @Override
+ public String unboxStr() {
+ return value;
+ }
+
+ @Override
+ public int compareTo(@Nullable ITmfStateValue other) {
+ if (other == null) {
+ throw new IllegalArgumentException();
+ }
+ if (other instanceof NullStateValue) {
+ return 0;
+ }
+ /*
+ * For every other state value type, we defer to how that type wants to
+ * be compared against null values.
+ */
+ return -(other.compareTo(this));
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2014 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.statevalue;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
+
+/**
+ * A state value containing a variable-sized string
+ *
+ * @version 1.0
+ * @author Alexandre Montplaisir
+ */
+final class StringStateValue extends TmfStateValue {
+
+ private final String value;
+
+ public StringStateValue(String valueAsString) {
+ this.value = valueAsString;
+ }
+
+ @Override
+ public Type getType() {
+ return Type.STRING;
+ }
+
+ @Override
+ public boolean isNull() {
+ return false;
+ }
+
+ @Override
+ public boolean equals(@Nullable Object object) {
+ if (!(object instanceof StringStateValue)) {
+ return false;
+ }
+ StringStateValue other = (StringStateValue) object;
+ return value.equals(other.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return value;
+ }
+
+ // ------------------------------------------------------------------------
+ // Unboxing methods
+ // ------------------------------------------------------------------------
+
+ @Override
+ public String unboxStr() {
+ return value;
+ }
+
+ @Override
+ public int compareTo(@Nullable ITmfStateValue other) {
+ if (other == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (other.getType()) {
+ case DOUBLE:
+ throw new StateValueTypeException("A String state value cannot be compared to a Double state value."); //$NON-NLS-1$
+ case INTEGER:
+ throw new StateValueTypeException("A String state value cannot be compared to an Integer state value."); //$NON-NLS-1$
+ case LONG:
+ throw new StateValueTypeException("A String state value cannot be compared to a Long state value."); //$NON-NLS-1$
+ case NULL:
+ /*
+ * We assume that every string state value is greater than a null
+ * state value.
+ */
+ return 1;
+ case STRING:
+ StringStateValue otherStringValue = (StringStateValue) other;
+ return value.compareTo(otherStringValue.value);
+ default:
+ throw new StateValueTypeException("A String state value cannot be compared to the type " + other.getType()); //$NON-NLS-1$
+ }
+
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2014 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ ******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.statevalue;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.internal.statesystem.core.Activator;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
+
+/**
+ * This is the wrapper class that exposes the different types of 'state values'
+ * available to use in the State System.
+ *
+ * This also defines how these values are to be stored in the History Tree. For
+ * example, we can save numerical values as integers instead of arrays of
+ * 1-digit characters.
+ *
+ * The available types are Int, Long, Double and String.
+ *
+ * @author Alexandre Montplaisir
+ */
+public abstract class TmfStateValue implements ITmfStateValue {
+
+ // ------------------------------------------------------------------------
+ // State value caches (sizes must be powers of 2)
+ // ------------------------------------------------------------------------
+
+ private static final int INT_CACHE_SIZE = 128;
+ private static final int LONG_CACHE_SIZE = 128;
+ private static final int DOUBLE_CACHE_SIZE = 128;
+
+ private static final IntegerStateValue intCache[] = new IntegerStateValue[INT_CACHE_SIZE];
+ private static final LongStateValue longCache[] = new LongStateValue[LONG_CACHE_SIZE];
+ private static final DoubleStateValue doubleCache[] = new DoubleStateValue[DOUBLE_CACHE_SIZE];
+
+ // ------------------------------------------------------------------------
+ // Factory methods to instantiate new state values
+ // ------------------------------------------------------------------------
+
+ /*
+ * Since all "null state values" are the same, we only need one copy in
+ * memory.
+ */
+ private static TmfStateValue nullValue = new NullStateValue();
+
+ /**
+ * Return an instance of a "null" value. Only one copy exists in memory.
+ *
+ * @return A null value
+ */
+ public static final TmfStateValue nullValue() {
+ return nullValue;
+ }
+
+ /**
+ * Factory constructor for Integer state values
+ *
+ * @param intValue
+ * The integer value to contain
+ * @return The newly-created TmfStateValue object
+ */
+ public static TmfStateValue newValueInt(int intValue) {
+ /* Lookup in cache for the existence of the same value. */
+ int offset = intValue & (INT_CACHE_SIZE - 1);
+ IntegerStateValue cached = intCache[offset];
+ if (cached != null && cached.unboxInt() == intValue) {
+ return cached;
+ }
+
+ /* Not in cache, create a new value and cache it. */
+ IntegerStateValue newValue = new IntegerStateValue(intValue);
+ intCache[offset] = newValue;
+ return newValue;
+ }
+
+ /**
+ * Factory constructor for Long state values
+ *
+ * @param longValue
+ * The long value to contain
+ * @return The newly-created TmfStateValue object
+ */
+ public static TmfStateValue newValueLong(long longValue) {
+ /* Lookup in cache for the existence of the same value. */
+ int offset = (int) longValue & (LONG_CACHE_SIZE - 1);
+ LongStateValue cached = longCache[offset];
+ if (cached != null && cached.unboxLong() == longValue) {
+ return cached;
+ }
+
+ /* Not in cache, create a new value and cache it. */
+ LongStateValue newValue = new LongStateValue(longValue);
+ longCache[offset] = newValue;
+ return newValue;
+ }
+
+ /**
+ * Factory constructor for Double state values
+ *
+ * @param value
+ * The double value to contain
+ * @return The newly-created TmfStateValue object
+ */
+ public static TmfStateValue newValueDouble(double value) {
+ /* Lookup in cache for the existence of the same value. */
+ int offset = (int) Double.doubleToLongBits(value) & (DOUBLE_CACHE_SIZE - 1);
+ DoubleStateValue cached = doubleCache[offset];
+
+ /*
+ * We're using Double.compare() instead of .equals(), because .compare()
+ * works when both values are Double.NaN.
+ */
+ if (cached != null && Double.compare(cached.unboxDouble(), value) == 0) {
+ return cached;
+ }
+
+ /* Not in cache, create a new value and cache it. */
+ DoubleStateValue newValue = new DoubleStateValue(value);
+ doubleCache[offset] = newValue;
+ return newValue;
+ }
+
+ /**
+ * Factory constructor for String state values
+ *
+ * @param strValue
+ * The string value to contain
+ * @return The newly-created TmfStateValue object
+ */
+ public static TmfStateValue newValueString(@Nullable String strValue) {
+ if (strValue == null) {
+ return nullValue();
+ }
+ /*
+ * Make sure the String does not contain "weird" things, like ISO
+ * control characters.
+ */
+ for (char c : strValue.toCharArray()) {
+ if (Character.isISOControl(c)) {
+ Activator.getDefault().logError("Trying to use invalid string: " + strValue); //$NON-NLS-1$
+ throw new IllegalArgumentException();
+ }
+ }
+ return new StringStateValue(strValue);
+ }
+
+ // ------------------------------------------------------------------------
+ // Default unboxing methods.
+ // Subclasses can override those for the types they support.
+ // ------------------------------------------------------------------------
+
+ private String unboxErrMsg(String targetType) {
+ return "Type " + getClass().getSimpleName() + //$NON-NLS-1$
+ " cannot be unboxed into a " + targetType + " value."; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ @Override
+ public int unboxInt() {
+ throw new StateValueTypeException(unboxErrMsg("Int")); //$NON-NLS-1$
+ }
+
+ @Override
+ public long unboxLong() {
+ throw new StateValueTypeException(unboxErrMsg("Long")); //$NON-NLS-1$
+ }
+
+ @Override
+ public double unboxDouble() {
+ throw new StateValueTypeException(unboxErrMsg("Double")); //$NON-NLS-1$
+ }
+
+ @Override
+ public String unboxStr() {
+ throw new StateValueTypeException(unboxErrMsg("String")); //$NON-NLS-1$
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2014 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ericsson - Initial API and implementation
+ *******************************************************************************/
+@org.eclipse.jdt.annotation.NonNullByDefault package org.eclipse.tracecompass.statesystem.core.statevalue;
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2015, Ericsson, EfficiOS Inc. and others
+
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/epl-v10.html
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <parent>
+ <artifactId>org.eclipse.tracecompass</artifactId>
+ <groupId>org.eclipse.tracecompass</groupId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>org.eclipse.tracecompass.statesystem-parent</artifactId>
+ <groupId>org.eclipse.tracecompass</groupId>
+ <version>1.0.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>Trace Compass State System Parent</name>
+
+ <modules>
+ <module>org.eclipse.tracecompass.statesystem.core</module>
+ <module>org.eclipse.tracecompass.statesystem.core.tests</module>
+ </modules>
+
+</project>