void DataStream::ReadNextRecordL() { DS_DEBUG_Start(); DS_Debug_Printf0("DataStream::ReadNextRecordL: step 1\n"); if(current_loading_record && current_loading_record->Finished()) { DS_Debug_Printf0("DataStream::ReadNextRecordL: return 1\n"); return; } if(MoreData()) { if(current_loading_record == NULL) { current_loading_record = CreateRecordL(); if(current_loading_record == NULL) return; } DS_Debug_Printf0("DataStream::ReadNextRecordL: step 2\n"); // The status of current_loadint_record is manually checked later. Therefore we can safely ignore OpStatus. OpStatus::Ignore(current_loading_record->ReadRecordFromStreamL(this)); DS_Debug_Printf0("DataStream::ReadNextRecordL: step 3\n"); if(current_loading_record->Finished()) { DS_Debug_Printf0("DataStream::ReadNextRecordL: return 2\n"); return; } } if(!MoreData() && !Active() && current_loading_record) { DS_Debug_Printf0("DataStream::ReadNextRecordL: step 4\n"); DataStream *temp = current_loading_record; ReleaseRecord(current_loading_record); OP_DELETE(temp); } DS_Debug_Printf0("DataStream::ReadNextRecordL: return 3\n"); }
int main() { __esan::HashTable<int, int> IntTable; assert(IntTable.size() == 0); // Test iteration on an empty table. int Count = 0; for (auto Iter = IntTable.begin(); Iter != IntTable.end(); ++Iter, ++Count) { // Empty. } assert(Count == 0); bool Added = IntTable.add(4, 42); assert(Added); assert(!IntTable.add(4, 42)); assert(IntTable.size() == 1); int Value; bool Found = IntTable.lookup(4, Value); assert(Found && Value == 42); // Test iterator. IntTable.lock(); for (auto Iter = IntTable.begin(); Iter != IntTable.end(); ++Iter, ++Count) { assert((*Iter).Key == 4); assert((*Iter).Data == 42); } IntTable.unlock(); assert(Count == 1); assert(Count == IntTable.size()); assert(!IntTable.remove(5)); assert(IntTable.remove(4)); // Test a more complex payload. __esan::HashTable<int, MyDataPayload> DataTable(4); MyDataPayload NewData(new MyData("mystring")); Added = DataTable.add(4, NewData); assert(Added); MyDataPayload FoundData; Found = DataTable.lookup(4, FoundData); assert(Found && strcmp(FoundData.Data->Buf, "mystring") == 0); assert(!DataTable.remove(5)); assert(DataTable.remove(4)); // Test resize. for (int i = 0; i < 4; ++i) { MyDataPayload MoreData(new MyData("delete-at-end")); Added = DataTable.add(i+1, MoreData); assert(Added); assert(!DataTable.add(i+1, MoreData)); } for (int i = 0; i < 4; ++i) { Found = DataTable.lookup(i+1, FoundData); assert(Found && strcmp(FoundData.Data->Buf, "delete-at-end") == 0); } DataTable.lock(); Count = 0; for (auto Iter = DataTable.begin(); Iter != DataTable.end(); ++Iter, ++Count) { int Key = (*Iter).Key; FoundData = (*Iter).Data; assert(Key >= 1 && Key <= 4); assert(strcmp(FoundData.Data->Buf, "delete-at-end") == 0); } DataTable.unlock(); assert(Count == 4); assert(Count == DataTable.size()); // Ensure the iterator supports a range-based for loop. DataTable.lock(); Count = 0; for (auto Pair : DataTable) { assert(Pair.Key >= 1 && Pair.Key <= 4); assert(strcmp(Pair.Data.Data->Buf, "delete-at-end") == 0); ++Count; } DataTable.unlock(); assert(Count == 4); assert(Count == DataTable.size()); // Test payload freeing via smart pointer wrapper. __esan::HashTable<MyDataPayload, MyDataPayload, true> DataKeyTable; MyDataPayload DataA(new MyData("string AB")); DataKeyTable.lock(); Added = DataKeyTable.add(DataA, DataA); assert(Added); Found = DataKeyTable.lookup(DataA, FoundData); assert(Found && strcmp(FoundData.Data->Buf, "string AB") == 0); MyDataPayload DataB(new MyData("string AB")); Added = DataKeyTable.add(DataB, DataB); assert(!Added); DataKeyTable.remove(DataB); // Should free the DataA payload. DataKeyTable.unlock(); // Test custom functors. struct CustomHash { size_t operator()(int Key) const { return Key % 4; } }; struct CustomEqual { bool operator()(int Key1, int Key2) const { return Key1 %4 == Key2 % 4; } }; __esan::HashTable<int, int, false, CustomHash, CustomEqual> ModTable; Added = ModTable.add(2, 42); assert(Added); Added = ModTable.add(6, 42); assert(!Added); fprintf(stderr, "All checks passed.\n"); return 0; }