Optimized Git Object Handling (#1734)

* Optimized git object handling

- Introduced secondary indices for ZIF_ABAPGIT_DEFINITIONS=>TY_OBJECTS_TT to allow fast access to git objects by SHA1 and TYPE
- Added a new column INDEX to ZIF_ABAPGIT_DEFINITIONS=>TY_OBJECT to allow reconstruction of the correct sort order of git objects when after processing in ZCL_ABAPGIT_GIT_PACK
- Optimized git object accesses in ZCL_ABAPGIT_GIT_PACK, ZCL_ABAPGIT_GIT_PORCELAIN and ZCL_ABAPGIT_MERGE by using the newly introduced indices

* Removed excess fields

Removed excess fields from secondary index definitions of ´ty_objects_tt´, since they are not required.
This commit is contained in:
Michael Käsemann 2018-08-07 07:20:52 +02:00 committed by Lars Hvam
parent 8e556701c3
commit 8d51e6eb34
4 changed files with 81 additions and 32 deletions

View File

@ -167,7 +167,7 @@ CLASS ZCL_ABAPGIT_GIT_PACK IMPLEMENTATION.
lv_xstring TYPE xstring,
lv_expected TYPE i,
ls_object LIKE LINE OF rt_objects.
DATA: uindex TYPE sy-index.
lv_data = iv_data.
@ -191,6 +191,8 @@ CLASS ZCL_ABAPGIT_GIT_PACK IMPLEMENTATION.
DO lv_objects TIMES.
uindex = sy-index.
lv_x = lv_data(1).
lv_type = get_type( lv_x ).
@ -262,6 +264,7 @@ CLASS ZCL_ABAPGIT_GIT_PACK IMPLEMENTATION.
ENDIF.
ls_object-type = lv_type.
ls_object-data = lv_decompressed.
ls_object-index = uindex.
APPEND ls_object TO rt_objects.
ENDDO.
@ -335,11 +338,19 @@ CLASS ZCL_ABAPGIT_GIT_PACK IMPLEMENTATION.
lt_deltas LIKE ct_objects.
LOOP AT ct_objects INTO ls_object WHERE type = zif_abapgit_definitions=>gc_type-ref_d.
DELETE ct_objects INDEX sy-tabix.
APPEND ls_object TO lt_deltas.
LOOP AT ct_objects INTO ls_object
USING KEY type
WHERE type = zif_abapgit_definitions=>gc_type-ref_d.
INSERT ls_object INTO TABLE lt_deltas.
ENDLOOP.
DELETE ct_objects
USING KEY type
WHERE type = zif_abapgit_definitions=>gc_type-ref_d.
"Restore correct Delta Order
SORT lt_deltas BY index.
CREATE OBJECT lo_progress
EXPORTING
iv_total = lines( lt_deltas ).
@ -498,7 +509,8 @@ CLASS ZCL_ABAPGIT_GIT_PACK IMPLEMENTATION.
lv_delta = is_object-data.
* find base
READ TABLE ct_objects ASSIGNING <ls_object> WITH KEY sha1 = is_object-sha1.
READ TABLE ct_objects ASSIGNING <ls_object>
WITH KEY sha COMPONENTS sha1 = is_object-sha1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Base not found, { is_object-sha1 }| ).
ELSEIF <ls_object>-type = zif_abapgit_definitions=>gc_type-ref_d.
@ -572,6 +584,7 @@ CLASS ZCL_ABAPGIT_GIT_PACK IMPLEMENTATION.
ls_object-sha1 = lv_sha1.
ls_object-type = <ls_object>-type.
ls_object-data = lv_result.
ls_object-index = <ls_object>-index. "Retain sort index
APPEND ls_object TO ct_objects.
ENDMETHOD.

View File

