- Update LibDataStr Open & Close,

- Make compile dsbench...
This commit is contained in:
Arnaud G. GIBERT 2024-04-22 18:37:50 +02:00
parent ed0f5062df
commit 33be3b6070
5 changed files with 996 additions and 534 deletions

View File

@ -137,7 +137,7 @@ typedef struct {
int Valid; /* Indique si la structure est valide ou non */ int Valid; /* Indique si la structure est valide ou non */
} DST_RootDesc; } DST_RootDesc;
char DS_Error_Msg [512]; //char DS_Error_Msg [512];
/* Définition des alias de l'API */ /* Définition des alias de l'API */

View File

@ -37,6 +37,9 @@
#include <libdatastr.h> #include <libdatastr.h>
//VER_INFO_EXPORT (libdatastr,"$Revision: 1.1 $", "$Name: $",__FILE__,"$Author: smas $") //VER_INFO_EXPORT (libdatastr,"$Revision: 1.1 $", "$Name: $",__FILE__,"$Author: smas $")
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
@ -57,57 +60,69 @@
/* (I) Debug_Mode : mode d'affichage des messages d'erreur */ /* (I) Debug_Mode : mode d'affichage des messages d'erreur */
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
DST_Status DS_Library_Open_I ( int Instance, const char * Context, DST_Flags Debug_Mode ) DST_Status DS_Library_Open_I ( int Instance, const char *Context, DST_Flags Debug_Mode )
{ {
DST_Status rc; DST_Status rc;
int SM_Debug = SMD_DEBUG_NONE; LGT_Status lg_status;
SMT_Status sm_status;
NDT_Status nd_status;
int sm_debug_flag = SMD_DEBUG_NONE;
NDT_Index_Type index_type = ( NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_TREE | NDD_INDEX_SUBTYPE_BALANCED);
/* Définition du mode debug */ /* Définition du mode debug */
if (Debug_Mode & DSD_DEBUG) if( Debug_Mode & DSD_DEBUG)
{ {
DS_stderr = stderr; DS_stderr = stderr;
SM_Debug = SMD_DEBUG; sm_debug_flag = SMD_DEBUG;
} }
else if (Debug_Mode & DSD_DEBUG_ALL) else if( Debug_Mode & DSD_DEBUG_ALL)
{ {
DS_stderr = stderr; DS_stderr = stderr;
SM_Debug = SMD_DEBUG_ALL; sm_debug_flag = SMD_DEBUG_ALL;
} }
if( ( lg_status = LG_Library_Open( LGD_LOG_WRITER_DEFAULT, false)) != LGS_OK)
{
fprintf( stderr, "Can't open LibLog library: (%d)\n", lg_status);
return( -1);
}
/* Ouverture de la librairie LIBSHMEM */ /* Ouverture de la librairie LIBSHMEM */
rc = SM_Library_Open (Instance, Context, SMD_OPEN | SM_Debug); if( ( sm_status = SM_Library_Open( Instance, Context, SMD_OPEN | sm_debug_flag)) != SMS_OK)
if (rc != SMS_OK)
{ {
sprintf (DS_Error_Msg, "Error DS_Library_Open : unable to open the LIBSHMEM library"); LG_LOG_ERROR_1( "Unable to open the LibShMem library: (%d)", sm_status);
DS_Error_Print (); return( DSS_OK);
return rc;
} }
/* /*
Lors de la première ouverture de la librairie LIBDATASTR, Lors de la première ouverture de la librairie LIBDATASTR,
on crée une structure locale permettant de référencer on crée une structure locale permettant de référencer
les data structures ouvertes. les data structures ouvertes.
*/ */
if (DS_Open_Counter == 0) if( DS_Open_Counter == 0)
{ {
rc = ND_DataStruct_Open (&OpenedDS_List, NDD_DS_TREE | NDD_MN_AUTO_EQU, NULL, NULL, NULL, TRUE); if( ( nd_status = ND_DataStruct_Open( &OpenedDS_List, 1, &index_type, "DS_OpenedDS_List_Manager", NULL, NULL, NULL, NULL, NULL, TRUE, NULL)) != NDS_OK)
if (rc != NDS_OK)
{ {
sprintf (DS_Error_Msg, "Error DS_Library_Open : unable to create the opened data structure list"); LG_LOG_ERROR_1( "Unable to create the opened data structure list: (%d)", nd_status);
DS_Error_Print ();
SM_Library_Close (SMD_CLOSE); SM_Library_Close (SMD_CLOSE);
return rc;
return( SMS_KO);
}
else
{
// strcpy( OpenedDS_List->Manager, "DS_OpenedDS_List_Manager");
} }
else strcpy (OpenedDS_List->Manager, "DS_OpenedDS_List_Manager");
} }
DS_Open_Counter++; DS_Open_Counter++;
return DSS_OK; return( DSS_OK);
} }
@ -116,41 +131,45 @@ DST_Status DS_Library_Open_I ( int Instance, const char * Context, DST_Flags Deb
/* Fermeture de l'instance de la librairie */ /* Fermeture de l'instance de la librairie */
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
DST_Status DS_Library_Close_I ( void ) DST_Status DS_Library_Close_I( void)
{ {
DST_Status rc; NDT_Status nd_status;
SMT_Status sm_status;
LGT_Status lg_status;
/* /*
A la dernière fermeture de la librairie LIBDATASTR, on détruit A la dernière fermeture de la librairie LIBDATASTR, on détruit
la structure locale qui référence les data structures ouvertes. la structure locale qui référence les data structures ouvertes.
*/ */
if (DS_Open_Counter == 1) if( DS_Open_Counter == 1)
{ {
rc = ND_DataStruct_Close (OpenedDS_List); if( ( nd_status = ND_DataStruct_Close( OpenedDS_List)) != NDS_OK)
if (rc != NDS_OK)
{ {
sprintf (DS_Error_Msg, "Error DS_Library_Close : unable to close the opened data structure list"); LG_LOG_ERROR_1( "Unable to close the opened data structure list: (%d)", nd_status);
DS_Error_Print (); return( DSS_KO);
if (DS_ERROR(rc)) return rc;
} }
} }
/* Fermeture de la librairie LIBSHMEM */ /* Fermeture de la librairie LIBSHMEM */
rc = SM_Library_Close (SMD_CLOSE); if( ( sm_status = SM_Library_Close( SMD_CLOSE)) != SMS_OK)
if (rc != SMS_OK)
{ {
sprintf (DS_Error_Msg, "Error DS_Library_Close : unable to close the LIBSHMEM library"); LG_LOG_ERROR_1( "Unable to close the LibShMem library: (%d)", sm_status);
DS_Error_Print (); return( DSS_KO);
if (DS_ERROR(rc)) return rc;
} }
DS_Open_Counter--; DS_Open_Counter--;
return rc; if( ( lg_status = LG_Library_Close( false)) != LGS_OK)
{
fprintf( stderr, "Can't close LibLog library: (%d)\n", lg_status);
return( DSS_KO);
}
return( DSS_OK);
} }
@ -161,10 +180,11 @@ DST_Status DS_Library_Close_I ( void )
/* (I) Out : flux de sortie des messages d'erreur */ /* (I) Out : flux de sortie des messages d'erreur */
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
DST_Status DS_Library_Stderr_Set_I ( FILE * Out ) DST_Status DS_Library_Stderr_Set_I( FILE *Out)
{ {
DS_stderr = Out; DS_stderr = Out;
return DSS_OK;
return( DSS_OK);
} }
@ -180,10 +200,8 @@ DST_Status DS_Library_Stderr_Set_I ( FILE * Out )
/* (I) Open_Mode : mode d'ouverture de la structure */ /* (I) Open_Mode : mode d'ouverture de la structure */
/* (I) Own_Values : indique si la structure possède ses valeurs */ /* (I) Own_Values : indique si la structure possède ses valeurs */
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
/*
DST_Status DS_DataStruct_Open_I ( const char * DS_Name, NDT_Root ** Root, \ DST_Status DS_DataStruct_Open_I( const char *DS_Name, NDT_Root **Root, NDT_DataStruct_Type Type, const char *Manager_FileName, size_t Segment_Size, DST_Flags Open_Mode, int Own_Values)
NDT_DataStruct_Type Type, const char * Manager_FileName, \
size_t Segment_Size, DST_Flags Open_Mode, int Own_Values )
{ {
DST_Status rc; DST_Status rc;
SMT_Heap * Heap; SMT_Heap * Heap;
@ -197,7 +215,7 @@ DST_Status DS_DataStruct_Open_I ( const char * DS_Name, NDT_Root ** Root, \
*Root = NULL; *Root = NULL;
/* On définit ce qu'on va faire en fonction du mode d'ouverture demandé et de ce qui existe déjà ou non */ /* On définit ce qu'on va faire en fonction du mode d'ouverture demandé et de ce qui existe déjà ou non */
/*
if (SM_Heap_Exist (Prefixed_Name) == SMS_YES) if (SM_Heap_Exist (Prefixed_Name) == SMS_YES)
{ {
if (DSD_MSK_OPEN (Open_Mode)) Mode = 2; if (DSD_MSK_OPEN (Open_Mode)) Mode = 2;
@ -226,7 +244,7 @@ DST_Status DS_DataStruct_Open_I ( const char * DS_Name, NDT_Root ** Root, \
/*--------------- Création d'une nouvelle data structure dans un heap existant -------------*/ /*--------------- Création d'une nouvelle data structure dans un heap existant -------------*/
/* Ouverture du heap en écriture */ /* Ouverture du heap en écriture */
/*
rc = SM_Heap_Open (Prefixed_Name, &Heap, 0, SMD_OPEN | SMD_WRITE, &Locked); rc = SM_Heap_Open (Prefixed_Name, &Heap, 0, SMD_OPEN | SMD_WRITE, &Locked);
if (rc != SMS_OK) if (rc != SMS_OK)
{ {
@ -237,7 +255,7 @@ DST_Status DS_DataStruct_Open_I ( const char * DS_Name, NDT_Root ** Root, \
} }
/* Création de la node structure */ /* Création de la node structure */
/*
Tmp_RootDesc.Heap_Name = Prefixed_Name; Tmp_RootDesc.Heap_Name = Prefixed_Name;
rc = ND_DataStruct_Open (Root, Type, "DS_DataStruct_Alloc", "DS_DataStruct_Free", &Tmp_RootDesc, Own_Values); rc = ND_DataStruct_Open (Root, Type, "DS_DataStruct_Alloc", "DS_DataStruct_Free", &Tmp_RootDesc, Own_Values);
@ -253,7 +271,7 @@ DST_Status DS_DataStruct_Open_I ( const char * DS_Name, NDT_Root ** Root, \
} }
/* Allocation de mémoire pour la description de la nouvelle data structure */ /* Allocation de mémoire pour la description de la nouvelle data structure */
/*
rc = DS_DataStruct_Alloc (sizeof (DST_RootDesc) + strlen (Prefixed_Name) + strlen (Manager_FileName) + 2, (void **)(&RootDesc), &Tmp_RootDesc); rc = DS_DataStruct_Alloc (sizeof (DST_RootDesc) + strlen (Prefixed_Name) + strlen (Manager_FileName) + 2, (void **)(&RootDesc), &Tmp_RootDesc);
if (rc != DSS_OK) if (rc != DSS_OK)
{ {
@ -274,21 +292,21 @@ DST_Status DS_DataStruct_Open_I ( const char * DS_Name, NDT_Root ** Root, \
strcpy (RootDesc->Manager_FileName, Manager_FileName); strcpy (RootDesc->Manager_FileName, Manager_FileName);
/* On indique que la structure n'est pas propriétaire de son heap */ /* On indique que la structure n'est pas propriétaire de son heap */
/*
RootDesc->Heap_Owner = FALSE; RootDesc->Heap_Owner = FALSE;
/*
/* On indique que la structure est valide */ /* On indique que la structure est valide */
/*
RootDesc->Valid = TRUE; RootDesc->Valid = TRUE;
/*
/* On rattache la desription de la data structure à la racine */ /* On rattache la desription de la data structure à la racine */
/*
(*Root)->User = RootDesc; (*Root)->User = RootDesc;
/* Pour une telle data structure, on ne crée pas de sémaphore d'ouverture */ /* Pour une telle data structure, on ne crée pas de sémaphore d'ouverture */
/* Déverrouillage du heap */ /* Déverrouillage du heap */
/*
if (Locked == TRUE) if (Locked == TRUE)
{ {
rc = SM_Heap_Unlock (Heap); rc = SM_Heap_Unlock (Heap);
@ -309,13 +327,13 @@ DST_Status DS_DataStruct_Open_I ( const char * DS_Name, NDT_Root ** Root, \
/*--------------- Ouverture d'une data structure existante ------------------*/ /*--------------- Ouverture d'une data structure existante ------------------*/
/* Si la structure a déjà été ouverte, on ne recommence pas */ /* Si la structure a déjà été ouverte, on ne recommence pas */
/*
rc = DS_DataStruct_IsOpen (DS_Name, Root); rc = DS_DataStruct_IsOpen (DS_Name, Root);
if (rc == DSS_YES) return DSS_OK; if (rc == DSS_YES) return DSS_OK;
else if (DS_ERROR(rc)) return rc; else if (DS_ERROR(rc)) return rc;
/* Accès au heap sous-jacent en lecture */ /* Accès au heap sous-jacent en lecture */
/*
rc = SM_Heap_Open (Prefixed_Name, &Heap, 0, SMD_OPEN | SMD_READ, &Locked); rc = SM_Heap_Open (Prefixed_Name, &Heap, 0, SMD_OPEN | SMD_READ, &Locked);
if (rc != SMS_OK) if (rc != SMS_OK)
{ {
@ -327,11 +345,11 @@ DST_Status DS_DataStruct_Open_I ( const char * DS_Name, NDT_Root ** Root, \
DSH = Heap->MHH->DSR->Head->Value; DSH = Heap->MHH->DSR->Head->Value;
/* La racine de la structure se trouve dans le premier chunk du premier segment du heap */ /* La racine de la structure se trouve dans le premier chunk du premier segment du heap */
/*
*Root = ( NDT_Root *)((size_t)(DSH->Start) + sizeof (NDT_Node) + sizeof (SMT_Chunk)); *Root = ( NDT_Root *)((size_t)(DSH->Start) + sizeof (NDT_Node) + sizeof (SMT_Chunk));
/* Chargement des fonctions manager de la structure */ /* Chargement des fonctions manager de la structure */
/*
RootDesc = (*Root)->User; RootDesc = (*Root)->User;
if (!RootDesc) if (!RootDesc)
@ -357,7 +375,7 @@ DST_Status DS_DataStruct_Open_I ( const char * DS_Name, NDT_Root ** Root, \
case 3: case 3:
/*--------------- Création d'une nouvelle structure de données dans un nouveau heap -----------------*/ /*--------------- Création d'une nouvelle structure de données dans un nouveau heap -----------------*/
/*
if (!Manager_FileName) if (!Manager_FileName)
{ {
sprintf (DS_Error_Msg, "Error DS_DataStruct_Open : the manager file name (.so) is undefined"); sprintf (DS_Error_Msg, "Error DS_DataStruct_Open : the manager file name (.so) is undefined");
@ -366,7 +384,7 @@ DST_Status DS_DataStruct_Open_I ( const char * DS_Name, NDT_Root ** Root, \
} }
/* Création d'un nouveau heap */ /* Création d'un nouveau heap */
/*
rc = SM_Heap_Open (Prefixed_Name, &Heap, Segment_Size, SMD_CREATE | SMD_WRITE, &Locked); rc = SM_Heap_Open (Prefixed_Name, &Heap, Segment_Size, SMD_CREATE | SMD_WRITE, &Locked);
if (rc != SMS_OK) if (rc != SMS_OK)
{ {
@ -376,7 +394,7 @@ DST_Status DS_DataStruct_Open_I ( const char * DS_Name, NDT_Root ** Root, \
} }
/* Création de la structure de données dans le heap */ /* Création de la structure de données dans le heap */
/*
Tmp_RootDesc.Heap_Name = Prefixed_Name; Tmp_RootDesc.Heap_Name = Prefixed_Name;
rc = ND_DataStruct_Open (Root, Type, "DS_DataStruct_Alloc", "DS_DataStruct_Free", &Tmp_RootDesc, Own_Values); rc = ND_DataStruct_Open (Root, Type, "DS_DataStruct_Alloc", "DS_DataStruct_Free", &Tmp_RootDesc, Own_Values);
@ -390,7 +408,7 @@ DST_Status DS_DataStruct_Open_I ( const char * DS_Name, NDT_Root ** Root, \
} }
/* Allocation de mémoire pour la description de la structure */ /* Allocation de mémoire pour la description de la structure */
/*
rc = DS_DataStruct_Alloc (sizeof (DST_RootDesc) + strlen (Prefixed_Name) + strlen (Manager_FileName) + 2, (void **)(&RootDesc), &Tmp_RootDesc); rc = DS_DataStruct_Alloc (sizeof (DST_RootDesc) + strlen (Prefixed_Name) + strlen (Manager_FileName) + 2, (void **)(&RootDesc), &Tmp_RootDesc);
if (rc != DSS_OK) if (rc != DSS_OK)
{ {
@ -408,19 +426,19 @@ DST_Status DS_DataStruct_Open_I ( const char * DS_Name, NDT_Root ** Root, \
strcpy (RootDesc->Manager_FileName, Manager_FileName); strcpy (RootDesc->Manager_FileName, Manager_FileName);
/* On indique que la structure est propriétaire du heap */ /* On indique que la structure est propriétaire du heap */
/*
RootDesc->Heap_Owner = TRUE; RootDesc->Heap_Owner = TRUE;
/* On indique que la structure est valide */ /* On indique que la structure est valide */
/*
RootDesc->Valid = TRUE; RootDesc->Valid = TRUE;
/* On rattache la desription de la data structure à la racine */ /* On rattache la desription de la data structure à la racine */
/*
(*Root)->User = RootDesc; (*Root)->User = RootDesc;
/* On crée un sémaphore pour compter le nombre de processus qui ouvrent la structure */ /* On crée un sémaphore pour compter le nombre de processus qui ouvrent la structure */
/*
rc = DS_Semaphore_Create (*Root); rc = DS_Semaphore_Create (*Root);
if (rc != DSS_OK) if (rc != DSS_OK)
{ {
@ -438,7 +456,7 @@ DST_Status DS_DataStruct_Open_I ( const char * DS_Name, NDT_Root ** Root, \
} }
/* On incrémente le sémaphore qui compte le nombre de processus qui ouvrent la structure */ /* On incrémente le sémaphore qui compte le nombre de processus qui ouvrent la structure */
/*
rc = DS_Semaphore_Operate (RootDesc->OpenSemID, DS_SemOp_Open, 1); rc = DS_Semaphore_Operate (RootDesc->OpenSemID, DS_SemOp_Open, 1);
if (rc != DSS_OK) if (rc != DSS_OK)
{ {
@ -460,7 +478,7 @@ DST_Status DS_DataStruct_Open_I ( const char * DS_Name, NDT_Root ** Root, \
} }
/* On ajoute la data structure à la liste des structures ouvertes par le processus courant */ /* On ajoute la data structure à la liste des structures ouvertes par le processus courant */
/*
Opened_DataStruct = (DST_DataStruct *)malloc (sizeof (DST_DataStruct)); Opened_DataStruct = (DST_DataStruct *)malloc (sizeof (DST_DataStruct));
Opened_DataStruct->Name = strdup (DS_Name); Opened_DataStruct->Name = strdup (DS_Name);
Opened_DataStruct->Root = *Root; Opened_DataStruct->Root = *Root;
@ -486,7 +504,7 @@ DST_Status DS_DataStruct_Open_I ( const char * DS_Name, NDT_Root ** Root, \
} }
/* Déverrouillage du heap */ /* Déverrouillage du heap */
/*
if (Locked == TRUE) if (Locked == TRUE)
{ {
rc = SM_Heap_Unlock (Heap); rc = SM_Heap_Unlock (Heap);
@ -515,6 +533,9 @@ DST_Status DS_DataStruct_Open_I ( const char * DS_Name, NDT_Root ** Root, \
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
/* Verrouillage d'une structure de données */ /* Verrouillage d'une structure de données */
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
@ -1533,22 +1554,24 @@ DST_Status DS_Value_Free_I ( NDT_Root * Root, void * Value )
/* (I) Size : taille mémoire à allouer */ /* (I) Size : taille mémoire à allouer */
/* (O) Ptr : adresse du pointeur sur la zone de données allouée */ /* (O) Ptr : adresse du pointeur sur la zone de données allouée */
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
/*
DST_Status DS_Alloc_I ( NDT_Root * Root, size_t Size, void ** Ptr ) DST_Status DS_Alloc_I( NDT_Root *Root, size_t Size, void **Ptr)
{ {
return DS_DataStruct_Alloc (Size, Ptr, Root->User); // return DS_DataStruct_Alloc (Size, Ptr, Root->User);
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
/* Désallocation d'une ressource pour une structure de données : */ /* Désallocation d'une ressource pour une structure de données : */
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de données */ /* (I) Root : pointeur sur la racine de la structure de données */
/* (I) Ptr : pointeur sur la zone à désallouer */ /* (I) Ptr : pointeur sur la zone à désallouer */
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
/*
DST_Status DS_Free_I ( NDT_Root * Root, void * Ptr ) DST_Status DS_Free_I( NDT_Root *Root, void *Ptr)
{ {
return DS_DataStruct_Free (Ptr, Root->User); // return DS_DataStruct_Free (Ptr, Root->User);
} }
@ -3197,3 +3220,4 @@ NDT_Status DS_OpenedDS_List_Manager ( va_list Args )
return NDS_OK; return NDS_OK;
} }
*/

View File

@ -41,6 +41,21 @@
#include <node.h> #include <node.h>
#include <datastr.h> #include <datastr.h>
/*----------------------------------------------------------------------------*/
/* Definitions */
/*----------------------------------------------------------------------------*/
#define LGD_MODULE_NAME "ds"
extern char * strdup ( const char * ); extern char * strdup ( const char * );
/* Compteur d'ouverture de la librairie */ /* Compteur d'ouverture de la librairie */

View File

@ -11,11 +11,11 @@ include ../Makefile.rule
DEP_STATIC += ../lib/libdatastr.a ../../libshmem/lib/libshmem.a ../../libnode/lib/libnode.a ../../liblog/lib/liblog.a DEP_STATIC += ../lib/libdatastr.a ../../libshmem/lib/libshmem.a ../../libnode/lib/libnode.a ../../liblog/lib/liblog.a
DEP_DYNAMIC += ../lib/libdatastr.so ../lib/libnode.so ../../liblog/lib/liblog.so DEP_DYNAMIC += ../lib/libdatastr.so ../../libshmem/lib/libshmem.so ../../libnode/lib/libnode.so ../../liblog/lib/liblog.so
INCLUDE += -I . -I ../include -I ../../liblog/include -I ../../libnode/include -I ../../libshmem/include INCLUDE += -I . -I ../include -I ../../liblog/include -I ../../libnode/include -I ../../libshmem/include
LIBDIR += -L . -L ../lib -L ../../liblog/lib -L ../../libnode/lib -L ../../libshmem/lib LIBDIR += -L . -L ../lib -L ../../liblog/lib -L ../../libnode/lib -L ../../libshmem/lib
LIB_STATIC += ../lib/libdatastr.a ../../libshmem/lib/libshmem.a ../../libnode/lib/libnode.a ../../liblog/lib/liblog.a -ldl LIB_STATIC += ../lib/libdatastr.a ../../libshmem/lib/libshmem.a ../../libnode/lib/libnode.a ../../liblog/lib/liblog.a -ldl
LIB_DYNAMIC += -ldatastr -lshmem -lnode -llog -ldl LIB_DYNAMIC += -ldatastr -lshmem -lnode -llog -ldl
CFLAGS += -rdynamic CFLAGS += -rdynamic

File diff suppressed because it is too large Load Diff