1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * Copyright by the Board of Trustees of the University of Illinois.         *
4  * All rights reserved.                                                      *
5  *                                                                           *
6  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
7  * terms governing use, modification, and redistribution, is contained in    *
8  * the files COPYING and Copyright.html.  COPYING can be found at the root   *
9  * of the source code distribution tree; Copyright.html can be found at the  *
10  * root level of an installed copy of the electronic HDF5 document set and   *
11  * is linked from the top-level documents page.  It can also be found at     *
12  * http://hdfgroup.org/HDF5/doc/Copyright.html.  If you do not have          *
13  * access to either file, you may request a copy from help@hdfgroup.org.     *
14  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /****************/
17 /* Module Setup */
18 /****************/
19 
20 #define H5O_PACKAGE		/*suppress error about including H5Opkg 	  */
21 #define H5SM_PACKAGE		/*suppress error about including H5SMpkg	  */
22 
23 
24 /***********/
25 /* Headers */
26 /***********/
27 #include "H5private.h"		/* Generic Functions			*/
28 #include "H5Eprivate.h"		/* Error handling		  	*/
29 #include "H5Opkg.h"             /* Object Headers                       */
30 #include "H5SMpkg.h"            /* Shared object header messages        */
31 
32 
33 /****************/
34 /* Local Macros */
35 /****************/
36 
37 
38 /******************/
39 /* Local Typedefs */
40 /******************/
41 
42 
43 /********************/
44 /* Local Prototypes */
45 /********************/
46 
47 /* v2 B-tree callbacks */
48 static void *H5SM_bt2_crt_context(void *udata);
49 static herr_t H5SM_bt2_dst_context(void *ctx);
50 static herr_t H5SM_bt2_store(void *native, const void *udata);
51 static herr_t H5SM_bt2_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id,
52     int indent, int fwidth, const void *record, const void *_udata);
53 static void *H5SM_bt2_crt_dbg_context(H5F_t *f, hid_t dxpl_id, haddr_t addr);
54 
55 
56 /*****************************/
57 /* Library Private Variables */
58 /*****************************/
59 /* v2 B-tree class for SOHM indexes*/
60 const H5B2_class_t H5SM_INDEX[1]={{   /* B-tree class information */
61     H5B2_SOHM_INDEX_ID,               /* Type of B-tree */
62     "H5B2_SOHM_INDEX_ID",             /* Name of B-tree class */
63     sizeof(H5SM_sohm_t),              /* Size of native record */
64     H5SM_bt2_crt_context,             /* Create client callback context */
65     H5SM_bt2_dst_context,             /* Destroy client callback context */
66     H5SM_bt2_store,                   /* Record storage callback */
67     H5SM_message_compare,             /* Record comparison callback */
68     H5SM_message_encode,              /* Record encoding callback */
69     H5SM_message_decode,              /* Record decoding callback */
70     H5SM_bt2_debug,                   /* Record debugging callback */
71     H5SM_bt2_crt_dbg_context,	      /* Create debugging context */
72     H5SM_bt2_dst_context 	      /* Destroy debugging context */
73 }};
74 
75 
76 /*******************/
77 /* Local Variables */
78 /*******************/
79 
80 /* Declare a free list to manage the H5SM_bt2_ctx_t struct */
81 H5FL_DEFINE_STATIC(H5SM_bt2_ctx_t);
82 
83 
84 
85 /*-------------------------------------------------------------------------
86  * Function:	H5SM_bt2_crt_context
87  *
88  * Purpose:	Create client callback context
89  *
90  * Return:	Success:	non-NULL
91  *		Failure:	NULL
92  *
93  * Programmer:	Quincey Koziol
94  *              Thursday, November 26, 2009
95  *
96  *-------------------------------------------------------------------------
97  */
98 static void *
H5SM_bt2_crt_context(void * _f)99 H5SM_bt2_crt_context(void *_f)
100 {
101     H5F_t *f = (H5F_t *)_f;     /* User data for building callback context */
102     H5SM_bt2_ctx_t *ctx;        /* Callback context structure */
103     void *ret_value;            /* Return value */
104 
105     FUNC_ENTER_NOAPI_NOINIT
106 
107     /* Sanity check */
108     HDassert(f);
109 
110     /* Allocate callback context */
111     if(NULL == (ctx = H5FL_MALLOC(H5SM_bt2_ctx_t)))
112         HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate callback context")
113 
114     /* Determine the size of addresses & lengths in the file */
115     ctx->sizeof_addr = H5F_SIZEOF_ADDR(f);
116 
117     /* Set return value */
118     ret_value = ctx;
119 
120 done:
121     FUNC_LEAVE_NOAPI(ret_value)
122 } /* H5SM_bt2_crt_context() */
123 
124 
125 /*-------------------------------------------------------------------------
126  * Function:	H5SM_bt2_dst_context
127  *
128  * Purpose:	Destroy client callback context
129  *
130  * Return:	Success:	non-negative
131  *		Failure:	negative
132  *
133  * Programmer:	Quincey Koziol
134  *              Thursday, November 26, 2009
135  *
136  *-------------------------------------------------------------------------
137  */
138 static herr_t
H5SM_bt2_dst_context(void * _ctx)139 H5SM_bt2_dst_context(void *_ctx)
140 {
141     H5SM_bt2_ctx_t *ctx = (H5SM_bt2_ctx_t *)_ctx;       /* Callback context structure */
142 
143     FUNC_ENTER_NOAPI_NOINIT_NOERR
144 
145     /* Sanity check */
146     HDassert(ctx);
147 
148     /* Release callback context */
149     ctx = H5FL_FREE(H5SM_bt2_ctx_t, ctx);
150 
151     FUNC_LEAVE_NOAPI(SUCCEED)
152 } /* H5SM_bt2_dst_context() */
153 
154 
155 /*-------------------------------------------------------------------------
156  * Function:	H5SM_bt2_store
157  *
158  * Purpose:	Store a H5SM_sohm_t SOHM message in the B-tree.  The message
159  *              comes in UDATA as a H5SM_mesg_key_t* and is copied to
160  *              NATIVE as a H5SM_sohm_t.
161  *
162  * Return:	Non-negative on success
163  *              Negative on failure
164  *
165  * Programmer:	James Laird
166  *              Monday, November 6, 2006
167  *
168  *-------------------------------------------------------------------------
169  */
170 static herr_t
H5SM_bt2_store(void * native,const void * udata)171 H5SM_bt2_store(void *native, const void *udata)
172 {
173     const H5SM_mesg_key_t *key = (const H5SM_mesg_key_t *)udata;
174 
175     FUNC_ENTER_NOAPI_NOINIT_NOERR
176 
177     /* Copy the source message to the B-tree */
178     *(H5SM_sohm_t *)native = key->message;
179 
180     FUNC_LEAVE_NOAPI(SUCCEED)
181 } /* end H5SM_bt2_store */
182 
183 
184 /*-------------------------------------------------------------------------
185  * Function:	H5SM_bt2_debug
186  *
187  * Purpose:	Print debugging information for a H5SM_sohm_t.
188  *
189  * Return:	Non-negative on success
190  *              Negative on failure
191  *
192  * Programmer:	James Laird
193  *              Monday, November 6, 2006
194  *
195  *-------------------------------------------------------------------------
196  */
197 static herr_t
H5SM_bt2_debug(FILE * stream,const H5F_t UNUSED * f,hid_t UNUSED dxpl_id,int indent,int fwidth,const void * record,const void UNUSED * _udata)198 H5SM_bt2_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
199     int indent, int fwidth, const void *record, const void UNUSED *_udata)
200 {
201     const H5SM_sohm_t *sohm = (const H5SM_sohm_t *)record;
202 
203     FUNC_ENTER_NOAPI_NOINIT_NOERR
204 
205     if(sohm->location == H5SM_IN_HEAP)
206         HDfprintf(stream, "%*s%-*s {%a, %lo, %Hx}\n", indent, "", fwidth,
207             "Shared Message in heap:",
208             sohm->u.heap_loc.fheap_id, sohm->hash, sohm->u.heap_loc.ref_count);
209     else {
210         HDassert(sohm->location == H5SM_IN_OH);
211         HDfprintf(stream, "%*s%-*s {%a, %lo, %Hx, %Hx}\n", indent, "", fwidth,
212             "Shared Message in OH:",
213             sohm->u.mesg_loc.oh_addr, sohm->hash, sohm->msg_type_id, sohm->u.mesg_loc.index);
214     } /* end else */
215 
216     FUNC_LEAVE_NOAPI(SUCCEED)
217 } /* end H5SM_bt2_debug */
218 
219 
220 /*-------------------------------------------------------------------------
221  * Function:	H5SM_bt2_crt_dbg_context
222  *
223  * Purpose:	Create context for debugging callback
224  *
225  * Return:	Success:	non-NULL
226  *		Failure:	NULL
227  *
228  * Programmer:	Quincey Koziol
229  *              Tuesday, December 1, 2009
230  *
231  *-------------------------------------------------------------------------
232  */
233 static void *
H5SM_bt2_crt_dbg_context(H5F_t * f,hid_t UNUSED dxpl_id,haddr_t UNUSED addr)234 H5SM_bt2_crt_dbg_context(H5F_t *f, hid_t UNUSED dxpl_id, haddr_t UNUSED addr)
235 {
236     H5SM_bt2_ctx_t *ctx;        /* Callback context structure */
237     void *ret_value;            /* Return value */
238 
239     FUNC_ENTER_NOAPI_NOINIT
240 
241     /* Sanity check */
242     HDassert(f);
243 
244     /* Allocate callback context */
245     if(NULL == (ctx = H5FL_MALLOC(H5SM_bt2_ctx_t)))
246         HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate callback context")
247 
248     /* Determine the size of addresses & lengths in the file */
249     ctx->sizeof_addr = H5F_SIZEOF_ADDR(f);
250 
251     /* Set return value */
252     ret_value = ctx;
253 
254 done:
255     FUNC_LEAVE_NOAPI(ret_value)
256 } /* H5SM_bt2_crt_dbg_context() */
257 
258 
259 /*-------------------------------------------------------------------------
260  * Function:	H5SM_bt2_convert_to_list_op
261  *
262  * Purpose:	An H5B2_remove_t callback function to convert a SOHM
263  *              B-tree index to a list.
264  *
265  *              Inserts this record into the list passed through op_data.
266  *
267  * Return:	Non-negative on success
268  *              Negative on failure
269  *
270  * Programmer:	James Laird
271  *              Monday, November 6, 2006
272  *
273  *-------------------------------------------------------------------------
274  */
275 herr_t
H5SM_bt2_convert_to_list_op(const void * record,void * op_data)276 H5SM_bt2_convert_to_list_op(const void * record, void *op_data)
277 {
278     const H5SM_sohm_t *message = (const H5SM_sohm_t *)record;
279     const H5SM_list_t *list = (const H5SM_list_t *)op_data;
280     size_t mesg_idx;            /* Index of message to modify */
281 
282     FUNC_ENTER_NOAPI_NOINIT_NOERR
283 
284     /* Sanity checks */
285     HDassert(record);
286     HDassert(op_data);
287 
288     /* Get the message index, and increment the # of messages in list */
289     mesg_idx = list->header->num_messages++;
290     HDassert(list->header->num_messages <= list->header->list_max);
291 
292     /* Insert this message at the end of the list */
293     HDassert(list->messages[mesg_idx].location == H5SM_NO_LOC);
294     HDassert(message->location != H5SM_NO_LOC);
295     HDmemcpy(&(list->messages[mesg_idx]), message, sizeof(H5SM_sohm_t));
296 
297     FUNC_LEAVE_NOAPI(SUCCEED)
298 } /* end H5SM_bt2_convert_to_list_op() */
299 
300