@ -378,7 +378,10 @@ CLASS ZCL_ABAPGIT_GIT_PORCELAIN IMPLEMENTATION.
ls_commit TYPE zcl_abapgit_git_pack=>ty_commit.
READ TABLE it_objects INTO ls_object WITH KEY sha1 = iv_branch type = zif_abapgit_definitions=>gc_type-commit.
READ TABLE it_objects INTO ls_object
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>gc_type-commit
sha1 = iv_branch .
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'commit not found' ).
ENDIF.
@ -411,7 +414,10 @@ CLASS ZCL_ABAPGIT_GIT_PORCELAIN IMPLEMENTATION.
ev_branch = ev_branch
eo_branch_list = eo_branch_list ).
READ TABLE et_objects INTO ls_object WITH KEY sha1 = ev_branch type = zif_abapgit_definitions=>gc_type-commit.
READ TABLE et_objects INTO ls_object
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>gc_type-commit
sha1 = ev_branch .
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Commit/branch not found' ).
ENDIF.
@ -542,6 +548,7 @@ CLASS ZCL_ABAPGIT_GIT_PORCELAIN IMPLEMENTATION.
ls_object-sha1 = lv_new_tag_sha1.
ls_object-type = zif_abapgit_definitions=>gc_type-tag.
ls_object-data = lv_tag.
ls_object-index = 1.
APPEND ls_object TO lt_objects.
lv_pack = zcl_abapgit_git_pack=>encode( lt_objects ).
@ -558,11 +565,12 @@ CLASS ZCL_ABAPGIT_GIT_PORCELAIN IMPLEMENTATION.
METHOD receive_pack_push.
DATA: lv_time TYPE zcl_abapgit_time=>ty_unixtime,
lv_commit TYPE xstring,
lv_pack TYPE xstring,
ls_object LIKE LINE OF et_new_objects,
ls_commit TYPE zcl_abapgit_git_pack=>ty_commit.
DATA: lv_time TYPE zcl_abapgit_time=>ty_unixtime,
lv_commit TYPE xstring,
lv_pack TYPE xstring,
ls_object LIKE LINE OF lt_objects,
ls_commit TYPE zcl_abapgit_git_pack=>ty_commit.
DATA: uindex TYPE sy-index.
FIELD-SYMBOLS: <ls_tree> LIKE LINE OF it_trees,
<ls_blob> LIKE LINE OF it_blobs.
@ -599,7 +607,10 @@ CLASS ZCL_ABAPGIT_GIT_PORCELAIN IMPLEMENTATION.
CLEAR ls_object.
ls_object-sha1 = <ls_tree>-sha1.
READ TABLE et_new_objects WITH KEY type = zif_abapgit_definitions=>gc_type-tree sha1 = ls_object-sha1
READ TABLE et_new_objects
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>gc_type-tree
sha1 = ls_object-sha1
TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
* two identical trees added at the same time, only add one to the pack
@ -608,6 +619,8 @@ CLASS ZCL_ABAPGIT_GIT_PORCELAIN IMPLEMENTATION.
ls_object-type = zif_abapgit_definitions=>gc_type-tree.
ls_object-data = <ls_tree>-data.
uindex = uindex + 1.
ls_object-index = uindex.
APPEND ls_object TO et_new_objects.
ENDLOOP.
@ -617,9 +630,10 @@ CLASS ZCL_ABAPGIT_GIT_PORCELAIN IMPLEMENTATION.
iv_type = zif_abapgit_definitions=>gc_type-blob
iv_data = <ls_blob>-data ).
READ TABLE et_new_objects WITH KEY
type = zif_abapgit_definitions=>gc_type-blob
sha1 = ls_object-sha1
READ TABLE et_new_objects
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>gc_type-blob
sha1 = ls_object-sha1
TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
* two identical files added at the same time, only add one blob to the pack
@ -629,6 +643,8 @@ CLASS ZCL_ABAPGIT_GIT_PORCELAIN IMPLEMENTATION.
ls_object-type = zif_abapgit_definitions=>gc_type-blob.
ASSERT NOT <ls_blob>-data IS INITIAL.
ls_object-data = <ls_blob>-data.
uindex = uindex + 1.
ls_object-index = uindex.
APPEND ls_object TO et_new_objects.
ENDLOOP.
@ -661,7 +677,10 @@ CLASS ZCL_ABAPGIT_GIT_PORCELAIN IMPLEMENTATION.
<ls_node> LIKE LINE OF lt_nodes.
READ TABLE it_objects ASSIGNING <ls_tree> WITH KEY sha1 = iv_sha1 type = zif_abapgit_definitions=>gc_type-tree.
READ TABLE it_objects ASSIGNING <ls_tree>
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>gc_type-tree
sha1 = iv_sha1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Walk, tree not found' ).
ENDIF.
@ -671,7 +690,9 @@ CLASS ZCL_ABAPGIT_GIT_PORCELAIN IMPLEMENTATION.
LOOP AT lt_nodes ASSIGNING <ls_node>.
IF <ls_node>-chmod = zif_abapgit_definitions=>gc_chmod-file.
READ TABLE it_objects ASSIGNING <ls_blob>
WITH KEY sha1 = <ls_node>-sha1 type = zif_abapgit_definitions=>gc_type-blob.
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>gc_type-blob
sha1 = <ls_node>-sha1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Walk, blob not found' ).
ENDIF.
@ -707,8 +728,9 @@ CLASS ZCL_ABAPGIT_GIT_PORCELAIN IMPLEMENTATION.
READ TABLE it_objects INTO ls_object
WITH KEY sha1 = iv_tree
type = zif_abapgit_definitions=>gc_type-tree.
WITH key type COMPONENTS
type = zif_abapgit_definitions=>gc_type-tree
sha1 = iv_tree.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'tree not found' ).
ENDIF.

