Actual source code: petscfptimpl.h


  2: #ifndef PETSCFPIMPL_H
  3: #define PETSCFPIMPL_H
  4: #include <petscviewertypes.h>
  5: #include <petscsys.h>
  6: /*
  7:     Function pointer table that maps from function pointers to their string representation

 10: */
 11: #define PetscCallQ(A) \
 12:   do { \
 13:     PetscErrorCode A; \
 14:     if (ierr) return (ierr); \
 15:   } while (0);

 17: typedef struct _n_PetscFPT *PetscFPT;
 18: struct _n_PetscFPT {
 19:   void   **functionpointer;
 20:   char   **functionname;
 21:   PetscInt count;
 22:   PetscInt tablesize;
 23: };
 24: PETSC_INTERN PetscFPT PetscFPTData;

 26: static inline PetscErrorCode PetscFPTView(PetscViewer viewer)
 27: {
 28:   if (PetscFPTData) {
 29:     for (PetscInt i = 0; i < PetscFPTData->tablesize; ++i) {
 30:       if (PetscFPTData->functionpointer[i]) printf("%s()\n", PetscFPTData->functionname[i]);
 31:     }
 32:   }
 33:   return 0;
 34: }

 36: static inline PetscErrorCode PetscFPTDestroy(void)
 37: {
 38:   PetscFPT data = PetscFPTData;

 40:   PetscFPTData = NULL;
 41:   if (!data) return 0;
 42:   PetscFree(data->functionpointer);
 43:   PetscFree(data->functionname);
 44:   PetscFree(data);
 45:   return 0;
 46: }

 48: /*
 49:    PetscFPTCreate  Creates a PETSc look up table from function pointers to strings

 51:    Input Parameters:
 52: .     n - expected number of keys

 54: */
 55: static inline PetscErrorCode PetscFPTCreate(PetscInt n)
 56: {
 57:   PetscFPT _PetscFPTData;

 60:   /* Cannot use PetscNew() here because it is not yet defined in the include file chain */
 61:   PetscMalloc(sizeof(struct _n_PetscFPT), &_PetscFPTData);
 62:   _PetscFPTData->tablesize = (3 * n) / 2 + 17;
 63:   if (_PetscFPTData->tablesize < n) _PetscFPTData->tablesize = PETSC_MAX_INT / 4; /* overflow */
 64:   PetscCalloc(sizeof(void *) * _PetscFPTData->tablesize, &_PetscFPTData->functionpointer);
 65:   PetscMalloc(sizeof(char **) * _PetscFPTData->tablesize, &_PetscFPTData->functionname);
 66:   _PetscFPTData->count = 0;
 67:   PetscFPTData         = _PetscFPTData;
 68:   return (0);
 69: }

 71: static inline unsigned long PetscFPTHashPointer(void *ptr)
 72: {
 73: #define PETSC_FPT_HASH_FACT 79943
 74:   return ((PETSC_FPT_HASH_FACT * ((size_t)ptr)) % PetscFPTData->tablesize);
 75: }

 77: static inline PetscErrorCode PetscFPTAdd(void *key, const char *data)
 78: {
 80:   if (!PetscFPTData) return 0;
 81:   for (PetscInt i = 0, hash = (PetscInt)PetscFPTHashPointer(key); i < PetscFPTData->tablesize; ++i) {
 82:     if (PetscFPTData->functionpointer[hash] == key) {
 83:       PetscFPTData->functionname[hash] = (char *)data;
 84:       return 0;
 85:     } else if (!PetscFPTData->functionpointer[hash]) {
 86:       PetscFPTData->count++;
 87:       PetscFPTData->functionpointer[hash] = key;
 88:       PetscFPTData->functionname[hash]    = (char *)data;
 89:       return 0;
 90:     }
 91:     hash = (hash == (PetscFPTData->tablesize - 1)) ? 0 : hash + 1;
 92:   }
 93:   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Function pointer table is full");
 94: }

 96: /*
 97:     PetscFPTFind - checks if a function pointer is in the table

 99:     If data==0, then no entry exists

101: */
102: static inline PetscErrorCode PetscFPTFind(void *key, char const **data)
103: {
104:   PetscInt hash, ii = 0;

106:   *data = NULL;
107:   if (!PetscFPTData) return (0);
108:   hash = PetscFPTHashPointer(key);
109:   while (ii++ < PetscFPTData->tablesize) {
110:     if (!PetscFPTData->functionpointer[hash]) break;
111:     else if (PetscFPTData->functionpointer[hash] == key) {
112:       *data = PetscFPTData->functionname[hash];
113:       break;
114:     }
115:     hash = (hash == (PetscFPTData->tablesize - 1)) ? 0 : hash + 1;
116:   }
117:   return 0;
118: }

120: #endif