MCPcopy Create free account
hub / github.com/apple/foundationdb / write_impl

Method write_impl

fdbserver/VersionedBTree.actor.cpp:856–952  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

854
855 // Write item to the next position in the current page or, if it won't fit, add a new page and write it there.
856 ACTOR static Future<Void> write_impl(Cursor* self, T item) {
857 ASSERT(self->mode == WRITE);
858
859 state FlowMutex::Lock lock;
860 state bool mustWait = self->isBusy();
861 state int bytesNeeded = Codec::bytesNeeded(item);
862 state bool needNewPage =
863 self->pageID == invalidPhysicalPageID || self->offset + bytesNeeded > self->header()->itemSpace;
864
865 if (g_network->isSimulated()) {
866 // Sometimes (1% probability) decide a new page is needed as long as at least 1 item has been
867 // written (indicated by non-zero offset) to the current page.
868 if ((self->offset > 0) && deterministicRandom()->random01() < 0.01) {
869 needNewPage = true;
870 }
871 }
872
873 debug_printf("FIFOQueue::Cursor(%s) write(%s) mustWait=%d needNewPage=%d\n",
874 self->toString().c_str(),
875 ::toString(item).c_str(),
876 mustWait,
877 needNewPage);
878
879 // If we have to wait for the mutex because it's busy, or we need a new page, then wait for the mutex.
880 if (mustWait || needNewPage) {
881 FlowMutex::Lock _lock = wait(self->mutex.take());
882 lock = _lock;
883
884 // If we had to wait because the mutex was busy, then update needNewPage as another writer
885 // would have changed the cursor state
886 // Otherwise, taking the mutex would be immediate so no other writer could have run
887 if (mustWait) {
888 needNewPage =
889 self->pageID == invalidPhysicalPageID || self->offset + bytesNeeded > self->header()->itemSpace;
890 if (g_network->isSimulated()) {
891 // Sometimes (1% probability) decide a new page is needed as long as at least 1 item has been
892 // written (indicated by non-zero offset) to the current page.
893 if ((self->offset > 0) && deterministicRandom()->random01() < 0.01) {
894 needNewPage = true;
895 }
896 }
897 }
898 }
899
900 // If we need a new page, add one.
901 if (needNewPage) {
902 debug_printf("FIFOQueue::Cursor(%s) write(%s) page is full, adding new page\n",
903 self->toString().c_str(),
904 ::toString(item).c_str());
905 state PhysicalPageID newPageID;
906 // If this is an extent based queue, check if there is an available page in current extent
907 if (self->queue->usesExtents) {
908 bool allocateNewExtent = false;
909 if (self->pageID != invalidPhysicalPageID) {
910 auto praw = self->header();
911 if (praw->extentCurPageID < praw->extentEndPageID) {
912 newPageID = praw->extentCurPageID + 1;
913 } else {

Callers

nothing calls this directly

Calls 14

isBusyMethod · 0.95
headerMethod · 0.95
toStringMethod · 0.95
addNewPageMethod · 0.95
deterministicRandomFunction · 0.85
delayFunction · 0.85
random01Method · 0.80
toStringFunction · 0.70
VoidClass · 0.50
isSimulatedMethod · 0.45
c_strMethod · 0.45
takeMethod · 0.45

Tested by

no test coverage detected