View File

@ -90,8 +90,9 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION.
DEFINE _from_source.
READ TABLE mt_objects ASSIGNING <ls_object>
WITH KEY type = zif_abapgit_definitions=>gc_type-blob
sha1 = <ls_source>-sha1.
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>gc_type-blob
sha1 = <ls_source>-sha1.
ASSERT sy-subrc = 0.
ms_merge-stage->add( iv_path = <ls_file>-path
@ -176,13 +177,17 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION.
<ls_conflict>-path = <ls_file>-path.
<ls_conflict>-filename = <ls_file>-name.
<ls_conflict>-source_sha1 = <ls_source>-sha1.
READ TABLE mt_objects ASSIGNING <ls_object> WITH KEY type = zif_abapgit_definitions=>gc_type-blob
sha1 = <ls_source>-sha1.
READ TABLE mt_objects ASSIGNING <ls_object>
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>gc_type-blob
sha1 = <ls_source>-sha1.
<ls_conflict>-source_data = <ls_object>-data.
<ls_conflict>-target_sha1 = <ls_target>-sha1.
READ TABLE mt_objects ASSIGNING <ls_object> WITH KEY type = zif_abapgit_definitions=>gc_type-blob
sha1 = <ls_target>-sha1.
READ TABLE mt_objects ASSIGNING <ls_object>
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>gc_type-blob
sha1 = <ls_target>-sha1.
<ls_conflict>-target_data = <ls_object>-data.
* added in source and target, but different, merge conflict must be resolved
@ -214,13 +219,17 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION.
<ls_conflict>-path = <ls_file>-path.
<ls_conflict>-filename = <ls_file>-name.
<ls_conflict>-source_sha1 = <ls_source>-sha1.
READ TABLE mt_objects ASSIGNING <ls_object> WITH KEY type = zif_abapgit_definitions=>gc_type-blob
sha1 = <ls_source>-sha1.
READ TABLE mt_objects ASSIGNING <ls_object>
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>gc_type-blob
sha1 = <ls_source>-sha1.
<ls_conflict>-source_data = <ls_object>-data.
<ls_conflict>-target_sha1 = <ls_target>-sha1.
READ TABLE mt_objects ASSIGNING <ls_object> WITH KEY type = zif_abapgit_definitions=>gc_type-blob
sha1 = <ls_target>-sha1.
READ TABLE mt_objects ASSIGNING <ls_object>
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>gc_type-blob
sha1 = <ls_target>-sha1.
<ls_conflict>-target_data = <ls_object>-data.
ms_merge-conflict = |{ <ls_file>-name } merge conflict, changed in source and target branch|.
@ -293,7 +302,9 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION.
LOOP AT lt_visit INTO lv_commit.
READ TABLE mt_objects ASSIGNING <ls_object>
WITH KEY type = zif_abapgit_definitions=>gc_type-commit sha1 = lv_commit.
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>gc_type-commit
sha1 = lv_commit.
ASSERT sy-subrc = 0.
ls_commit = zcl_abapgit_git_pack=>decode_commit( <ls_object>-data ).

View File

@ -172,9 +172,12 @@ INTERFACE zif_abapgit_definitions PUBLIC.
type TYPE zif_abapgit_definitions=>ty_type,
data TYPE xstring,
adler32 TYPE ty_adler32,
index TYPE i,
END OF ty_object .
TYPES:
ty_objects_tt TYPE STANDARD TABLE OF ty_object WITH DEFAULT KEY .
ty_objects_tt TYPE STANDARD TABLE OF ty_object WITH DEFAULT KEY
WITH NON-UNIQUE SORTED KEY sha COMPONENTS sha1
WITH NON-UNIQUE SORTED KEY type COMPONENTS type sha1.
TYPES:
BEGIN OF ty_tadir,
pgmid TYPE tadir-pgmid,