📄 common.c
字号:
{ newAlloc = 256; dumpIdMap = (DumpableObject **) malloc(newAlloc * sizeof(DumpableObject *)); } else { newAlloc = allocedDumpIds * 2; dumpIdMap = (DumpableObject **) realloc(dumpIdMap, newAlloc * sizeof(DumpableObject *)); } if (dumpIdMap == NULL) exit_horribly(NULL, NULL, "out of memory\n"); memset(dumpIdMap + allocedDumpIds, 0, (newAlloc - allocedDumpIds) * sizeof(DumpableObject *)); allocedDumpIds = newAlloc; } dumpIdMap[dobj->dumpId] = dobj; /* mark catalogIdMap invalid, but don't rebuild it yet */ catalogIdMapValid = false;}/* * Assign a DumpId that's not tied to a DumpableObject. * * This is used when creating a "fixed" ArchiveEntry that doesn't need to * participate in the sorting logic. */DumpIdcreateDumpId(void){ return ++lastDumpId;}/* * Return the largest DumpId so far assigned */DumpIdgetMaxDumpId(void){ return lastDumpId;}/* * Find a DumpableObject by dump ID * * Returns NULL for invalid ID */DumpableObject *findObjectByDumpId(DumpId dumpId){ if (dumpId <= 0 || dumpId >= allocedDumpIds) return NULL; /* out of range? */ return dumpIdMap[dumpId];}/* * Find a DumpableObject by catalog ID * * Returns NULL for unknown ID * * We use binary search in a sorted list that is built on first call. * If AssignDumpId() and findObjectByCatalogId() calls were intermixed, * the code would work, but possibly be very slow. In the current usage * pattern that does not happen, indeed we only need to build the list once. */DumpableObject *findObjectByCatalogId(CatalogId catalogId){ DumpableObject **low; DumpableObject **high; if (!catalogIdMapValid) { if (catalogIdMap) free(catalogIdMap); getDumpableObjects(&catalogIdMap, &numCatalogIds); if (numCatalogIds > 1) qsort((void *) catalogIdMap, numCatalogIds, sizeof(DumpableObject *), DOCatalogIdCompare); catalogIdMapValid = true; } /* * We could use bsearch() here, but the notational cruft of calling * bsearch is nearly as bad as doing it ourselves; and the generalized * bsearch function is noticeably slower as well. */ if (numCatalogIds <= 0) return NULL; low = catalogIdMap; high = catalogIdMap + (numCatalogIds - 1); while (low <= high) { DumpableObject **middle; int difference; middle = low + (high - low) / 2; /* comparison must match DOCatalogIdCompare, below */ difference = oidcmp((*middle)->catId.oid, catalogId.oid); if (difference == 0) difference = oidcmp((*middle)->catId.tableoid, catalogId.tableoid); if (difference == 0) return *middle; else if (difference < 0) low = middle + 1; else high = middle - 1; } return NULL;}static intDOCatalogIdCompare(const void *p1, const void *p2){ DumpableObject *obj1 = *(DumpableObject **) p1; DumpableObject *obj2 = *(DumpableObject **) p2; int cmpval; /* * Compare OID first since it's usually unique, whereas there will only be * a few distinct values of tableoid. */ cmpval = oidcmp(obj1->catId.oid, obj2->catId.oid); if (cmpval == 0) cmpval = oidcmp(obj1->catId.tableoid, obj2->catId.tableoid); return cmpval;}/* * Build an array of pointers to all known dumpable objects * * This simply creates a modifiable copy of the internal map. */voidgetDumpableObjects(DumpableObject ***objs, int *numObjs){ int i, j; *objs = (DumpableObject **) malloc(allocedDumpIds * sizeof(DumpableObject *)); if (*objs == NULL) exit_horribly(NULL, NULL, "out of memory\n"); j = 0; for (i = 1; i < allocedDumpIds; i++) { if (dumpIdMap[i]) (*objs)[j++] = dumpIdMap[i]; } *numObjs = j;}/* * Add a dependency link to a DumpableObject * * Note: duplicate dependencies are currently not eliminated */voidaddObjectDependency(DumpableObject *dobj, DumpId refId){ if (dobj->nDeps >= dobj->allocDeps) { if (dobj->allocDeps <= 0) { dobj->allocDeps = 16; dobj->dependencies = (DumpId *) malloc(dobj->allocDeps * sizeof(DumpId)); } else { dobj->allocDeps *= 2; dobj->dependencies = (DumpId *) realloc(dobj->dependencies, dobj->allocDeps * sizeof(DumpId)); } if (dobj->dependencies == NULL) exit_horribly(NULL, NULL, "out of memory\n"); } dobj->dependencies[dobj->nDeps++] = refId;}/* * Remove a dependency link from a DumpableObject * * If there are multiple links, all are removed */voidremoveObjectDependency(DumpableObject *dobj, DumpId refId){ int i; int j = 0; for (i = 0; i < dobj->nDeps; i++) { if (dobj->dependencies[i] != refId) dobj->dependencies[j++] = dobj->dependencies[i]; } dobj->nDeps = j;}/* * findTableByOid * finds the entry (in tblinfo) of the table with the given oid * returns NULL if not found * * NOTE: should hash this, but just do linear search for now */TableInfo *findTableByOid(Oid oid){ int i; for (i = 0; i < numTables; i++) { if (tblinfo[i].dobj.catId.oid == oid) return &tblinfo[i]; } return NULL;}/* * findTypeByOid * finds the entry (in typinfo) of the type with the given oid * returns NULL if not found * * NOTE: should hash this, but just do linear search for now */TypeInfo *findTypeByOid(Oid oid){ int i; for (i = 0; i < numTypes; i++) { if (typinfo[i].dobj.catId.oid == oid) return &typinfo[i]; } return NULL;}/* * findFuncByOid * finds the entry (in funinfo) of the function with the given oid * returns NULL if not found * * NOTE: should hash this, but just do linear search for now */FuncInfo *findFuncByOid(Oid oid){ int i; for (i = 0; i < numFuncs; i++) { if (funinfo[i].dobj.catId.oid == oid) return &funinfo[i]; } return NULL;}/* * findOprByOid * finds the entry (in oprinfo) of the operator with the given oid * returns NULL if not found * * NOTE: should hash this, but just do linear search for now */OprInfo *findOprByOid(Oid oid){ int i; for (i = 0; i < numOperators; i++) { if (oprinfo[i].dobj.catId.oid == oid) return &oprinfo[i]; } return NULL;}/* * findParentsByOid * find a table's parents in tblinfo[] */static voidfindParentsByOid(TableInfo *self, InhInfo *inhinfo, int numInherits){ Oid oid = self->dobj.catId.oid; int i, j; int numParents; numParents = 0; for (i = 0; i < numInherits; i++) { if (inhinfo[i].inhrelid == oid) numParents++; } self->numParents = numParents; if (numParents > 0) { self->parents = (TableInfo **) malloc(sizeof(TableInfo *) * numParents); j = 0; for (i = 0; i < numInherits; i++) { if (inhinfo[i].inhrelid == oid) { TableInfo *parent; parent = findTableByOid(inhinfo[i].inhparent); if (parent == NULL) { write_msg(NULL, "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found\n", inhinfo[i].inhparent, self->dobj.name, oid); exit_nicely(); } self->parents[j++] = parent; } } } else self->parents = NULL;}/* * parseOidArray * parse a string of numbers delimited by spaces into a character array * * Note: actually this is used for both Oids and potentially-signed * attribute numbers. This should cause no trouble, but we could split * the function into two functions with different argument types if it does. */voidparseOidArray(const char *str, Oid *array, int arraysize){ int j, argNum; char temp[100]; char s; argNum = 0; j = 0; for (;;) { s = *str++; if (s == ' ' || s == '\0') { if (j > 0) { if (argNum >= arraysize) { write_msg(NULL, "could not parse numeric array: too many numbers\n"); exit_nicely(); } temp[j] = '\0'; array[argNum++] = atooid(temp); j = 0; } if (s == '\0') break; } else { if (!(isdigit((unsigned char) s) || s == '-') || j >= sizeof(temp) - 1) { write_msg(NULL, "could not parse numeric array: invalid character in number\n"); exit_nicely(); } temp[j++] = s; } } while (argNum < arraysize) array[argNum++] = InvalidOid;}/* * strInArray: * takes in a string and a string array and the number of elements in the * string array. * returns the index if the string is somewhere in the array, -1 otherwise */static intstrInArray(const char *pattern, char **arr, int arr_size){ int i; for (i = 0; i < arr_size; i++) { if (strcmp(pattern, arr[i]) == 0) return i; } return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -