diff options
Diffstat (limited to 'storage/connect/filamap.cpp')
-rw-r--r-- | storage/connect/filamap.cpp | 198 |
1 files changed, 147 insertions, 51 deletions
diff --git a/storage/connect/filamap.cpp b/storage/connect/filamap.cpp index 1723ee4ac27..c0ca40f4c01 100644 --- a/storage/connect/filamap.cpp +++ b/storage/connect/filamap.cpp @@ -1,11 +1,11 @@ /*********** File AM Map C++ Program Source Code File (.CPP) ***********/ /* PROGRAM NAME: FILAMAP */ /* ------------- */ -/* Version 1.4 */ +/* Version 1.6 */ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 2005-2013 */ +/* (C) Copyright to the author Olivier BERTRAND 2005-2014 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -89,7 +89,7 @@ int MAPFAM::GetFileLength(PGLOBAL g) { int len; - len = (To_Fb) ? To_Fb->Length : TXTFAM::GetFileLength(g); + len = (To_Fb) ? To_Fb->Length : TXTFAM::GetFileLength(g); if (trace) htrc("Mapped file length=%d\n", len); @@ -129,7 +129,7 @@ bool MAPFAM::OpenTableFile(PGLOBAL g) && fp->Count && fp->Mode == mode) break; - if (trace) + if (trace) htrc("Mapping file, fp=%p\n", fp); } else @@ -286,6 +286,16 @@ bool MAPFAM::RecordPos(PGLOBAL g) } // end of RecordPos /***********************************************************************/ +/* Initialize Fpos and Mempos for indexed DELETE. */ +/***********************************************************************/ +int MAPFAM::InitDelete(PGLOBAL g, int fpos, int spos) + { + Fpos = Memory + fpos; + Mempos = Memory + spos; + return RC_OK; + } // end of InitDelete + +/***********************************************************************/ /* Skip one record in file. */ /***********************************************************************/ int MAPFAM::SkipRecord(PGLOBAL g, bool header) @@ -322,8 +332,27 @@ int MAPFAM::ReadBuffer(PGLOBAL g) /*******************************************************************/ /* Record file position in case of UPDATE or DELETE. */ /*******************************************************************/ - Fpos = Mempos; - CurBlk = (int)Rows++; + int rc; + + next: + Fpos = Mempos; + CurBlk = (int)Rows++; + + /*******************************************************************/ + /* Check whether optimization on ROWID */ + /* can be done, as well as for join as for local filtering. */ + /*******************************************************************/ + switch (Tdbp->TestBlock(g)) { + case RC_EF: + return RC_EF; + case RC_NF: + // Skip this record + if ((rc = SkipRecord(g, false)) != RC_OK) + return rc; + + goto next; + } // endswitch rc + } else Placed = false; @@ -380,13 +409,13 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc) } // endif irc - if (Tpos == Spos) + if (Tpos == Spos) { /*******************************************************************/ - /* First line to delete. Move of eventual preceding lines is */ + /* First line to delete. Move of eventual preceeding lines is */ /* not required here, just setting of future Spos and Tpos. */ /*******************************************************************/ - Tpos = Fpos; // Spos is set below - else if ((n = Fpos - Spos) > 0) { + Tpos = Spos = Fpos; + } else if ((n = Fpos - Spos) > 0) { /*******************************************************************/ /* Non consecutive line to delete. Move intermediate lines. */ /*******************************************************************/ @@ -396,7 +425,7 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc) if (trace) htrc("move %d bytes\n", n); - } // endif n + } // endif n if (irc == RC_OK) { Spos = Mempos; // New start position @@ -415,40 +444,46 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc) CloseMemMap(fp->Memory, (size_t)fp->Length); fp->Count = 0; // Avoid doing it twice - /*******************************************************************/ - /* Remove extra records. */ - /*******************************************************************/ - n = Tpos - Memory; + if (!Abort) { + /*****************************************************************/ + /* Remove extra records. */ + /*****************************************************************/ + n = Tpos - Memory; #if defined(WIN32) - DWORD drc = SetFilePointer(fp->Handle, n, NULL, FILE_BEGIN); + DWORD drc = SetFilePointer(fp->Handle, n, NULL, FILE_BEGIN); - if (drc == 0xFFFFFFFF) { - sprintf(g->Message, MSG(FUNCTION_ERROR), - "SetFilePointer", GetLastError()); - CloseHandle(fp->Handle); - return RC_FX; - } // endif + if (drc == 0xFFFFFFFF) { + sprintf(g->Message, MSG(FUNCTION_ERROR), + "SetFilePointer", GetLastError()); + CloseHandle(fp->Handle); + return RC_FX; + } // endif - if (trace) - htrc("done, Tpos=%p newsize=%d drc=%d\n", Tpos, n, drc); + if (trace) + htrc("done, Tpos=%p newsize=%d drc=%d\n", Tpos, n, drc); - if (!SetEndOfFile(fp->Handle)) { - sprintf(g->Message, MSG(FUNCTION_ERROR), - "SetEndOfFile", GetLastError()); - CloseHandle(fp->Handle); - return RC_FX; - } // endif + if (!SetEndOfFile(fp->Handle)) { + sprintf(g->Message, MSG(FUNCTION_ERROR), + "SetEndOfFile", GetLastError()); + CloseHandle(fp->Handle); + return RC_FX; + } // endif - CloseHandle(fp->Handle); #else // UNIX - if (ftruncate(fp->Handle, (off_t)n)) { - sprintf(g->Message, MSG(TRUNCATE_ERROR), strerror(errno)); - close(fp->Handle); - return RC_FX; - } // endif + if (ftruncate(fp->Handle, (off_t)n)) { + sprintf(g->Message, MSG(TRUNCATE_ERROR), strerror(errno)); + close(fp->Handle); + return RC_FX; + } // endif + +#endif // UNIX + } // endif Abort - close(fp->Handle); +#if defined(WIN32) + CloseHandle(fp->Handle); +#else // UNIX + close(fp->Handle); #endif // UNIX } // endif irc @@ -458,10 +493,10 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc) /***********************************************************************/ /* Table file close routine for MAP access method. */ /***********************************************************************/ -void MAPFAM::CloseTableFile(PGLOBAL g) +void MAPFAM::CloseTableFile(PGLOBAL g, bool abort) { PlugCloseFile(g, To_Fb); - To_Fb = NULL; // To get correct file size in Cardinality + To_Fb = NULL; // To get correct file size in Cardinality if (trace) htrc("MAP Close: closing %s count=%d\n", @@ -488,7 +523,7 @@ MBKFAM::MBKFAM(PDOSDEF tdp) : MAPFAM(tdp) Block = tdp->GetBlock(); Last = tdp->GetLast(); Nrec = tdp->GetElemt(); - BlkPos = NULL; + BlkPos = tdp->GetTo_Pos(); CurNum = Nrec; } // end of MBKFAM standard constructor @@ -508,9 +543,7 @@ void MBKFAM::Reset(void) /***********************************************************************/ int MBKFAM::Cardinality(PGLOBAL g) { - // Should not be called in this version - return (g) ? -1 : 0; -//return (g) ? (int)((Block - 1) * Nrec + Last) : 1; + return (g) ? (int)((Block - 1) * Nrec + Last) : 1; } // end of Cardinality /***********************************************************************/ @@ -534,8 +567,49 @@ int MBKFAM::GetRowID(void) /***********************************************************************/ int MBKFAM::ReadBuffer(PGLOBAL g) { - strcpy(g->Message, "This AM cannot be used in this version"); - return RC_FX; + int len; + + /*********************************************************************/ + /* Sequential block reading when Placed is not true. */ + /*********************************************************************/ + if (Placed) { + Placed = false; + } else if (Mempos >= Top) { // Are we at the end of the memory + return RC_EF; + } else if (++CurNum < Nrec) { + Fpos = Mempos; + } else { + /*******************************************************************/ + /* New block. */ + /*******************************************************************/ + CurNum = 0; + + next: + if (++CurBlk >= Block) + return RC_EF; + + /*******************************************************************/ + /* Before reading a new block, check whether block optimization */ + /* can be done, as well as for join as for local filtering. */ + /*******************************************************************/ + switch (Tdbp->TestBlock(g)) { + case RC_EF: + return RC_EF; + case RC_NF: + goto next; + } // endswitch rc + + Fpos = Mempos = Memory + BlkPos[CurBlk]; + } // endif's + + // Immediately calculate next position (Used by DeleteDB) + while (*Mempos++ != '\n') ; // What about Unix ??? + + // Set caller line buffer + len = (Mempos - Fpos) - Ending; + memcpy(Tdbp->GetLine(), Fpos, len); + Tdbp->GetLine()[len] = '\0'; + return RC_OK; } // end of ReadBuffer /***********************************************************************/ @@ -607,6 +681,16 @@ bool MPXFAM::SetPos(PGLOBAL g, int pos) } // end of SetPos /***********************************************************************/ +/* Initialize CurBlk, CurNum, Mempos and Fpos for indexed DELETE. */ +/***********************************************************************/ +int MPXFAM::InitDelete(PGLOBAL g, int fpos, int spos) + { + Fpos = Memory + Headlen + fpos * Lrecl; + Mempos = Fpos + Lrecl; + return RC_OK; + } // end of InitDelete + +/***********************************************************************/ /* ReadBuffer: Read one line for a mapped Fix file. */ /***********************************************************************/ int MPXFAM::ReadBuffer(PGLOBAL g) @@ -618,17 +702,29 @@ int MPXFAM::ReadBuffer(PGLOBAL g) Placed = false; } else if (Mempos >= Top) { // Are we at the end of the memory return RC_EF; - } else if (++CurNum < Nrec) { + } else if (++CurNum < Nrec) { Fpos = Mempos; - } else { + } else { /*******************************************************************/ /* New block. */ /*******************************************************************/ - CurNum = 0; + CurNum = 0; + + next: + if (++CurBlk >= Block) + return RC_EF; + + /*******************************************************************/ + /* Before reading a new block, check whether block optimization */ + /* can be done, as well as for join as for local filtering. */ + /*******************************************************************/ + switch (Tdbp->TestBlock(g)) { + case RC_EF: + return RC_EF; + case RC_NF: + goto next; + } // endswitch rc - if (++CurBlk >= Block) - return RC_EF; - Fpos = Mempos = Headlen + Memory + CurBlk * Blksize; } // endif's |