summaryrefslogtreecommitdiff
path: root/storage/connect/filamap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'storage/connect/filamap.cpp')
-rw-r--r--storage/connect/filamap.cpp198
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