int main(void) { Node *head = 0; head = addNodeAtHead(head, 23); head = addNodeAtHead(head, 43); head = addNodeAtHead(head, 73); head = addNodeAtHead(head, 13); head = addNodeAtHead(head, 33); dumpList("Completed", head); head = removeNode(head, 33); dumpList("Remove 33", head); head = removeNode(head, 23); dumpList("Remove 23", head); head = removeNode(head, 13); dumpList("Remove 13", head); head = removeNode(head, 34); dumpList("Remove 34", head); head = removeNode(head, 43); dumpList("Remove 43", head); head = removeNode(head, 73); dumpList("Remove 73", head); head = removeNode(head, 37); dumpList("Remove 37", head); return 0; }
// // CPreferenceFile // // A File comprised of CPreference Items // // This is a textfile implementation in the format: // // [Section1Identifier] // PreferenceItem PreferenceValue // // [Section2Identifier] // PreferenceItem PreferenceValue // CPreferenceFile::CPreferenceFile(const char *inFileName) { fFileName = strdup(inFileName); m_list = NULL; fModified = FALSE; Load(); #ifdef DEBUG qDebug("Loaded Preferences:"); dumpList(m_list); #endif } // end Constructor
/** * Deletes the first occurrence of name that matches the movie's title from the * given list * @param movieNode The list of movies to find and remove the node from * @param name The name of the movie to remove */ void deleteMovie(MovieNodeType **list, char *title) { fprintf(outputFile, "* Entering DeleteMovie *\n"); dumpList(*list); MovieNodeType *current = *list; while (current != NULL) { int compare = strcmp(current->data->title, title); if (compare == 0) { // if removing from the beginning if (current->prev == NULL) { *list = current->next; } else { current->prev->next = current->next; } // if removing from the end if (current->next != NULL) { current->next->prev = current->prev; } current->next = NULL; current->prev = NULL; freeNodeAndData(current); dumpList(*list); fprintf(outputFile, "* Leaving DeleteMovie *\n"); return; } else { current = current->next; } } dumpList(*list); fprintf(outputFile, "* Leaving DeleteMovie *\n"); return; }
int main() { ListNode *node = new ListNode(2); ListNode *l1 = node; node->next = new ListNode(4); node = node->next; node->next = new ListNode(3); node = new ListNode(5); ListNode *l2 = node; node->next = new ListNode(6); node = node->next; node->next = new ListNode(4); Solution_1 slu1; dumpList(slu1.addTwoNumbers(l1, l2)); Solution_2 slu2; dumpList(slu2.addTwoNumbers(l1, l2)); return 0; }
GCHeap::~GCHeap() { printf( "waiting for others to complete\n" ); printf( "Total number of allocations: %d\n", mNumTotalAllocations ); printf( "Max size of heap: %d\n", mMaxSize ); if ( !mObjects.empty() ) { printf( "LEAKED, %d objects, totaling %d bytes\n", mNumCurrentAllocations, mCurrentSize ); printf( "The following objects have been leaked\n" ); dumpList(); } }
int main(int argc, const char * argv[]) { LinkN *null = NULL; LinkN **head = &null; const size_t COUNT = 37; size_t *data = SafeMalloc(COUNT * sizeof(size_t)), i; LinkN *nodes = SafeMalloc(COUNT * sizeof(LinkN)); rb_red_blk_tree tree; RBTreeInit(&tree, &pointerDiff, NULL, &RBNodeAlloc); for(i = 0; i < COUNT; i++){ data[i] = i; nodes[i].data = data + i; linkFront(head, nodes + i); } dumpList(head); mergeSort(head, &csT); dumpList(head); qsort(data, 0, COUNT, &qsCompare); dumpArray(data, COUNT); for(i = 0; i < COUNT; i++){ RBSetAdd(&tree, data + i); } dumpSet(&tree); dPrintf(("%p - %p = " PDF " ?= (-1 * " PDF ")\n",(void*)&data[2],(void*)&data[3],(&data[2] - &data[3]),(&data[3] - &data[2]))); dPrintf(("\t ?= %d ?= (-1 * %d)\n",pointerDiff(&data[2], &data[3]),pointerDiff(&data[3], &data[2]))); free(nodes); free(data); return 0; }
//!----------------------------------- void removeList(header_t *Head) { assert_ok(Head != NULL); listElem_t * work = Head->theFirst; for (int i = 2; i < Head->ListLen; i++) { assert(2 <= i && i <= Head->ListLen); dtor(work->prev, Head); work = work->next; } work = NULL; free(Head); dumpList(Head); }
/** * Prints in terminal a human readable representation of the hash-list. * * @param hl A hash-list structure */ void hl_print(HashList *hl) { int i = 0, n = hl->size; List *l; printf("[\n"); for ( ; i < n ; i++ ) { l = &(hl->buckets[i]); printf(" [%3d] List[%d] {\n", i, l->numItems); dumpList(l); printf(" }\n"); } printf("]\n"); }
//!----------------------------------- void insert_in(dataType value, int position, int orientation, header_t *Head) { assert_ok(List_ok(Head) == NULL); assert_ok(position <= Head->ListLen); listElem_t *work = Head->theFirst; for (int i = 1; i < position; i++) { assert(1 <= i && i < position); work = work->next; } listElem_t *target = ctor(); target->data = value; if (orientation == LEFT) { listElem_t *previous = work->prev; //printf("previous [0x%p]\n", previous); if (previous != NULL) previous->next = target; if (previous == NULL) Head->theFirst = target; target->prev = previous; target->next = work; work->prev = target; Head->ListLen += 1; } if (orientation == RIGHT) { listElem_t * theNext = work->next; work->next = target; target->prev = work; target->next = theNext; if (theNext != NULL) theNext->prev = target; if (theNext == NULL) Head->theLast = target; Head->ListLen += 1; } dumpList(Head); assert_ok(List_ok(Head) == NULL); }
void CppContainer::dump(std::ostream & os, int level) const { int newLevel = level + 1; dumpList(this->namespaceList, os, newLevel); dumpList(this->classList, os, newLevel); dumpList(this->fieldList, os, newLevel); dumpList(this->methodList, os, newLevel); dumpList(this->enumList, os, newLevel); dumpList(this->operatorList, os, newLevel); }
int main(int argc, const char* argv[]) { mamaCaptureConfig mCapture = NULL; mamaCaptureList mCaptureList = NULL; mamaCaptureConfig_create (&mCapture); if (mCapture == NULL) { mama_log (MAMA_LOG_LEVEL_NORMAL, "Allocation of memory for capture failed!!!!"); exit (1); } gCapture = &mCapture; parseCommandLine (mCapture , &mCaptureList, argc, argv); /*Set up a signal handler so that we don't just stop without cleaning up*/ gCaptureList = &mCaptureList; initializeMama (mCapture); mamaCaptureList_parseCommandInput (mCapture, mCaptureList, gSource); mamaCapture_openFile (&mCapture->myCapture, mCapture->myCaptureFilename); buildDataDictionary(mCapture); dumpDataDictionary (mCapture); if (mCapture->myDumpList) { dumpList (mCaptureList); } subscribeToSymbols (mCapture,mCaptureList); mama_logStdout (MAMA_LOG_LEVEL_NORMAL, "Type CTRL-C to exit.\n\n"); mama_start (mCapture->myBridge); mamaCapture_closeFile(mCapture->myCapture); msshutdown (mCapture,mCaptureList); return 0; }
// . return false if blocked, otherwise true // . sets g_errno on error bool RdbMerge::resumeMerge ( ) { // return true if not suspended if ( ! m_isSuspended ) return true; // turn off the suspension so getNextList() will work m_isSuspended = false; // the usual loop loop: // . this returns false if blocked, true otherwise // . sets g_errno on error // . we return true if it blocked if ( ! getNextList ( ) ) return false; // if g_errno is out of memory then msg3 wasn't able to get the lists // so we should sleep and retry... // or if no thread slots were available... if ( g_errno == ENOMEM || g_errno == ENOTHREADSLOTS ) { doSleep(); return false; } // if list is empty or we had an error then we're done if ( g_errno || m_doneMerging ) { doneMerging(); return true; } // . otherwise dump the list we read to our target file // . this returns false if blocked, true otherwise if ( ! dumpList ( ) ) return false; // repeat ad nauseam goto loop; }
void paintCode(pPdf417param p) { pdf417class pp; arrayList list; int maxErr, fixedColumn, lenErr, tot, skipRowColAdjust, pad; pp.param = p; p->error = 0; if (p->options & PDF417_USE_RAW_CODEWORDS) { if (p->lenCodewords > MAX_DATA_CODEWORDS || p->lenCodewords < 1 || p->lenCodewords != p->codewords[0]) { p->error = PDF417_ERROR_INVALID_PARAMS; return; } } else { if (p->lenText < 0) p->lenText = strlen(p->text); if (p->lenText > ABSOLUTE_MAX_TEXT_SIZE) { p->error = PDF417_ERROR_TEXT_TOO_BIG; return; } listInit(&list); breakString(&pp, &list); dumpList(&pp, &list); assemble(&pp, &list); listFree(&list); if (p->error) return; p->codewords[0] = p->lenCodewords = pp.cwPtr; } maxErr = maxPossibleErrorLevel(MAX_DATA_CODEWORDS + 2 - p->lenCodewords); if (!(p->options & PDF417_USE_ERROR_LEVEL)) { if (p->lenCodewords < 41) p->errorLevel = 2; else if (p->lenCodewords < 161) p->errorLevel = 3; else if (p->lenCodewords < 321) p->errorLevel = 4; else p->errorLevel = 5; } if (p->errorLevel < 0) p->errorLevel = 0; else if (p->errorLevel > maxErr) p->errorLevel = maxErr; if (p->codeColumns < 1) p->codeColumns = 1; else if (p->codeColumns > 30) p->codeColumns = 30; if (p->codeRows < 3) p->codeRows = 3; else if (p->codeRows > 90) p->codeRows = 90; lenErr = 2 << p->errorLevel; fixedColumn = !(p->options & PDF417_FIXED_ROWS); skipRowColAdjust = 0; tot = p->lenCodewords + lenErr; if (p->options & PDF417_FIXED_RECTANGLE) { tot = p->codeColumns * p->codeRows; if (tot > MAX_DATA_CODEWORDS + 2) { tot = getMaxSquare(p); } if (tot < p->lenCodewords + lenErr) tot = p->lenCodewords + lenErr; else skipRowColAdjust = 1; } else if (!(p->options & (PDF417_FIXED_COLUMNS | PDF417_FIXED_ROWS))) { double c, b; fixedColumn = 1; if (p->aspectRatio < 0.001) p->aspectRatio = 0.001f; else if (p->aspectRatio > 1000) p->aspectRatio = 1000; b = 73 * p->aspectRatio - 4; c = (-b + sqrt(b * b + 4 * 17 * p->aspectRatio * (p->lenCodewords + lenErr) * p->yHeight)) / (2 * 17 * p->aspectRatio); p->codeColumns = (int)(c + 0.5); if (p->codeColumns < 1) p->codeColumns = 1; else if (p->codeColumns > 30) p->codeColumns = 30; } if (!skipRowColAdjust) { if (fixedColumn) { p->codeRows = (tot - 1) / p->codeColumns + 1; if (p->codeRows < 3) p->codeRows = 3; else if (p->codeRows > 90) { p->codeRows = 90; p->codeColumns = (tot - 1) / 90 + 1; } } else { p->codeColumns = (tot - 1) / p->codeRows + 1; if (p->codeColumns > 30) { p->codeColumns = 30; p->codeRows = (tot - 1) / 30 + 1; } } tot = p->codeRows * p->codeColumns; } if (tot > MAX_DATA_CODEWORDS + 2) { tot = getMaxSquare(p); } p->errorLevel = maxPossibleErrorLevel(tot - p->lenCodewords); lenErr = 2 << p->errorLevel; pad = tot - lenErr - p->lenCodewords; pp.cwPtr = p->lenCodewords; while (pad--) p->codewords[pp.cwPtr++] = TEXT_MODE; p->codewords[0] = p->lenCodewords = pp.cwPtr; calculateErrorCorrection(&pp, pp.param->lenCodewords); pp.param->lenCodewords = tot; outPaintCode(&pp); }
//!----------------------------------- void remove_in(int position, int orientation, header_t *Head) { assert_ok(List_ok(Head) == NULL); assert_ok(position <= Head->ListLen); assert_ok(orientation == LEFT || orientation == RIGHT); listElem_t *work = Head->theFirst; for (int i = 1; i < position; i++) { assert(1 <= i && i < position); work = work->next; } if (Head->ListLen == 1) { printf("Unable to delete!\n"); exit(3); } if (orientation == LEFT) { if (work->prev == NULL) { printf("FAIL! You are trying to delete unexisted element\n"); return; } listElem_t *previous = work->prev; if (previous == Head->theFirst) { Head->theFirst = work; work->prev = NULL; dtor(previous, Head); Head->ListLen -= 1; dumpList(Head); return; } work->prev = previous->prev; previous->prev->next = work; dtor(previous, Head); Head->ListLen -= 1; } if (orientation == RIGHT) { if (work->next == NULL) { printf("ERROR! You are trying to delete unexisted element!\n"); exit(1); } listElem_t * theNext = work->next; if (theNext == Head->theLast) { Head->theLast = work; work->next = NULL; dtor(theNext, Head); Head->ListLen -= 1; dumpList(Head); return; } work->next = theNext->next; theNext->next->prev = work; dtor(theNext, Head); Head->ListLen -= 1; } else { printf("ERROR! WRONG ORIENTATION!\n"); exit(2); } assert_ok(List_ok(Head) == NULL); dumpList(Head); }
bool palListTest() { palList<int> il; il.SetAllocator(g_DefaultHeapAllocator); dumpList(il); il.PushFront(4); dumpList(il); il.PushFront(5); dumpList(il); il.PushFront(6); dumpList(il); il.PushFront(9); dumpList(il); il.PushFront(13); dumpList(il); il.PopFront(); dumpList(il); il.PopBack(); dumpList(il); il.Remove(6); dumpList(il); #if 0 palList<int> il_spliced_head; il_spliced_head.SetAllocator(g_DefaultHeapAllocator); il_spliced_head.PushFront(9); il_spliced_head.PushBack(21); palList<int> il_spliced_tail; il_spliced_tail.SetAllocator(g_DefaultHeapAllocator); il_spliced_tail.PushFront(99); il_spliced_tail.PushBack(13); printf("head:\n"); dumpList(il_spliced_head); printf("tail:\n"); dumpList(il_spliced_tail); il.SpliceHead(&il_spliced_head); dumpList(il); il.SpliceTail(&il_spliced_tail); dumpList(il); #endif #if 0 palList<int> sublist; il.MakeSublist(&sublist, p_21, p_99); printf("original:\n"); dumpList(il); printf("sublist:\n"); dumpList(sublist); #endif return true; }
void main(void) { int i,count; MyNode *n1,*middle,*beforeMiddle,*last; cout << "Memory at start: " << coreleft() << " bytes\n"; // Create a linked list of 10 nodes adding at the head of the list. for (i = 0; i < 10; i++) { n1 = new MyNode(i); l.addToHead(n1); if (i == 0) last = n1; if (i == 5) beforeMiddle = n1; if (i == 4) middle = n1; } cout << "Memory after creating list: " << coreleft() << " bytes\n"; dumpList(l); // Add a new node after the head of the list and after a middle node n1 = new MyNode(20); l.addAfter(n1,l.peekHead()); n1 = new MyNode(21); l.addAfter(n1,last); n1 = new MyNode(22); l.addAfter(n1,middle); dumpList(l); // Remove the middle object from the list using beforeMiddle as the // previous node in the list. delete l.removeNext(beforeMiddle); dumpList(l); // Remove all remaining nodes with removeFromHead(). count = l.numberOfItems(); for (i = 0; i < count+5; i++) delete l.removeFromHead(); dumpList(l); cout << "Memory: " << coreleft() << " bytes\n"; for (i = 0; i < 10; i++) { n1 = new MyNode(i); l.addToHead(n1); } // Display the list using iterators to move through the list. SimpleListIterator<MyNode> it1; for (it1 = l; it1; it1++) cout << it1.node()->id() << " "; cout << endl; for (it1.restart(); it1;) cout << it1++->id() << " "; cout << endl; l.empty(); cout << "Memory at end: " << coreleft() << " bytes\n\n"; }
void GFF3Dumper::dumpField(const Aurora::GFF3Struct &strct, const Common::UString &field) { Aurora::GFF3Struct::FieldType type = strct.getType(field); Common::UString typeName; if (((size_t) type) < ARRAYSIZE(kGFF3FieldTypeNames)) typeName = kGFF3FieldTypeNames[(int)type]; else typeName = "filetype" + Common::composeString((uint64) type); Common::UString label = field; // Structs already open their own tag if (type != Aurora::GFF3Struct::kFieldTypeStruct) { _xml->openTag(typeName); _xml->addProperty("label", label); } switch (type) { case Aurora::GFF3Struct::kFieldTypeChar: _xml->setContents(Common::composeString(strct.getUint(field))); break; case Aurora::GFF3Struct::kFieldTypeByte: case Aurora::GFF3Struct::kFieldTypeUint16: case Aurora::GFF3Struct::kFieldTypeUint32: case Aurora::GFF3Struct::kFieldTypeUint64: _xml->setContents(Common::composeString(strct.getUint(field))); break; case Aurora::GFF3Struct::kFieldTypeSint16: case Aurora::GFF3Struct::kFieldTypeSint32: case Aurora::GFF3Struct::kFieldTypeSint64: _xml->setContents(Common::composeString(strct.getSint(field))); break; case Aurora::GFF3Struct::kFieldTypeFloat: case Aurora::GFF3Struct::kFieldTypeDouble: _xml->setContents(Common::UString::format("%.6f", strct.getDouble(field))); break; case Aurora::GFF3Struct::kFieldTypeStrRef: _xml->setContents(strct.getString(field)); break; case Aurora::GFF3Struct::kFieldTypeExoString: case Aurora::GFF3Struct::kFieldTypeResRef: try { _xml->setContents(strct.getString(field)); } catch (...) { _xml->addProperty("base64", "true"); Common::SeekableReadStream *data = strct.getData(field); _xml->setContents(*data); delete data; } break; case Aurora::GFF3Struct::kFieldTypeLocString: { Aurora::LocString locString; strct.getLocString(field, locString); _xml->addProperty("strref", Common::composeString(locString.getID())); dumpLocString(locString); } break; case Aurora::GFF3Struct::kFieldTypeVoid: _xml->setContents(*strct.getData(field)); break; case Aurora::GFF3Struct::kFieldTypeStruct: dumpStruct(strct.getStruct(field), label); break; case Aurora::GFF3Struct::kFieldTypeList: dumpList(strct.getList(field)); break; case Aurora::GFF3Struct::kFieldTypeOrientation: { double a = 0.0, b = 0.0, c = 0.0, d = 0.0; strct.getOrientation(field, a, b, c, d); _xml->breakLine(); _xml->openTag("double"); _xml->setContents(Common::UString::format("%.6f", a)); _xml->closeTag(); _xml->breakLine(); _xml->openTag("double"); _xml->setContents(Common::UString::format("%.6f", b)); _xml->closeTag(); _xml->breakLine(); _xml->openTag("double"); _xml->setContents(Common::UString::format("%.6f", c)); _xml->closeTag(); _xml->breakLine(); _xml->openTag("double"); _xml->setContents(Common::UString::format("%.6f", d)); _xml->closeTag(); _xml->breakLine(); } break; case Aurora::GFF3Struct::kFieldTypeVector: { double x = 0.0, y = 0.0, z = 0.0; strct.getVector(field, x, y, z); _xml->breakLine(); _xml->openTag("double"); _xml->setContents(Common::UString::format("%.6f", x)); _xml->closeTag(); _xml->breakLine(); _xml->openTag("double"); _xml->setContents(Common::UString::format("%.6f", y)); _xml->closeTag(); _xml->breakLine(); _xml->openTag("double"); _xml->setContents(Common::UString::format("%.6f", z)); _xml->closeTag(); _xml->breakLine(); } break; default: break; } // Structs already close their own tag if (type != Aurora::GFF3Struct::kFieldTypeStruct) { _xml->closeTag(); _xml->breakLine(); } }
// // Save() // // Save values from cache to file // void CPreferenceFile::Save() { #ifdef DEBUG printf("CPreferenceFile::Save() %s\n", fModified?"Modified":"Not Modified"); dumpList(m_list); #endif if (fModified) { FILE *in; FILE *out; char msg[MAXLEN]; char *p; int count = 0; bool bQuoted = FALSE; bool bSaved = FALSE; // Open source and destination files char *outfilename = NULL; const char *infilename = fFileName; outfilename = (char *) malloc(strlen(infilename) + 64); sprintf(outfilename, "%s%s", fFileName, ".new"); in = fopen (infilename, "r"); out = fopen (outfilename, "w+"); if (in == 0) { fprintf (stderr, "Couldn't open current config file. '%s' - %s\n", infilename, strerror(errno)); } if (out == 0) { fprintf (stderr, "Couldn't open new config file. '%s' - %s\n", outfilename, strerror(errno)); } else { char *sType = NULL; // build a copy of all the args we want to save CPreferenceList *pTempList = new QList<CPrefItem>; CPrefItem *pref; for( pref = m_list->first(); pref != 0; pref=m_list->next() ) { if (pref->Persistent()) pTempList->append(pref); } #ifdef DEBUGSAVE printf("CPreferenceFile::Save() Saving list:\n"); dumpList(pTempList); #endif if (in) { // Parse source file while (fgets (msg, sizeof(msg), in) != NULL) { // terminate on CF or LF p = index (msg, '\n'); if (p) *p = 0; p = index (msg, '\r'); if (p) *p = 0; // end of section - dump all items left in list that belong here if (sType && !msg[0]) { bool bRemoved; do { bRemoved = FALSE; // done copying filters that existed in file already // dump whatever is left in list for( pref = pTempList->first(); pref != 0; pref = pTempList->next() ) { char *tempStr = strdup(pref->Identifier()); // p = index(tempStr, '_'); p = rindex(tempStr, '_'); if (p) *p++ = 0; if (!strcasecmp(sType, tempStr)) { struct timeval tv; if (!gettimeofday(&tv, NULL)) fprintf(out, "%s\t%s\t# Added %s", p, pref->Text(), ctime(&tv.tv_sec)); else fprintf(out, "%s\t%s\t# Added\n", p,pref->Text()); #ifdef DEBUGSAVE fprintf(stdout, "CPreferenceFile::Save(): '%s\t%s' - added\n", pref->Identifier(), pref->Text()); #endif count++; pTempList->remove(pref); bRemoved = TRUE; break; // repeat search for more to remove } // if this belongs in this section } // end for all prefs in unsaved list } while (bRemoved); free(sType); sType = 0; } // end if end of section // Check for section name if (msg[0] == '[') { p = index(msg, ']'); if (p) *p = 0; p = index(msg, '\r'); if (p) *p = 0; if (sType) free(sType); sType = strdup(msg + 1); fprintf(out, "[%s]", sType); // cr will get tacked on later #ifdef DEBUGSAVE fprintf(stdout, "CPreferenceFile::Save(): '[%s]' - sectionname\n", sType); #endif msg[0] = 0; // skip this line } // end if section name // treat lines beginning with # or ; as comments if ( (msg[0] == '#') || (msg[0] == ';')) { #ifdef DEBUGSAVE fprintf(stdout, "CPreferenceFile::Save(): '%s' - comment\n", msg); #endif fprintf(out, "%s", msg); msg[0] = 0; } // end if comment if (msg[0]) { char *tempstr = strdup(msg); char *valueend = 0; char *name = 0; char *value = 0; char *ioLine = tempstr; // strip leading whitespace from line while(*ioLine && isspace(*ioLine)) ioLine++; name = ioLine; // advance to whitespace while(*ioLine && !isspace(*ioLine)) ioLine++; if(*ioLine) *ioLine++ = 0; // strip whitespace in front of value while(*ioLine && isspace(*ioLine)) ioLine++; value = ioLine; // if value is quoted, parse to end of it bQuoted = FALSE; if (value[0] == '"') { bQuoted = TRUE; value++; char *endquote = index(value, '\"'); if (endquote) { *endquote = 0; ioLine = endquote; } } // advance to whitespace and terminate while(*ioLine && !isspace(*ioLine)) ioLine++; if(*ioLine) *ioLine = 0; // look for a match, if found put it in the file // and remove it from the list char *tempstr1; if (sType) { tempstr1 = (char *) malloc(strlen(sType)+strlen(name)+2); sprintf(tempstr1, "%s_%s", sType, name); } else tempstr1 = strdup(name); bSaved = FALSE; for(pref = pTempList->first();pref != 0;pref=pTempList->next()) { // if this is the same identifier as the one in the file if (!strcmp(pref->Identifier(), tempstr1)) { char *ioLine1 = msg; char *restofline = 0; // everything after value char *whitespace = 0; // start of whitespace after name // advance to text (name) while(*ioLine1 && isspace(*ioLine1)) ioLine1++; // advance to whitespace while(*ioLine1 && !isspace(*ioLine1)) ioLine1++; whitespace = ioLine1; // advance to text (value) while(*ioLine1 && isspace(*ioLine1)) ioLine1++; bQuoted = (ioLine1[0] == '"'); *ioLine1++ = 0; // terminate it if (bQuoted) { char *endquote = index(ioLine1, '\"'); if (endquote) { ioLine1 = endquote; ioLine1++; } } // advance to whitespace while(*ioLine1 && !isspace(*ioLine1)) ioLine1++; restofline = ioLine1; if (!bQuoted) { fprintf(out, "%s%s%s%s\n", name, whitespace, pref->Text(), restofline); #ifdef DEBUGSAVE fprintf(stdout, "CPreferenceFile::Save(): '%s%s%s%s\n' - updated\n", name, whitespace, pref->Text(), restofline); #endif } else { fprintf(out, "%s%s\"%s\"%s\n", name, whitespace, pref->Text(), restofline); #ifdef DEBUGSAVE fprintf(stdout, "CPreferenceFile::Save(): '%s%s%s%s\n' - updated\n", name, whitespace, pref->Text(), restofline); #endif } bSaved = TRUE; count++; pTempList->remove(pref); break; // match found, done looking } // end if match } // end for all entries in temp list // if we didn't find a match, save whatever the line was if (!bSaved) { #ifdef DEBUGSAVE fprintf(stdout, "CPreferenceFile::Save(): '%s\n' - saved non update\n", msg); #endif fprintf(out, "%s\n", msg); } free(tempstr); free(tempstr1); } // end if pref else { fprintf(out, "\n"); } } // end while lines in source file #ifdef DEBUGSAVE printf("\nCPreferenceFile::Save() - done parsing file-saving leftovers\n\n"); dumpList(pTempList); #endif // done copying filters that existed in file already // dump whatever is left in list if (pTempList->count() > 0) { struct timeval tv; if (!gettimeofday(&tv, NULL)) fprintf(out, "\n# Added Items %s", ctime(&tv.tv_sec)); else fprintf(out, "\n# Added Items\n"); for( pref = pTempList->first(); pref != 0; pref = pTempList->next() ) { fprintf(out, "%s\t%s\n", pref->Identifier(), pref->Text()); #ifdef DEBUGSAVE fprintf(stdout, "CPreferenceFile::Save(): '%s\t%s\n", pref->Identifier(), pref->Text()); #endif } // end for all items in remaining list } // if items to be added if (fflush (out)) fprintf (stderr, "Couldn't flush file. '%s' - %s\n", outfilename, strerror(errno)); if (fclose (out)) fprintf (stderr, "Couldn't flush file. '%s' - %s\n", outfilename, strerror(errno)); if (in) fclose (in); // printf ("file saved '%s'\n", outfilename); #if 1 // rename files char *tempstr = (char*) malloc( (strlen(infilename) * 2) + strlen(outfilename) + 25); // should be enough sprintf(tempstr, "cp %s %s.bak", infilename, infilename); #ifdef DEBUG printf("%s\n", tempstr); #endif if (-1 == system(tempstr)) { fprintf(stderr, "'%s' - failed\n", tempstr); } sprintf(tempstr, "mv -f %s %s", outfilename, infilename); #ifdef DEBUG printf("%s\n", tempstr); #endif if (-1 == system(tempstr)) { fprintf(stderr, "'%s' - failed\n", tempstr); } #endif free(tempstr); if (sType) free(sType); } if (outfilename) free(outfilename); } // end else file handles good fModified = FALSE; } // end if modified } // end Save()
/** * Asks the user to add a user specified amount of movies and their respective * data. Adds all movies to the specified movieList * @param movieList The list to add movies to */ void getMovieData(MovieNodeType **movieList) { fprintf(outputFile, "* Entering getMovieData *\n"); dumpList(*movieList); /* * Ask the user how many movies they want to input */ int returnVal, numMovies; const int SCANF_UNSUCCESSFUL = 1; do { printf("Enter the number of movies to be entered: "); returnVal = scanf("%d", &numMovies); clearStdin(); } while (returnVal != SCANF_UNSUCCESSFUL || numMovies < 0); /* * Get the user to input the movie data */ int i = 0; for (i = 0; i < numMovies; ++i) { char title[MAX_STR]; int year; GenreType genre; // get movie name printf("Enter the name of movie %d:\n", i + 1); fgets(title, MAX_STR, stdin); title[strlen(title) - 1] = '\0'; // get movie year do { printf("Enter the year of movie %d:\n", i + 1); returnVal = scanf("%d", &year); clearStdin(); } while (returnVal != SCANF_UNSUCCESSFUL || year < 0); // get movie genre char genreInput[MAX_STR]; do { printf( "Enter the genre of movie %d\nAvailable choices are 'comedy', 'drama', 'action', 'horror', 'science-fiction', 'adventure', 'western':\n", i + 1); fgets(genreInput, MAX_STR, stdin); genreInput[strlen(genreInput) - 1] = '\0'; if (strcmp(genreInput, "comedy") == 0) { genre = C_COMEDY; break; } else if (strcmp(genreInput, "drama") == 0) { genre = C_DRAMA; break; } else if (strcmp(genreInput, "action") == 0) { genre = C_ACTION; break; } else if (strcmp(genreInput, "horror") == 0) { genre = C_HORROR; break; } else if (strcmp(genreInput, "science-fiction") == 0) { genre = C_SF; break; } else if (strcmp(genreInput, "adventure") == 0) { genre = C_ADVENTURE; break; } else if (strcmp(genreInput, "western") == 0) { genre = C_WESTERN; break; } else { continue; } } while (1); // add movie to list MovieType *movie; initMovie(&movie, title, year, genre); addToMovieList(movieList, movie); } dumpList(*movieList); fprintf(outputFile, "* Leaving getMovieData *\n"); }
// . returns false if blocked, true otherwise // . sets g_errno on error // . dumps the RdbTree, m_tree, into m_file // . also sets and writes the RdbMap for m_file // . we methodically get RdbLists from the RdbTree // . dumped recs are ordered by key if "orderedDump" was true in call to set() // otherwise, lists are ordered by node # // . we write each list of recs to the file until the whole tree has been done // . we delete all records in list from the tree after we've written the list // . if a cache was provided we incorporate the list into the cache before // deleting it from the tree to keep the cache in sync. NO we do NOT! // . called again by writeBuf() when it's done writing the whole list bool RdbDump::dumpTree ( bool recall ) { // set up some vars //int32_t nextNode; //key_t maxEndKey; //maxEndKey.setMax(); char maxEndKey[MAX_KEY_BYTES]; KEYMAX(maxEndKey,m_ks); // if dumping statsdb, we can only dump records 30 seconds old or // more because Statsdb.cpp can "back modify" such records in the tree // because it may have a query that took 10 seconds come in then it // needs to add a partial stat to the last 10 stats for those 10 secs. // we use Global time at this juncture if ( m_rdb->m_rdbId == RDB_STATSDB ) { int32_t nowSecs = getTimeGlobal(); StatKey *sk = (StatKey *)maxEndKey; sk->m_zero = 0x01; sk->m_labelHash = 0xffffffff; // leave last 60 seconds in there just to be safe sk->m_time1 = nowSecs - 60; } // this list will hold the list of nodes/recs from m_tree m_list = &m_ourList; // convert coll to collnum //collnum_t collnum = g_collectiondb.getCollnum ( m_coll ); // a collnum of -1 is for collectionless rdbs //if ( collnum < 0 ) { // //if ( g_catdb->getRdb() == m_rdb ) // if ( ! m_rdb->m_isCollectionLess ) { // char *xx=NULL;*xx=0; //return true; // } // g_errno = 0; // collnum = 0; //} // getMemOccupiedForList2() can take some time, so breathe int32_t niceness = 1; loop: // if the lastKey was the max end key last time then we're done if ( m_rolledOver ) return true; // this is set to -1 when we're done with our unordered dump if ( m_nextNode == -1 ) return true; // . NOTE: list's buffer space should be re-used!! (TODO) // . "lastNode" is set to the last node # in the list bool status = true; //if ( ! m_orderedDump ) { // status = ((RdbTree *)m_tree)->getListUnordered ( m_nextNode , // m_maxBufSize , // m_list , // &nextNode ); // // this is -1 when no more nodes are left // m_nextNode = nextNode; //} // "lastKey" is set to the last key in the list //else { { // can we remove neg recs? // class RdbBase *base = m_rdb->getBase(m_collnum); // bool removeNegRecs = false; // if ( base->m_numFiles <= 0 ) removeNegRecs = true; if ( recall ) goto skip; // debug msg //log("RdbDump:: getting list"); m_t1 = gettimeofdayInMilliseconds(); if(m_tree) status = m_tree->getList ( m_collnum , m_nextKey , maxEndKey , m_maxBufSize , // max recSizes m_list , &m_numPosRecs , &m_numNegRecs , m_useHalfKeys , niceness ); else if(m_buckets) status = m_buckets->getList ( m_collnum, m_nextKey , maxEndKey , m_maxBufSize , // max recSizes m_list , &m_numPosRecs , &m_numNegRecs , m_useHalfKeys ); // don't dump out any neg recs if it is our first time dumping // to a file for this rdb/coll. TODO: implement this later. //if ( removeNegRecs ) // m_list.removeNegRecs(); // if(!m_list->checkList_r ( false , // removeNegRecs? // false , // sleep on problem? // m_rdb->m_rdbId )) { // log("db: list to dump is not sane!"); // char *xx=NULL;*xx=0; // } skip: int64_t t2; //key_t lastKey; char *lastKey; // if error getting list (out of memory?) if ( ! status ) goto hadError; // debug msg t2 = gettimeofdayInMilliseconds(); log(LOG_INFO,"db: Get list took %"INT64" ms. " "%"INT32" positive. %"INT32" negative.", t2 - m_t1 , m_numPosRecs , m_numNegRecs ); // keep a total count for reporting when done m_totalPosDumped += m_numPosRecs; m_totalNegDumped += m_numNegRecs; // . check the list we got from the tree for problems // . ensures keys are ordered from lowest to highest as well //#ifdef GBSANITYCHECK if ( g_conf.m_verifyWrites ) { char *s = "none"; if ( m_rdb ) s = getDbnameFromId(m_rdb->m_rdbId); log("dump: verifying list before dumping (rdb=%s)",s); m_list->checkList_r ( false , // removeNegRecs? false , // sleep on problem? m_rdb->m_rdbId ); } // if list is empty, we're done! if ( status && m_list->isEmpty() ) { // consider that a rollover? if ( m_rdb->m_rdbId == RDB_STATSDB ) m_rolledOver = true; return true; } // get the last key of the list lastKey = m_list->getLastKey(); // advance m_nextKey //m_nextKey = lastKey ; //m_nextKey += (uint32_t)1; //if ( m_nextKey < lastKey ) m_rolledOver = true; KEYSET(m_nextKey,lastKey,m_ks); KEYADD(m_nextKey,1,m_ks); if (KEYCMP(m_nextKey,lastKey,m_ks)<0) m_rolledOver = true; // debug msg //log(0,"RdbDump:lastKey.n1=%"UINT32",n0=%"UINT64"",lastKey.n1,lastKey.n0); //log(0,"RdbDump:next.n1=%"UINT32",n0=%"UINT64"",m_nextKey.n1,m_nextKey.n0); } // . return true on error, g_errno should have been set // . this is probably out of memory error if ( ! status ) { hadError: log("db: Had error getting data for dump: %s. Retrying.", mstrerror(g_errno)); // debug msg //log("RdbDump::getList: sleeping and retrying"); // retry for the remaining two types of errors if (!g_loop.registerSleepCallback(1000,this,tryAgainWrapper2)){ log( "db: Retry failed. Could not register callback."); return true; } // wait for sleep return false; } // if list is empty, we're done! if ( m_list->isEmpty() ) return true; // . set m_firstKeyInQueue and m_lastKeyInQueue // . this doesn't work if you're doing an unordered dump, but we should // not allow adds when closing m_lastKeyInQueue = m_list->getLastKey(); //m_firstKeyInQueue = m_list->getCurrentKey(); m_list->getCurrentKey(m_firstKeyInQueue); // . write this list to disk // . returns false if blocked, true otherwise // . sets g_errno on error // . if this blocks it should call us (dumpTree() back) if ( ! dumpList ( m_list , m_niceness , false ) ) return false; // close up shop on a write/dumpList error if ( g_errno ) return true; // . if dumpList() did not block then keep on truckin' // . otherwise, wait for callback of dumpTree() goto loop; }
// . delete list from tree, incorporate list into cache, add to map // . returns false if blocked, true otherwise, sets g_errno on error bool RdbDump::doneDumpingList ( bool addToMap ) { // we can get suspended when gigablast is shutting down, in which // case the map may have been deleted. only RdbMerge suspends its // m_dump class, not Rdb::m_dump. return false so caller nevers // gets called back. we can not resume from this suspension! //if ( m_isSuspended ) return false; // . if error was EFILECLOSE (file got closed before we wrote to it) // then try again. file can close because fd pool needed more fds // . we cannot do this retry in BigFile.cpp because the BigFile // may have been deleted/unlinked from a merge, but we could move // this check to Msg3... and do it for writes, too... // . seem to be getting EBADFD errors now, too (what code is it?) // i don't remember, just do it on *all* errors for now! //if ( g_errno == EFILECLOSED || g_errno == EBADFD ) { if ( g_errno && ! m_isSuspended ) { log(LOG_INFO,"db: Had error dumping data: %s. Retrying.", mstrerror(g_errno)); // . deal with the EBADF bug, it will loop forever on this // . i still don't know how the fd gets closed and s_fds[vfd] // is not set to -1?!?!?! if ( g_errno == EBADF ) { // note it log(LOG_LOGIC,"db: setting fd for vfd to -1."); // mark our fd as not there... //int32_t i=(m_offset-m_bytesToWrite) / MAX_PART_SIZE; // sets s_fds[vfd] to -1 // MDW: no, can't do this now // if ( m_file->m_files[i] ) // releaseVfd ( m_file->m_files[i]->m_vfd ); } //log("RdbDump::doneDumpingList: retrying."); return dumpList ( m_list , m_niceness , true ); } // bail on error if ( g_errno ) { log("db: Had error dumping data: %s.", mstrerror(g_errno)); //log("RdbDump::doneDumpingList: %s",mstrerror(g_errno)); return true; } // . don't delete the list if we were dumping an unordered list // . we only dump unordered lists when we do a save // . it saves time not having to delete the list and it also allows // us to do saves without deleting our data! good! if ( ! m_orderedDump ) return true; //--turn this off until save works // save for verify routine m_addToMap = addToMap; // should we verify what we wrote? useful for preventing disk // corruption from those pesky Western Digitals and Maxtors? if ( g_conf.m_verifyWrites ) { // a debug message, if log disk debug messages is enabled log(LOG_DEBUG,"disk: Verifying %"INT32" bytes written.", m_bytesToWrite); // make a read buf if ( m_verifyBuf && m_verifyBufSize < m_bytesToWrite ) { mfree ( m_verifyBuf , m_verifyBufSize , "RdbDump3" ); m_verifyBuf = NULL; m_verifyBufSize = 0; } if ( ! m_verifyBuf ) { m_verifyBuf = (char *)mmalloc ( m_bytesToWrite , "RdbDump3" ); m_verifyBufSize = m_bytesToWrite; } // out of mem? if so, skip the write verify if ( ! m_verifyBuf ) return doneReadingForVerify(); // read what we wrote bool isDone = m_file->read ( m_verifyBuf , m_bytesToWrite , m_offset - m_bytesToWrite , &m_fstate , this , doneReadingForVerifyWrapper , m_niceness ); // debug msg //log("RdbDump dumped %"INT32" bytes, done=%"INT32"\n", // m_bytesToWrite,isDone); // return false if it blocked if ( ! isDone ) return false; } return doneReadingForVerify(); }
bool RdbDump::doneReadingForVerify ( ) { // if someone reset/deleted the collection we were dumping... CollectionRec *cr = g_collectiondb.getRec ( m_collnum ); // . do not do this for statsdb/catdb which always use collnum of 0 // . RdbMerge also calls us but gives a NULL m_rdb so we can't // set m_isCollectionless to false if ( ! cr && m_doCollCheck ) { g_errno = ENOCOLLREC; // m_file is invalid if collrec got nuked because so did // the Rdbbase which has the files log("db: lost collection while dumping to disk. making " "map null so we can stop."); m_map = NULL; } // see if what we wrote is the same as what we read back if ( m_verifyBuf && g_conf.m_verifyWrites && memcmp(m_verifyBuf,m_buf,m_bytesToWrite) != 0 && ! g_errno ) { log("disk: Write verification of %"INT32" bytes to file %s " "failed at offset=%"INT64". Retrying.", m_bytesToWrite, m_file->getFilename(), m_offset - m_bytesToWrite); // try writing again return dumpList ( m_list , m_niceness , true ); } // time dump to disk (and tfndb bins) int64_t t ; // start timing on first call only if ( m_addToMap ) t = gettimeofdayInMilliseconds(); // sanity check if ( m_list->m_ks != m_ks ) { char *xx = NULL; *xx = 0; } bool triedToFix = false; tryAgain: // . register this with the map now // . only register AFTER it's ALL on disk so we don't get partial // record reads and we don't read stuff on disk that's also in tree // . add the list to the rdb map if we have one // . we don't have maps when we do unordered dumps // . careful, map is NULL if we're doing unordered dump if ( m_addToMap && m_map && ! m_map->addList ( m_list ) ) { // keys out of order in list from tree? if ( g_errno == ECORRUPTDATA ) { log("db: trying to fix tree or buckets"); if ( m_tree ) m_tree->fixTree(); //if ( m_buckets ) m_buckets->fixBuckets(); if ( m_buckets ) { char *xx=NULL;*xx=0; } if ( triedToFix ) { char *xx=NULL;*xx=0; } triedToFix = true; goto tryAgain; } g_errno = ENOMEM; log("db: Failed to add data to map."); // undo the offset update, the write failed, the parent // should retry. i know RdbMerge.cpp does, but not sure // what happens when Rdb.cpp is dumping an RdbTree //m_offset -= m_bytesToWrite ; // this should never happen now since we call prealloc() above char *xx = NULL; *xx = 0; return true; } // debug msg int64_t now = gettimeofdayInMilliseconds(); log(LOG_TIMING,"db: adding to map took %"UINT64" ms" , now - t ); // . Msg5.cpp and RdbList::merge_r() should remove titleRecs // that are not supported by tfndb, so we only need to add tfndb // records at this point to update the tfndb recs to point to the // new tfn we are dumping into for the existing titlerecs // . we just add one tfndb rec per positive titleRec in m_list // . negative TitleRec keys should have had a negative tfndb key // added to tfndb in Rdb.cpp::addRecord() already, and ... // . RdbList::indexMerge_r() will take care of merging properly // so as to not treat the tfn bits as part of the key when comparing // . this will re-call this doneDumpingList(false) if it blocks // . returns false if blocks, true otherwise //if ( ! updateTfndbLoop() ) return false; // . HACK: fix hacked lists before deleting from tree // . iff the first key has the half bit set if ( m_hacked ) { //char tmp[6]; char tmp[MAX_KEY_BYTES]; char *p = m_list->getList() - 6 ; //gbmemcpy ( tmp , p , 6 ); //gbmemcpy ( p , p + 6 , 6 ); //gbmemcpy ( p + 6 , tmp , 6 ); gbmemcpy ( tmp , p , 6 ); gbmemcpy ( p , p + 6 , m_ks-6 ); gbmemcpy ( p + (m_ks-6) , tmp , 6 ); // undo the big hack m_list->m_list = p ; m_list->m_listPtr = p ; // make this work for POSDB... m_list->m_listPtrLo = p + m_ks - 12; m_list->m_listPtrHi = p + m_ks - 6; m_list->m_listSize += 6 ; // hack off the half bit, we're 12 bytes again *p &= 0xfd ; // turn it off again just in case m_hacked = false; } if ( m_hacked12 ) { char tmp[MAX_KEY_BYTES]; char *p = m_list->getList() - 12 ; // swap high 12 bytes with low 6 bytes for first key gbmemcpy ( tmp , p , 12 ); gbmemcpy ( p , p + 12 , 6 ); gbmemcpy ( p + 6, tmp , 12 ); // big hack here m_list->m_list = p ; m_list->m_listPtr = p ; m_list->m_listPtrLo = p + 6; m_list->m_listPtrHi = p + 12; m_list->m_listSize += 12 ; // hack off the half bit, we're 12 bytes again *p &= 0xf9 ; m_hacked12 = false; } // verify keys are in order after we hack it back //if ( m_orderedDump ) m_list->checkList_r ( false , true ); // if we're NOT dumping a tree then return control to RdbMerge if ( ! m_tree && !m_buckets ) return true; // . merge the writeBuf into the cache at this point or after deleting // . m_list should have it's m_lastKey set since we got called from // RdbMerge if m_cache is non-NULL and it called RdbList::merge() // through Msg5 at one point to form this list // . right now i just made this clear the cache... it's easier //if ( m_cache ) m_cache->incorporateList ( m_list , m_dedup , // m_list->getLastKey() ); // . delete these nodes from the tree now that they're on the disk // now that they can be read from list since addList() was called // . however, while we were writing to disk a key that we were // writing could have been deleted from the tree. To prevent // problems we should only delete nodes that are present in tree... // . actually i fixed that problem by not deleting any nodes that // might be in the middle of being dumped // . i changed Rdb::addNode() and Rdb::deleteNode() to do this // . since we made it here m_list MUST be ordered, therefore // let's try the new, faster deleteOrderedList and let's not do // balancing to make it even faster // . balancing will be restored once we're done deleting this list // debug msg //log("RdbDump:: deleting list"); int64_t t1 = gettimeofdayInMilliseconds(); // convert to number, this is -1 if no longer exists //collnum_t collnum = g_collectiondb.getCollnum ( m_coll ); //if ( collnum < 0 && m_rdb->m_isCollectionLess ) { // collnum = 0; // g_errno = 0; //} //m_tree->deleteOrderedList ( m_list , false /*do balancing?*/ ); // tree delete is slow due to checking for leaks, not balancing bool s; if(m_tree) { s = m_tree->deleteList(m_collnum,m_list,true/*do balancing?*/); } else if(m_buckets) { s = m_buckets->deleteList(m_collnum, m_list); } // problem? if ( ! s && ! m_tried ) { m_tried = true; log("db: Corruption in tree detected when dumping to %s. " "Fixing. Your memory had an error. Consider replacing it.", m_file->getFilename()); log("db: was collection restarted/reset/deleted before we " "could delete list from tree? collnum=%"INT32"", (int32_t)m_collnum); // reset error in that case g_errno = 0; // if ( m_rdb && m_rdb->m_rdbId != RDB_DOLEDB ) { // // core now to debug this for sectiondb // char *xx=NULL;*xx=0; // ((RdbTree *)m_tree)->fixTree ( ); // } } // tell rdb he needs saving now //if ( m_rdb ) m_rdb->m_needsSave = true; // debug msg int64_t t2 = gettimeofdayInMilliseconds(); log(LOG_TIMING,"db: dump: deleteList: took %"INT64"",t2-t1); return true; }
/** * dumps the list to the recovery log * expired events are not dumped * @param reason * **/ void straightQueue::dumpQueue( const char* reason ) { int numProcessed = dumpList( &eventList, reason ); listSize -= numProcessed; } // dumpQueue