forked from HDFGroup/hdf5
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathH5Cprivate.h
2249 lines (2187 loc) · 101 KB
/
H5Cprivate.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the LICENSE file, which can be found at the root of the source code *
* distribution tree, or in https://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* [email protected]. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*-------------------------------------------------------------------------
*
* Created: H5Cprivate.h
*
* Purpose: Constants and typedefs available to the rest of the
* library.
*
*-------------------------------------------------------------------------
*/
#ifndef H5Cprivate_H
#define H5Cprivate_H
#include "H5Cpublic.h" /* public prototypes */
/* Private headers needed by this header */
#include "H5private.h" /* Generic Functions */
#include "H5Fprivate.h" /* File access */
/**************************/
/* Library Private Macros */
/**************************/
/* Cache configuration settings */
#define H5C__MAX_NUM_TYPE_IDS 30
#define H5C__PREFIX_LEN 32
/* This sanity checking constant was picked out of the air. Increase
* or decrease it if appropriate. Its purposes is to detect corrupt
* object sizes, so it probably doesn't matter if it is a bit big.
*/
#define H5C_MAX_ENTRY_SIZE ((size_t)(32 * 1024 * 1024))
#ifdef H5_HAVE_PARALLEL
/* we must maintain the clean and dirty LRU lists when we are compiled
* with parallel support.
*/
#define H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS 1
#else /* H5_HAVE_PARALLEL */
/* The clean and dirty LRU lists don't buy us anything here -- we may
* want them on for testing on occasion, but in general they should be
* off.
*/
#define H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS 0
#endif /* H5_HAVE_PARALLEL */
/* Flags for cache client class behavior */
#define H5C__CLASS_NO_FLAGS_SET ((unsigned)0x0)
#define H5C__CLASS_SPECULATIVE_LOAD_FLAG ((unsigned)0x1)
/* The following flags may only appear in test code */
#define H5C__CLASS_SKIP_READS ((unsigned)0x2)
#define H5C__CLASS_SKIP_WRITES ((unsigned)0x4)
/* Flags for pre-serialize callback */
#define H5C__SERIALIZE_NO_FLAGS_SET ((unsigned)0)
#define H5C__SERIALIZE_RESIZED_FLAG ((unsigned)0x1)
#define H5C__SERIALIZE_MOVED_FLAG ((unsigned)0x2)
/* Upper and lower limits on cache size. These limits are picked
* out of a hat -- you should be able to change them as necessary.
*
* However, if you need a very big cache, you should also increase the
* size of the hash table (H5C__HASH_TABLE_LEN in H5Cpkg.h). The current
* upper bound on cache size is rather large for the current hash table
* size.
*/
#define H5C__MAX_MAX_CACHE_SIZE ((size_t)(128 * 1024 * 1024))
#define H5C__MIN_MAX_CACHE_SIZE ((size_t)(1024))
/* Default max cache size and min clean size are give here to make
* them generally accessible.
*/
#define H5C__DEFAULT_MAX_CACHE_SIZE ((size_t)(4 * 1024 * 1024))
#define H5C__DEFAULT_MIN_CLEAN_SIZE ((size_t)(2 * 1024 * 1024))
/* Cache configuration validation definitions */
#define H5C_RESIZE_CFG__VALIDATE_GENERAL 0x1
#define H5C_RESIZE_CFG__VALIDATE_INCREMENT 0x2
#define H5C_RESIZE_CFG__VALIDATE_DECREMENT 0x4
#define H5C_RESIZE_CFG__VALIDATE_INTERACTIONS 0x8
/* clang-format off */
#define H5C_RESIZE_CFG__VALIDATE_ALL \
( \
H5C_RESIZE_CFG__VALIDATE_GENERAL | \
H5C_RESIZE_CFG__VALIDATE_INCREMENT | \
H5C_RESIZE_CFG__VALIDATE_DECREMENT | \
H5C_RESIZE_CFG__VALIDATE_INTERACTIONS \
)
/* clang-format on */
/* Cache configuration versions */
#define H5C__CURR_AUTO_SIZE_CTL_VER 1
#define H5C__CURR_AUTO_RESIZE_RPT_FCN_VER 1
#define H5C__CURR_CACHE_IMAGE_CTL_VER 1
/* Default configuration settings */
#define H5C__DEF_AR_UPPER_THRESHHOLD 0.9999
#define H5C__DEF_AR_LOWER_THRESHHOLD 0.9
#define H5C__DEF_AR_MAX_SIZE ((size_t)(16 * 1024 * 1024))
#define H5C__DEF_AR_INIT_SIZE ((size_t)(1 * 1024 * 1024))
#define H5C__DEF_AR_MIN_SIZE ((size_t)(1 * 1024 * 1024))
#define H5C__DEF_AR_MIN_CLEAN_FRAC 0.5
#define H5C__DEF_AR_INCREMENT 2.0
#define H5C__DEF_AR_MAX_INCREMENT ((size_t)(2 * 1024 * 1024))
#define H5C__DEF_AR_FLASH_MULTIPLE 1.0
#define H5C__DEV_AR_FLASH_THRESHOLD 0.25
#define H5C__DEF_AR_DECREMENT 0.9
#define H5C__DEF_AR_MAX_DECREMENT ((size_t)(1 * 1024 * 1024))
#define H5C__DEF_AR_EPCHS_B4_EVICT 3
#define H5C__DEF_AR_EMPTY_RESERVE 0.05
#define H5C__MIN_AR_EPOCH_LENGTH 100
#define H5C__DEF_AR_EPOCH_LENGTH 50000
#define H5C__MAX_AR_EPOCH_LENGTH 1000000
/* #defines of flags used in the flags parameters in some of the
* following function calls. Note that not all flags are applicable
* to all function calls. Flags that don't apply to a particular
* function are ignored in that function.
*
* These flags apply to all function calls:
* H5C__NO_FLAGS_SET (generic "no flags set" for all fcn calls)
*
*
* These flags apply to H5C_insert_entry():
* H5C__PIN_ENTRY_FLAG
* H5C__FLUSH_LAST_FLAG ; super block only
* H5C__FLUSH_COLLECTIVELY_FLAG ; super block only
*
* These flags apply to H5C_protect()
* H5C__READ_ONLY_FLAG
* H5C__FLUSH_LAST_FLAG ; super block only
* H5C__FLUSH_COLLECTIVELY_FLAG ; super block only
*
* These flags apply to H5C_unprotect():
* H5C__DELETED_FLAG
* H5C__DIRTIED_FLAG
* H5C__PIN_ENTRY_FLAG
* H5C__UNPIN_ENTRY_FLAG
* H5C__FREE_FILE_SPACE_FLAG
* H5C__TAKE_OWNERSHIP_FLAG
*
* These flags apply to H5C_expunge_entry():
* H5C__FREE_FILE_SPACE_FLAG
*
* These flags apply to H5C_evict():
* H5C__EVICT_ALLOW_LAST_PINS_FLAG
*
* These flags apply to H5C_flush_cache():
* H5C__FLUSH_INVALIDATE_FLAG
* H5C__FLUSH_CLEAR_ONLY_FLAG
* H5C__FLUSH_IGNORE_PROTECTED_FLAG (can't use this flag in combination
* with H5C__FLUSH_INVALIDATE_FLAG)
* H5C__DURING_FLUSH_FLAG
*
* These flags apply to H5C_flush_single_entry():
* H5C__FLUSH_INVALIDATE_FLAG
* H5C__FLUSH_CLEAR_ONLY_FLAG
* H5C__TAKE_OWNERSHIP_FLAG
* H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG
* H5C__GENERATE_IMAGE_FLAG
* H5C__UPDATE_PAGE_BUFFER_FLAG
*/
#define H5C__NO_FLAGS_SET 0x00000
#define H5C__DELETED_FLAG 0x00001
#define H5C__DIRTIED_FLAG 0x00002
#define H5C__PIN_ENTRY_FLAG 0x00004
#define H5C__UNPIN_ENTRY_FLAG 0x00008
#define H5C__FLUSH_INVALIDATE_FLAG 0x00010
#define H5C__FLUSH_CLEAR_ONLY_FLAG 0x00020
#define H5C__FLUSH_IGNORE_PROTECTED_FLAG 0x00040
#define H5C__READ_ONLY_FLAG 0x00080
#define H5C__FREE_FILE_SPACE_FLAG 0x00100
#define H5C__TAKE_OWNERSHIP_FLAG 0x00200
#define H5C__FLUSH_LAST_FLAG 0x00400
#define H5C__FLUSH_COLLECTIVELY_FLAG 0x00800
#define H5C__EVICT_ALLOW_LAST_PINS_FLAG 0x01000
#define H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG 0x02000
#define H5C__DURING_FLUSH_FLAG 0x04000 /* Set when the entire cache is being flushed */
#define H5C__GENERATE_IMAGE_FLAG 0x08000 /* Set during parallel I/O */
#define H5C__UPDATE_PAGE_BUFFER_FLAG 0x10000 /* Set during parallel I/O */
/* Debugging/sanity checking/statistics settings */
/* #define H5C_DO_SANITY_CHECKS */
/* #define H5C_DO_SLIST_SANITY_CHECKS */
/* #define H5C_DO_TAGGING_SANITY_CHECKS */
/* #define H5C_DO_EXTREME_SANITY_CHECKS */
/*
* If not already set externally (e.g., from the build
* system), set a few debugging options for debug builds.
*/
#ifndef NDEBUG
#ifndef H5C_DO_SANITY_CHECKS
#define H5C_DO_SANITY_CHECKS
#endif
#ifndef H5C_DO_TAGGING_SANITY_CHECKS
#define H5C_DO_TAGGING_SANITY_CHECKS
#endif
#endif
/* Cork actions: cork/uncork/get cork status of an object */
#define H5C__SET_CORK 0x1
#define H5C__UNCORK 0x2
#define H5C__GET_CORKED 0x4
/* Note: The memory sanity checks aren't going to work until I/O filters are
* changed to call a particular alloc/free routine for their buffers,
* because the H5AC__SERIALIZE_RESIZED_FLAG set by the fractal heap
* direct block serialize callback calls H5Z_pipeline(). When the I/O
* filters are changed, then we should implement "cache image alloc/free"
* routines that the fractal heap direct block (and global heap) serialize
* calls can use when resizing (and re-allocating) their image in the
* cache. -QAK */
#define H5C_DO_MEMORY_SANITY_CHECKS 0
/* H5C_COLLECT_CACHE_STATS controls overall collection of statistics
* on cache activity. In general, this #define should be set to 1 in
* debug mode, and 0 in production mode..
*/
#ifndef NDEBUG
#define H5C_COLLECT_CACHE_STATS 1
#else /* NDEBUG */
#define H5C_COLLECT_CACHE_STATS 0
#endif /* NDEBUG */
/* H5C_COLLECT_CACHE_ENTRY_STATS controls collection of statistics
* in individual cache entries.
*
* H5C_COLLECT_CACHE_ENTRY_STATS should only be defined to true if
* H5C_COLLECT_CACHE_STATS is also defined to true.
*/
#if H5C_COLLECT_CACHE_STATS
#define H5C_COLLECT_CACHE_ENTRY_STATS 1
#else
#define H5C_COLLECT_CACHE_ENTRY_STATS 0
#endif /* H5C_COLLECT_CACHE_STATS */
/****************************/
/* Library Private Typedefs */
/****************************/
/* Typedef for the main structure for the cache (defined in H5Cpkg.h) */
typedef struct H5C_t H5C_t;
/*
*
* Struct H5C_class_t
*
* Instances of H5C_class_t are used to specify the callback functions
* used by the metadata cache for each class of metadata cache entry.
* The fields of the structure are discussed below:
*
* id: Integer field containing the unique ID of the class of metadata
* cache entries.
*
* name: Pointer to a string containing the name of the class of metadata
* cache entries.
*
* mem_type: Instance of H5FD_mem_t, that is used to supply the
* mem type passed into H5F_block_read().
*
* flags: Flags indicating class-specific behavior.
*
* Possible flags are:
*
* H5C__CLASS_NO_FLAGS_SET: No special processing.
*
* H5C__CLASS_SPECULATIVE_LOAD_FLAG: This flag is used only in
* H5C_load_entry(). When it is set, entries are
* permitted to change their sizes on the first attempt
* to load.
*
* If the new size is larger than the old, the read buffer
* is reallocated to the new size, loaded from file, and the
* deserialize routine is called a second time on the
* new buffer. The entry returned by the first call to
* the deserialize routine is discarded (via the free_icr
* call) after the new size is retrieved (via the image_len
* call). Note that the new size is used as the size of the
* entry in the cache.
*
* If the new size is smaller than the old, no new loads
* or deserializes are performed, but the new size becomes
* the size of the entry in the cache.
*
* When this flag is set, an attempt to read past the
* end of file could occur. In this case, if the size
* returned get_load_size callback would result in a
* read past the end of file, the size is truncated to
* avoid this, and processing proceeds as normal.
*
* The following flags may only appear in test code.
*
* H5C__CLASS_SKIP_READS: This flags is intended only for use in test
* code. When it is set, reads on load will be skipped,
* and an uninitialize buffer will be passed to the
* deserialize function.
*
* H5C__CLASS_SKIP_WRITES: This flags is intended only for use in test
* code. When it is set, writes of buffers prepared by the
* serialize callback will be skipped.
*
* GET_INITIAL_LOAD_SIZE: Pointer to the 'get initial load size' function.
*
* This function determines the size based on the information in the
* parameter "udata" or an initial speculative guess. The size is
* returned in the parameter "image_len_ptr".
*
* For an entry with H5C__CLASS_NO_FLAGS_SET:
* This function returns in "image_len_ptr" the on disk size of the
* entry.
*
* For an entry with H5C__CLASS_SPECULATIVE_LOAD_FLAG:
* This function returns in "image_len_ptr" an initial guess of the
* entry's on disk size. This many bytes will be loaded from
* the file and then passed to 'get_final_load_size' callback
* for the actual (final) image length to be determined.
*
* The typedef for the get_initial_load_size callback is as follows:
*
* typedef herr_t (*H5C_get_initial_load_size_func_t)(void *udata_ptr,
* size_t *image_len_ptr);
*
* The parameters of the get_initial_load_size callback are as follows:
*
* udata_ptr: Pointer to user data provided in the protect call, which
* will also be passed through to the 'get_final_load_size',
* 'verify_chksum', and 'deserialize' callbacks.
*
* image_len_ptr: Pointer to the length in bytes of the in-file image to
* be deserialized is to be returned.
*
* This value is used by the cache to determine the size of
* the disk image for the metadata, in order to read the disk
* image from the file.
*
* Processing in the get_load_size function should proceed as follows:
*
* If successful, the function will place the length in the *image_len_ptr
* associated with supplied user data and then return SUCCEED.
*
* On failure, the function must return FAIL and push error information
* onto the error stack with the error API routines, without modifying
* the value pointed to by image_len_ptr.
*
*
* GET_FINAL_LOAD_SIZE: Pointer to the 'get final load size' function.
*
* This function determines the final size of a speculatively loaded
* metadata cache entry based on the parameter "image" and the "udata"
* parameters. This callback _must_ be implemented for cache clients
* which set the H5C__CLASS_SPECULATIVE_LOAD_FLAG and must return the
* actual length of on-disk image after being called once.
*
* This function might deserialize the needed metadata information to
* determine the actual size. The size is returned in the parameter
* "actual_len_ptr".
*
* The typedef for the get_load_size callback is as follows:
*
* typedef herr_t (*H5C_get_final_load_size_func_t)(const void *image_ptr,
* size_t image_len,
* void *udata_ptr,
* size_t *actual_len_ptr);
*
* The parameters of the get_load_size callback are as follows:
*
* image_ptr: Pointer to a buffer containing the (possibly partial)
* metadata read in.
*
* image_len: The length in bytes of the (possibly partial) in-file image
* to be queried for an actual length.
*
* udata_ptr: Pointer to user data provided in the protect call, which
* will also be passed through to the 'verify_chksum' and
* 'deserialize' callbacks.
*
* actual_len_ptr: Pointer to the location containing the actual length
* of the metadata entry on disk.
*
* Processing in the get_final_load_size function should proceed as follows:
*
* If successful, the function will place the length in the *actual_len_ptr
* associated with supplied image and/or user data and then return SUCCEED.
*
* On failure, the function must return FAIL and push error information
* onto the error stack with the error API routines, without modifying
* the value pointed to by actual_len_ptr.
*
*
* VERIFY_CHKSUM: Pointer to the verify_chksum function.
*
* This function verifies the checksum computed for the metadata is
* the same as the checksum stored in the metadata.
*
* It computes the checksum based on the metadata stored in the
* parameter "image_ptr" and the actual length of the metadata in the
* parameter "len" which is obtained from the "get_load_size" callback.
*
* The typedef for the verify_chksum callback is as follows:
*
* typedef htri_t (*H5C_verify_chksum_func_t)(const void *image_ptr,
* size_t len,
* void *udata_ptr);
*
* The parameters of the verify_chksum callback are as follows:
*
* image_ptr: Pointer to a buffer containing the metadata read in.
*
* len: The actual length of the metadata.
*
* udata_ptr: Pointer to user data.
*
*
* DESERIALIZE: Pointer to the deserialize function.
*
* This function must be able to deserialize a buffer containing the
* on-disk image of a metadata cache entry, allocate and initialize the
* equivalent in core representation, and return a pointer to that
* representation.
*
* The typedef for the deserialize callback is as follows:
*
* typedef void *(*H5C_deserialize_func_t)(const void * image_ptr,
* size_t len,
* void * udata_ptr,
* boolean * dirty_ptr);
*
* The parameters of the deserialize callback are as follows:
*
* image_ptr: Pointer to a buffer of length len containing the
* contents of the file starting at addr and continuing
* for len bytes.
*
* len: Length in bytes of the in file image to be deserialized.
*
* This parameter is supplied mainly for sanity checking.
* Sanity checks should be performed when compiled in debug
* mode, but the parameter may be unused when compiled in
* production mode.
*
* udata_ptr: Pointer to user data provided in the protect call, which
* must be passed through to the deserialize callback.
*
* dirty_ptr: Pointer to boolean which the deserialize function
* must use to mark the entry dirty if it has to modify
* the entry to clean up file corruption left over from
* an old bug in the HDF5 library.
*
* Processing in the deserialize function should proceed as follows:
*
* If the image contains valid data, and is of the correct length,
* the deserialize function must allocate space for an in-core
* representation of that data, deserialize the contents of the image
* into the space allocated for the in-core representation, and return
* a pointer to the in core representation. Observe that an
* instance of H5C_cache_entry_t must be the first item in this
* representation. The cache will initialize it after the callback
* returns.
*
* Note that the structure of the in-core representation is otherwise
* up to the cache client. All that is required is that the pointer
* returned be sufficient for the client's purposes when it is returned
* on a protect call.
*
* If the deserialize function has to clean up file corruption
* left over from an old bug in the HDF5 library, it must set
* *dirty_ptr to true. If it doesn't, no action is needed as
* *dirty_ptr will be set to false before the deserialize call.
*
* If the operation fails for any reason (i.e. bad data in buffer, bad
* buffer length, malloc failure, etc.) the function must return NULL and
* push error information on the error stack with the error API routines.
*
*
* IMAGE_LEN: Pointer to the image length callback.
*
* The image_len callback is used to obtain the size of newly inserted
* entries and assert verification.
*
* The typedef for the image_len callback is as follows:
*
* typedef herr_t (*H5C_image_len_func_t)(void *thing,
* size_t *image_len_ptr);
*
* The parameters of the image_len callback are as follows:
*
* thing: Pointer to the in core representation of the entry.
*
* image_len_ptr: Pointer to size_t in which the callback will return
* the length (in bytes) of the cache entry.
*
* Processing in the image_len function should proceed as follows:
*
* If successful, the function will place the length of the on disk
* image associated with the in core representation provided in the
* thing parameter in *image_len_ptr, and then return SUCCEED.
*
* If the function fails, it must return FAIL and push error information
* onto the error stack with the error API routines, and return without
* modifying the values pointed to by the image_len_ptr parameter.
*
*
* PRE_SERIALIZE: Pointer to the pre-serialize callback.
*
* The pre-serialize callback is invoked by the metadata cache before
* it needs a current on-disk image of the metadata entry for purposes
* either constructing a journal or flushing the entry to disk.
*
* If the client needs to change the address or length of the entry prior
* to flush, the pre-serialize callback is responsible for these actions,
* so that the actual serialize callback (described below) is only
* responsible for serializing the data structure, not moving it on disk
* or resizing it.
*
* In addition, the client may use the pre-serialize callback to
* ensure that the entry is ready to be flushed -- in particular,
* if the entry contains references to other entries that are in
* temporary file space, the pre-serialize callback must move those
* entries into real file space so that the serialized entry will
* contain no invalid data.
*
* One would think that the base address and length of
* the length of the entry's image on disk would be well known.
* However, that need not be the case as free space section info
* entries will change size (and possibly location) depending on the
* number of blocks of free space being manages, and fractal heap
* direct blocks can change compressed size (and possibly location)
* on serialization if compression is enabled. Similarly, it may
* be necessary to move entries from temporary to real file space.
*
* The pre-serialize callback must report any such changes to the
* cache, which must then update its internal structures as needed.
*
* The typedef for the pre-serialize callback is as follows:
*
* typedef herr_t (*H5C_pre_serialize_func_t)(H5F_t *f,
* void * thing,
* haddr_t addr,
* size_t len,
* haddr_t * new_addr_ptr,
* size_t * new_len_ptr,
* unsigned * flags_ptr);
*
* The parameters of the pre-serialize callback are as follows:
*
* f: File pointer -- needed if other metadata cache entries
* must be modified in the process of serializing the
* target entry.
*
* thing: Pointer to void containing the address of the in core
* representation of the target metadata cache entry.
* This is the same pointer returned by a protect of the
* addr and len given above.
*
* addr: Base address in file of the entry to be serialized.
*
* This parameter is supplied mainly for sanity checking.
* Sanity checks should be performed when compiled in debug
* mode, but the parameter may be unused when compiled in
* production mode.
*
* len: Length in bytes of the in file image of the entry to be
* serialized. Also the size the image passed to the
* serialize callback (discussed below) unless that
* value is altered by this function.
*
* This parameter is supplied mainly for sanity checking.
* Sanity checks should be performed when compiled in debug
* mode, but the parameter may be unused when compiled in
* production mode.
*
* new_addr_ptr: Pointer to haddr_t. If the entry is moved by
* the serialize function, the new on disk base address must
* be stored in *new_addr_ptr, and the appropriate flag set
* in *flags_ptr.
*
* If the entry is not moved by the serialize function,
* *new_addr_ptr is undefined on pre-serialize callback
* return.
*
* new_len_ptr: Pointer to size_t. If the entry is resized by the
* serialize function, the new length of the on disk image
* must be stored in *new_len_ptr, and the appropriate flag set
* in *flags_ptr.
*
* If the entry is not resized by the pre-serialize function,
* *new_len_ptr is undefined on pre-serialize callback
* return.
*
* flags_ptr: Pointer to an unsigned integer used to return flags
* indicating whether the preserialize function resized or moved
* the entry. If the entry was neither resized or moved, the
* serialize function must set *flags_ptr to zero. The
* H5C__SERIALIZE_RESIZED_FLAG or H5C__SERIALIZE_MOVED_FLAG must
* be set to indicate a resize or move respectively.
*
* If the H5C__SERIALIZE_RESIZED_FLAG is set, the new length
* must be stored in *new_len_ptr.
*
* If the H5C__SERIALIZE_MOVED_FLAG flag is set, the
* new image base address must be stored in *new_addr_ptr.
*
* Processing in the pre-serialize function should proceed as follows:
*
* The pre-serialize function must examine the in core representation
* indicated by the thing parameter, if the pre-serialize function does
* not need to change the size or location of the on-disk image, it must
* set *flags_ptr to zero.
*
* If the size of the on-disk image must be changed, the pre-serialize
* function must load the length of the new image into *new_len_ptr, and
* set the H5C__SERIALIZE_RESIZED_FLAG in *flags_ptr.
*
* If the base address of the on disk image must be changed, the
* pre-serialize function must set *new_addr_ptr to the new base address,
* and set the H5C__SERIALIZE_MOVED_FLAG in *flags_ptr.
*
* In addition, the pre-serialize callback may perform any other
* processing required before the entry is written to disk
*
* If it is successful, the function must return SUCCEED.
*
* If it fails for any reason, the function must return FAIL and
* push error information on the error stack with the error API
* routines.
*
*
* SERIALIZE: Pointer to the serialize callback.
*
* The serialize callback is invoked by the metadata cache whenever
* it needs a current on disk image of the metadata entry for purposes
* either constructing a journal entry or flushing the entry to disk.
*
* At this point, the base address and length of the entry's image on
* disk must be well known and not change during the serialization
* process.
*
* While any size and/or location changes must have been handled
* by a pre-serialize call, the client may elect to handle any other
* changes to the entry required to place it in correct form for
* writing to disk in this call.
*
* The typedef for the serialize callback is as follows:
*
* typedef herr_t (*H5C_serialize_func_t)(const H5F_t *f,
* void * image_ptr,
* size_t len,
* void * thing);
*
* The parameters of the serialize callback are as follows:
*
* f: File pointer -- needed if other metadata cache entries
* must be modified in the process of serializing the
* target entry.
*
* image_ptr: Pointer to a buffer of length len bytes into which a
* serialized image of the target metadata cache entry is
* to be written.
*
* Note that this buffer will not in general be initialized
* to any particular value. Thus the serialize function may
* not assume any initial value and must set each byte in
* the buffer.
*
* len: Length in bytes of the in file image of the entry to be
* serialized. Also the size of *image_ptr (below).
*
* This parameter is supplied mainly for sanity checking.
* Sanity checks should be performed when compiled in debug
* mode, but the parameter may be unused when compiled in
* production mode.
*
* thing: Pointer to void containing the address of the in core
* representation of the target metadata cache entry.
* This is the same pointer returned by a protect of the
* addr and len given above.
*
* Processing in the serialize function should proceed as follows:
*
* If there are any remaining changes to the entry required before
* write to disk, they must be dealt with first.
*
* The serialize function must then examine the in core
* representation indicated by the thing parameter, and write a
* serialized image of its contents into the provided buffer.
*
* If it is successful, the function must return SUCCEED.
*
* If it fails for any reason, the function must return FAIL and
* push error information on the error stack with the error API
* routines.
*
*
* NOTIFY: Pointer to the notify callback.
*
* The notify callback is invoked by the metadata cache when a cache
* action on an entry has taken/will take place and the client indicates
* it wishes to be notified about the action.
*
* The typedef for the notify callback is as follows:
*
* typedef herr_t (*H5C_notify_func_t)(H5C_notify_action_t action,
* void *thing);
*
* The parameters of the notify callback are as follows:
*
* action: An enum indicating the metadata cache action that has taken/
* will take place.
*
* thing: Pointer to void containing the address of the in core
* representation of the target metadata cache entry. This
* is the same pointer that would be returned by a protect
* of the addr and len of the entry.
*
* Processing in the notify function should proceed as follows:
*
* The notify function may perform any action it would like, including
* metadata cache calls.
*
* If the function is successful, it must return SUCCEED.
*
* If it fails for any reason, the function must return FAIL and
* push error information on the error stack with the error API
* routines.
*
*
* FREE_ICR: Pointer to the free ICR callback.
*
* The free ICR callback is invoked by the metadata cache when it
* wishes to evict an entry, and needs the client to free the memory
* allocated for the in core representation.
*
* The typedef for the free ICR callback is as follows:
*
* typedef herr_t (*H5C_free_icr_func_t)(void * thing));
*
* The parameters of the free ICR callback are as follows:
*
* thing: Pointer to void containing the address of the in core
* representation of the target metadata cache entry. This
* is the same pointer that would be returned by a protect
* of the addr and len of the entry.
*
* Processing in the free ICR function should proceed as follows:
*
* The free ICR function must free all memory allocated to the
* in core representation.
*
* If the function is successful, it must return SUCCEED.
*
* If it fails for any reason, the function must return FAIL and
* push error information on the error stack with the error API
* routines.
*
* At least when compiled with debug, it would be useful if the
* free ICR call would fail if the in core representation has been
* modified since the last serialize callback.
*
* GET_FSF_SIZE: Pointer to the get file space free size callback.
*
* In principle, there is no need for the get file space free size
* callback. However, as an optimization, it is sometimes convenient
* to allocate and free file space for a number of cache entries
* simultaneously in a single contiguous block of file space.
*
* File space allocation is done by the client, so the metadata cache
* need not be involved. However, since the metadata cache typically
* handles file space release when an entry is destroyed, some
* adjustment on the part of the metadata cache is required for this
* operation.
*
* The get file space free size callback exists to support this
* operation.
*
* If a group of cache entries that were allocated as a group are to
* be discarded and their file space released, the type of the first
* (i.e. lowest address) entry in the group must implement the
* get free file space size callback.
*
* To free the file space of all entries in the group in a single
* operation, first expunge all entries other than the first without
* the free file space flag.
*
* Then, to complete the operation, unprotect or expunge the first
* entry in the block with the free file space flag set. Since
* the get free file space callback is implemented, the metadata
* cache will use this callback to get the size of the block to be
* freed, instead of using the size of the entry as is done otherwise.
*
* At present this callback is used only by the H5FA and H5EA dblock
* and dblock page client classes.
*
* The typedef for the get_fsf_size callback is as follows:
*
* typedef herr_t (*H5C_get_fsf_size_t)(const void * thing,
* hsize_t *fsf_size_ptr);
*
* The parameters of the get_fsf_size callback are as follows:
*
* thing: Pointer to void containing the address of the in core
* representation of the target metadata cache entry. This
* is the same pointer that would be returned by a protect()
* call of the associated addr and len.
*
* fs_size_ptr: Pointer to hsize_t in which the callback will return
* the size of the piece of file space to be freed. Note
* that the space to be freed is presumed to have the same
* base address as the cache entry.
*
* The function simply returns the size of the block of file space
* to be freed in *fsf_size_ptr.
*
* If the function is successful, it must return SUCCEED.
*
* If it fails for any reason, the function must return FAIL and
* push error information on the error stack with the error API
* routines.
*
***************************************************************************/
/* Actions that can be reported to 'notify' client callback */
typedef enum H5C_notify_action_t {
H5C_NOTIFY_ACTION_AFTER_INSERT, /* Entry has been added to the cache
* via the insert call
*/
H5C_NOTIFY_ACTION_AFTER_LOAD, /* Entry has been loaded into the
* from file via the protect call
*/
H5C_NOTIFY_ACTION_AFTER_FLUSH, /* Entry has just been flushed to
* file.
*/
H5C_NOTIFY_ACTION_BEFORE_EVICT, /* Entry is about to be evicted
* from cache.
*/
H5C_NOTIFY_ACTION_ENTRY_DIRTIED, /* Entry has been marked dirty. */
H5C_NOTIFY_ACTION_ENTRY_CLEANED, /* Entry has been marked clean. */
H5C_NOTIFY_ACTION_CHILD_DIRTIED, /* Dependent child has been marked dirty. */
H5C_NOTIFY_ACTION_CHILD_CLEANED, /* Dependent child has been marked clean. */
H5C_NOTIFY_ACTION_CHILD_UNSERIALIZED, /* Dependent child has been marked unserialized. */
H5C_NOTIFY_ACTION_CHILD_SERIALIZED /* Dependent child has been marked serialized. */
} H5C_notify_action_t;
/* Cache client callback function pointers */
typedef herr_t (*H5C_get_initial_load_size_func_t)(void *udata_ptr, size_t *image_len_ptr);
typedef herr_t (*H5C_get_final_load_size_func_t)(const void *image_ptr, size_t image_len, void *udata_ptr,
size_t *actual_len_ptr);
typedef htri_t (*H5C_verify_chksum_func_t)(const void *image_ptr, size_t len, void *udata_ptr);
typedef void *(*H5C_deserialize_func_t)(const void *image_ptr, size_t len, void *udata_ptr, bool *dirty_ptr);
typedef herr_t (*H5C_image_len_func_t)(const void *thing, size_t *image_len_ptr);
typedef herr_t (*H5C_pre_serialize_func_t)(H5F_t *f, void *thing, haddr_t addr, size_t len,
haddr_t *new_addr_ptr, size_t *new_len_ptr, unsigned *flags_ptr);
typedef herr_t (*H5C_serialize_func_t)(const H5F_t *f, void *image_ptr, size_t len, void *thing);
typedef herr_t (*H5C_notify_func_t)(H5C_notify_action_t action, void *thing);
typedef herr_t (*H5C_free_icr_func_t)(void *thing);
typedef herr_t (*H5C_get_fsf_size_t)(const void *thing, hsize_t *fsf_size_ptr);
/* Metadata cache client class definition */
typedef struct H5C_class_t {
int id;
const char *name;
H5FD_mem_t mem_type;
unsigned flags;
H5C_get_initial_load_size_func_t get_initial_load_size;
H5C_get_final_load_size_func_t get_final_load_size;
H5C_verify_chksum_func_t verify_chksum;
H5C_deserialize_func_t deserialize;
H5C_image_len_func_t image_len;
H5C_pre_serialize_func_t pre_serialize;
H5C_serialize_func_t serialize;
H5C_notify_func_t notify;
H5C_free_icr_func_t free_icr;
H5C_get_fsf_size_t fsf_size;
} H5C_class_t;
/* Type definitions of callback functions used by the cache as a whole */
typedef herr_t (*H5C_write_permitted_func_t)(const H5F_t *f, bool *write_permitted_ptr);
typedef herr_t (*H5C_log_flush_func_t)(H5C_t *cache_ptr, haddr_t addr, bool was_dirty, unsigned flags);
/****************************************************************************
*
* H5C_ring_t & associated #defines
*
* The metadata cache uses the concept of rings to order the flushes of
* classes of entries. In this arrangement, each entry in the cache is
* assigned to a ring, and on flush, the members of the outermost ring
* are flushed first, followed by the next outermost, and so on with the
* members of the innermost ring being flushed last.
*
* Note that flush dependencies are used to order flushes within rings.
*
* Note also that at the conceptual level, rings are arguably superfluous,
* as a similar effect could be obtained via the flush dependency mechanism.
* However, this would require all entries in the cache to participate in a
* flush dependency -- with the implied setup and takedown overhead and
* added complexity. Further, the flush ordering between rings need only
* be enforced on flush operations, and thus the use of flush dependencies
* instead would apply unnecessary constraints on flushes under normal
* operating circumstances.
*
* As of this writing, all metadata entries pertaining to data sets and
* groups must be flushed first, and are thus assigned to the outermost
* ring.
*
* Free space managers managing file space must be flushed next,
* and are assigned to the second and third outermost rings. Two rings
* are used here as the raw data free space manager must be flushed before
* the metadata free space manager.
*
* The object header and associated chunks used to implement superblock
* extension messages must be flushed next, and are thus assigned to
* the fourth outermost ring.
*
* The superblock proper must be flushed last, and is thus assigned to
* the innermost ring.
*
* The H5C_ring_t and the associated #defines below are used to define
* the rings. Each entry must be assigned to the appropriate ring on
* insertion or protect.
*
* Note that H5C_ring_t was originally an enumerated type. It was
* converted to an integer and a set of #defines for convenience in
* debugging.
*/
#define H5C_RING_UNDEFINED 0 /* shouldn't appear in the cache */
#define H5C_RING_USER 1 /* outermost ring */
#define H5C_RING_RDFSM 2
#define H5C_RING_MDFSM 3
#define H5C_RING_SBE 4
#define H5C_RING_SB 5 /* innermost ring */
#define H5C_RING_NTYPES 6
typedef int H5C_ring_t;
/****************************************************************************
*
* structure H5C_cache_entry_t
*
* Instances of the H5C_cache_entry_t structure are used to store cache
* entries in a hash table and sometimes in a skip list.
* See H5SL.c for the particulars of the skip list.
*
* In typical application, this structure is the first field in a
* structure to be cached. For historical reasons, the external module
* is responsible for managing the is_dirty field (this is no longer
* completely true. See the comment on the is_dirty field for details).
* All other fields are managed by the cache.
*
* The fields of this structure are discussed individually below:
*
* cache_ptr: Pointer to the cache that this entry is contained within.
*
* addr: Base address of the cache entry on disk.
*
* size: Length of the cache entry on disk in bytes Note that unlike
* normal caches, the entries in this cache are of arbitrary size.
*
* The file space allocations for cache entries implied by the
* addr and size fields must be disjoint.
*
* image_ptr: Pointer to void. When not NULL, this field points to a
* dynamically allocated block of size bytes in which the
* on disk image of the metadata cache entry is stored.
*
* If the entry is dirty, the pre-serialize and serialize
* callbacks must be used to update this image before it is
* written to disk
*
* image_up_to_date: Boolean flag that is set to true when *image_ptr
* is up to date, and set to false when the entry is dirtied.
*
* type: Pointer to the instance of H5C_class_t containing pointers
* to the methods for cache entries of the current type. This
* field should be NULL when the instance of H5C_cache_entry_t
* is not in use.
*
* The name is not particularly descriptive, but is retained
* to avoid changes in existing code.
*
* is_dirty: Boolean flag indicating whether the contents of the cache
* entry has been modified since the last time it was written
* to disk.
*
* dirtied: Boolean flag used to indicate that the entry has been
* dirtied while protected.