Actual source code: petscctable.h
1: #ifndef PETSCCTABLE_H
2: #define PETSCCTABLE_H
3: #include <petscsys.h>
5: struct _n_PetscTable {
6: PetscInt *keytable;
7: PetscInt *table;
8: PetscInt count;
9: PetscInt tablesize;
10: PetscInt head;
11: PetscInt maxkey; /* largest key allowed */
12: };
14: typedef struct _n_PetscTable *PetscTable;
15: typedef PetscInt *PetscTablePosition;
17: static inline unsigned long PetscHash(PetscTable ta, unsigned long x)
18: {
19: return (x % (unsigned long)ta->tablesize);
20: }
22: static inline unsigned long PetscHashStep(PetscTable ta, unsigned long x)
23: {
24: return (1 + (x % (unsigned long)(ta->tablesize - 1)));
25: }
27: PETSC_EXTERN PetscErrorCode PetscTableCreate(const PetscInt, PetscInt, PetscTable *);
28: PETSC_EXTERN PetscErrorCode PetscTableCreateCopy(const PetscTable, PetscTable *);
29: PETSC_EXTERN PetscErrorCode PetscTableDestroy(PetscTable *);
30: PETSC_EXTERN PetscErrorCode PetscTableGetCount(const PetscTable, PetscInt *);
31: PETSC_EXTERN PetscErrorCode PetscTableIsEmpty(const PetscTable, PetscInt *);
32: PETSC_EXTERN PetscErrorCode PetscTableAddExpand(PetscTable, PetscInt, PetscInt, InsertMode);
33: PETSC_EXTERN PetscErrorCode PetscTableAddCountExpand(PetscTable, PetscInt);
34: PETSC_EXTERN PetscErrorCode PetscTableGetHeadPosition(PetscTable, PetscTablePosition *);
35: PETSC_EXTERN PetscErrorCode PetscTableGetNext(PetscTable, PetscTablePosition *, PetscInt *, PetscInt *);
36: PETSC_EXTERN PetscErrorCode PetscTableRemoveAll(PetscTable);
38: static inline PetscErrorCode PetscTableAdd(PetscTable ta, PetscInt key, PetscInt data, InsertMode imode)
39: {
40: PetscInt i, hash = (PetscInt)PetscHash(ta, (unsigned long)key);
41: PetscInt hashstep = (PetscInt)PetscHashStep(ta, (unsigned long)key);
47: for (i = 0; i < ta->tablesize; i++) {
48: if (ta->keytable[hash] == key) {
49: switch (imode) {
50: case INSERT_VALUES:
51: ta->table[hash] = data; /* over write */
52: break;
53: case ADD_VALUES:
54: ta->table[hash] += data;
55: break;
56: case MAX_VALUES:
57: ta->table[hash] = PetscMax(ta->table[hash], data);
58: break;
59: case MIN_VALUES:
60: ta->table[hash] = PetscMin(ta->table[hash], data);
61: break;
62: case NOT_SET_VALUES:
63: case INSERT_ALL_VALUES:
64: case ADD_ALL_VALUES:
65: case INSERT_BC_VALUES:
66: case ADD_BC_VALUES:
67: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported InsertMode");
68: }
69: return 0;
70: } else if (!ta->keytable[hash]) {
71: if (ta->count < 5 * (ta->tablesize / 6) - 1) {
72: ta->count++; /* add */
73: ta->keytable[hash] = key;
74: ta->table[hash] = data;
75: } else PetscTableAddExpand(ta, key, data, imode);
76: return 0;
77: }
78: hash = (hash + hashstep) % ta->tablesize;
79: }
80: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_COR, "Full table");
81: /* return 0; */
82: }
84: static inline PetscErrorCode PetscTableAddCount(PetscTable ta, PetscInt key)
85: {
86: PetscInt i, hash = (PetscInt)PetscHash(ta, (unsigned long)key);
87: PetscInt hashstep = (PetscInt)PetscHashStep(ta, (unsigned long)key);
92: for (i = 0; i < ta->tablesize; i++) {
93: if (ta->keytable[hash] == key) {
94: return 0;
95: } else if (!ta->keytable[hash]) {
96: if (ta->count < 5 * (ta->tablesize / 6) - 1) {
97: ta->count++; /* add */
98: ta->keytable[hash] = key;
99: ta->table[hash] = ta->count;
100: } else PetscTableAddCountExpand(ta, key);
101: return 0;
102: }
103: hash = (hash + hashstep) % ta->tablesize;
104: }
105: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_COR, "Full table");
106: /* return 0; */
107: }
109: /*
110: PetscTableFind - finds data in table from a given key, if the key is valid but not in the table returns 0
111: */
112: static inline PetscErrorCode PetscTableFind(PetscTable ta, PetscInt key, PetscInt *data)
113: {
114: PetscInt ii = 0;
115: PetscInt hash = (PetscInt)PetscHash(ta, (unsigned long)key);
116: PetscInt hashstep = (PetscInt)PetscHashStep(ta, (unsigned long)key);
118: *data = 0;
122: while (ii++ < ta->tablesize) {
123: if (!ta->keytable[hash]) break;
124: else if (ta->keytable[hash] == key) {
125: *data = ta->table[hash];
126: break;
127: }
128: hash = (hash + hashstep) % ta->tablesize;
129: }
130: return 0;
131: }
133: #endif