Package org.xBaseJ.micro.indexes

Source Code of org.xBaseJ.micro.indexes.MDX

package org.xBaseJ.micro.indexes;
/**
*xBaseJ - java access to dBase files
*<p>&copy;Copyright 1997-2006 - American Coders, LTD  - Raleigh NC USA
*<p>All rights reserved
*<p>Currently supports only dBase III format DBF, DBT and NDX files
*<p>                        dBase IV format DBF, DBT, MDX and NDX files

*<p>American Coders, Ltd
*<br>P. O. Box 97462
*<br>Raleigh, NC  27615  USA
*<br>1-919-846-2014
*<br>http://www.americancoders.com
@author Joe McVerry, American Coders Ltd.
@version 3.0.0
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library Lesser General Public
* License along with this library; if not, write to the Free
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
*/

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.StringTokenizer;

import org.xBaseJ.micro.DBF;
import org.xBaseJ.micro.xBaseJException;
import org.xBaseJ.micro.fields.Field;

public class MDX extends Index
{

short tag_pos;
public MDXFile mfile;
TagDescriptor tagDesc;
TagHeader tagHead;

public MDX(MDXFile ifile, DBF iDBF, short ipos) throws xBaseJException, IOException
   {
    int reading;
    String wb;
    MNode lNode = null;
    int Index_record;
    Field field = null;
    database = iDBF;
    mfile = ifile;
    tagDesc =  mfile.getTagDescriptor(ipos);
    dosname = tagDesc.name;
    tagHead = new TagHeader(ifile, (short) tagDesc.indheaderpage);
    key_per_Node = tagHead.key_per_Node;
    key_length = tagHead.key_length;
    nfile = ifile.nfile;
    keyType = (char) tagHead.keyType;

    if ((keyType == 'N'&& (key_length == 12)) keyType = 'F'// now flip to xbasej definition of.
    if (keyType == 'D') keyType = 'N';

    Index_record = (int) tagHead.top_Node;


  reading = Index_record;
  stringKey = new String(tagHead.NDXString);
  StringTokenizer strtok = new StringTokenizer(stringKey, "+");

  while (strtok.hasMoreElements())
  {
   wb = (String) strtok.nextElement();
   wb=wb.trim();
   field = database.getField(wb);
   keyControl.addElement(field);
  }   /* endwhile */


  while (reading > 0)
  {
    if (topNode == null)
    {
      lNode = new MNode(mfile, key_per_Node, key_length, keyType, Index_record, false);
    }
    else
    {
      MNode llNode = new MNode(mfile, key_per_Node, key_length, keyType, Index_record, false);
      lNode.set_prev(llNode);
      lNode = (MNode) llNode;
    }      //  /* endif */
    workNode =  lNode;
    lNode.set_pos(0);
    lNode.read();

    if (reading > 0)
    {//        /* if reading is zero we're still reading Nodes, when < 0 then read
                                 //     * a leaf */
      Index_record = lNode.get_lower_level();
      if (Index_record == 0)
      {
  Index_record = lNode.get_key_record_number();
  reading = 0//  /* read a leaf so last time in loop */
  lNode.set_pos(0);//  /* so sequentially reads get first record */
      }//        /* Index = 0 then it's a leaf pointer */
    }      //  /* reading > 0 */
    if (topNode == null)
      topNode = (MNode) lNode.clone();
  }//        /* endwhile */


   try {dosname = new String(tagDesc.tagname, DBF.encodedType);}
   catch (UnsupportedEncodingException UEE){ dosname = new String(tagDesc.tagname);}

   }

public MDX(String iname, String NDXString,
                  DBF iDBF, MDXFile ifile,
                      TagDescriptor inTagDesc, short pos,
                           boolean unique)
                                                     throws xBaseJException, IOException

   {
    dosname = iname;
    database = iDBF;
    mfile = ifile;
    nfile = ifile.nfile;
    int i = iname.length();
    int j;

  unique_key = (byte) (unique ? 64 : 0);

  if ((i < 1) || (i > 10))
       throw new xBaseJException("Invalid tag name " + iname + " name length incorrect");

  if (!Character.isLetter(iname.charAt(0)))
       throw new xBaseJException("Invalid tag name " + iname + " first character not alphabetic");

  iname = iname.toUpperCase();

  for (j = 1; j < i; j++)
  {
    if (Character.isLetter(iname.charAt(j))
  || (Character.isDigit(iname.charAt(j))
  || (iname.charAt(j) == '_') ) )
      ;
    else
       throw new xBaseJException("Invalid tag name " + iname + " invalid character at position " + (j+1));
   }

  stringKey = new String(NDXString);
  StringTokenizer strtok = new StringTokenizer(NDXString, "+");

  String fname;
  Field ffld;
  char type;

  int keylen = 0;
  keyType = ' ';

  do
  {
    fname = (String) strtok.nextElement();
    ffld = iDBF.getField(fname);
    type = ffld.getType();
    if (type == 'M')
  throw new xBaseJException("Can't make memo field part of a key");
    if (type == 'L')
  throw new xBaseJException("Can't make logical field part of a key");
    if (type == 'F')
  throw new xBaseJException("Can't make float field part of a key");
    if (keyType == ' ')
    {
      keyType = type;
    }
    else
    {
      if (keyType != type)
      {
  keyType = 'C';
      }        /* endif */
    }        /* endif */
    keylen += ffld.getLength();
    keyControl.addElement(ffld);
  } while (strtok.hasMoreElements())/* endwhile */

  if (keyType == 'D')
    keylen = 8;
  if (keyType == 'N')
    keylen = 12;

  int len = (((keylen - 1) / 4) + 1) * 4;
  if (len < 1)
    throw new xBaseJException("Key length too short");

  if (len > 100)
    throw new xBaseJException("Key length too long");

  tagDesc = inTagDesc;
  tagDesc.setKeyType(keyType);
  tagHead = new TagHeader(mfile, (short) tagDesc.indheaderpage, (short) len, keyType, unique);


   if (keyType == 'N') keyType = 'F'// now flip to xbase definition of.
   if (keyType == 'D') keyType = 'N';

  key_length = tagHead.key_length;
  key_per_Node = tagHead.key_per_Node;

  byte kd[];
  try { kd = NDXString.toUpperCase().substring(0, NDXString.length()).getBytes(DBF.encodedType);}
  catch (UnsupportedEncodingException UEE){ kd = NDXString.toUpperCase().substring(0, NDXString.length()).getBytes();}
  for (int x = 0; x < kd.length; x++)
     tagHead.key_definition[x] = kd[x];

  if (database.getRecordCount() > 0)
     reIndex();
  else
   {
        tagDesc.write();
        tagHead.write();
   }


   }

public void set_tag_pos(short pos)
   {
     tag_pos = pos;
   }

public short get_tag_pos()
   {
    return tag_pos;
   }


public void  reIndex() throws   xBaseJException, IOException
{
   int i;
   int reccount = database.getRecordCount();
   NodeKey lastkey;
   BinaryTree  topTree = null;
  if (database.getRecordCount() > 0) {
  database.gotoRecord(1);
  top_Node = 0;

  for (i = 1; i <= reccount; i++)
  {
    lastkey = build_key();
    if (topTree == null)
        topTree = new BinaryTree(lastkey, i, topTree);

    if (i < reccount)
        database.read();
    }
  }

  topNode = null;
  if (database.getRecordCount() > 0)
      reIndexWork(topTree.getLeast(), 0, topTree);
  tagHead.top_Node = top_Node;
  tagHead.write();
  tagDesc.write();
  anchor_write();
}

public int reIndexWork(BinaryTree bt, int level, BinaryTree topTree) throws IOException, xBaseJException
{

int prev_page = 0;
BinaryTree tree2 = null;
int pos = 0;
if (level > 0) prev_page = top_Node;
top_Node = (short) mfile.anchor.get_nextavailable();
workNode = new MNode(mfile, key_per_Node, key_length, keyType, top_Node, level>0);
workNode.set_prev_page(prev_page);
mfile.anchor.update_nextavailable();
tagHead.pagesused += mfile.anchor.get_blocksize();

workNode.set_pos(0);
NodeKey lastKey = null;
btLoop: while (true)
  {
     if (pos == key_per_Node || bt == null)
        {
           if ((tree2 == null &&  level > 0 &&  pos == 1) || pos == 0)
             {
                top_Node--;
                mfile.anchor.reset_nextavailable();
                topNode = workNode; // just in case its not set
                 for (int i=pos; i<key_per_Node; i++)
                   {
                        workNode.set_pos(i);
                        workNode.set_key_value(lastKey);
                    }
                workNode.write();
                break btLoop;
              }
           if (bt != null || tree2 != null) {
             if (tree2 == null)
                {
                   topNode = workNode;
                   tree2 = new BinaryTree(lastKey, workNode.get_record_number(), tree2);
                }
            }
           if (level == 0)
                workNode.set_keys_in_this_Node(pos);
           else
                workNode.set_keys_in_this_Node(pos-1);
              {
                 for (int i=pos; i<key_per_Node; i++)
                   {
                        workNode.set_pos(i);
                        workNode.set_key_value(lastKey);
                    }
              }
                workNode.write();
           if (bt == null) {
               topNode = workNode;
               break btLoop; // we're all done
              }
           top_Node = (short) mfile.anchor.get_nextavailable();
           workNode = new MNode(mfile, key_per_Node, key_length, keyType, top_Node, level>0);
           mfile.anchor.update_nextavailable();
           tagHead.pagesused += mfile.anchor.get_blocksize();
           pos = 0;
           workNode.set_pos(0);
         }
    pos++;
    lastKey = bt.getKey();
    workNode.set_key_value(lastKey);
    if (level == 0)
        workNode.set_key_record_number(bt.getWhere());
    else
        workNode.set_lower_level(bt.getWhere());
  workNode.pos_up();
   bt = bt.getNext();
  }

if (tree2 == nullreturn 0;

topTree = null;
System.gc();

return reIndexWork(tree2.getLeast(), ++level, tree2);

}

public int  find_entry(NodeKey findKey) throws   xBaseJException, IOException
{
  return find_entry(findKey,  findAnyKey);
}


public int  find_entry(NodeKey findKey, int rec) throws   xBaseJException, IOException
{
  if (topNode == null)
  {        /* no keys yet */
    throw new xBaseJException("No keys built");
  }        /* endif */
  topNode.set_pos(0);
  record = find_entry(findKey, (MNode) topNode, rec);
  return record;
}


public int  find_entry(NodeKey findKey, MNode aNode,
                                   int findrec) throws   xBaseJException, IOException
{
  int rec, leaf, until;
  int stat = 0;
  MNode Node_2;
  foundExact = false;
  workNode = aNode;
  if (aNode == null)
  {        /* no keys yet */
    throw new xBaseJException("No keys built");
  }        /* endif */

  leaf = aNode.get_lower_level();
  if (leaf != 0)      /* leaf pointers usually have one more pointer than shown */
    until = aNode.get_keys_in_this_Node() + 1;
  else
    until = aNode.get_keys_in_this_Node();

  for (aNode.set_pos(0);
       aNode.get_pos() < until;
       aNode.pos_up())
  {
    leaf = aNode.get_lower_level();
    rec = aNode.get_key_record_number();
    if (aNode.get_pos() < (aNode.get_keys_in_this_Node()))
        {        /* leafs make us do this */
       stat = findKey.compareKey(aNode.get_key_value());
       if (stat > 0)
          continue;
        }
    if (leaf > 0)
    {        /* still dealing with Nodes */
      if (aNode.get_next() == null)
      {
        Node_2 = new MNode(mfile, key_per_Node, key_length, keyType, leaf, true);
  aNode.set_next(Node_2);
  Node_2.set_prev(aNode);
      }
      else
  Node_2 =  (MNode) aNode.get_next();
     Node_2.set_record_number(leaf);
     Node_2.read();
     Node_2.set_pos(0);
     workNode = Node_2;
     rec = find_entry(findKey, Node_2, findrec);
     return (rec);    /* if rec < 0 then didn't find the record yet */
    }        /* leaf > 0 */


    if (stat < 0)    /* can't find the key  but ...  */
     {

      if (findrec > 0)
  return (keyNotFound);    /* when findrec -1 then looking for specific key and record */

      if (findrec == findFirstMatchingKey)
  return (keyNotFound);    /* when findrec findAnyKey then for the key */

      return (rec);    /* looking for key greater than or equal to */
     }

    /* stat is zero -  key matches the current key */


    foundExact = true;

    if ((findrec > 0) && (rec == findrec))  /* found matching key and matching record number */
      return rec;

    if (findrec == findFirstMatchingKey)
      return rec;    /* found one key that matches */

    if (findrec == findAnyKey)
      return rec;    /* found one key that matches */

    /* findrec not zero so we are looking for the key that is greater than  */
    /* or we looking for a key with a particular record number */

  }        /* end for */

  return (foundMatchingKeyButNotRecord);      /* at end of current line but keep looking for recursion */
}


public int  get_next_key() throws   xBaseJException, IOException
{
  return get_next_key((MNode) workNode);
}

public  int  get_next_key(MNode aNode) throws   xBaseJException, IOException
{

  int rec, until, leaf;


  if (aNode == null)
    return -1;

  leaf = aNode.get_lower_level();

  if (aNode.branch)      /* leaf pointers usually have one more pointer than shown */
    until = aNode.get_keys_in_this_Node() + 1;
  else
    until = aNode.get_keys_in_this_Node();

  aNode.pos_up();

  if (aNode.get_pos() >= until)
  {
    MNode rNode;
    rNode =  (MNode) aNode.get_prev();
    rec = get_next_key(rNode);
    if (rec == -1)
    {
      aNode.set_pos(until);
      return -1;
    }        /* endif */
    workNode =  aNode;
    aNode.set_record_number(rec);
    aNode.read();
    aNode.set_pos(0);
  }        /* endif */

  leaf = aNode.get_lower_level();
  workNode =  aNode;
  if (leaf>0)
    return (leaf);
  return (aNode.get_key_record_number());
}


public  int get_prev_key() throws   xBaseJException, IOException
{
   return get_prev_key((MNode) workNode);
}

public  int  get_prev_key(MNode aNode) throws   xBaseJException, IOException
{
  int rec, until, leaf;

  if (aNode == null)
    return -1;

  if (aNode.get_pos() < 0)
    return -1;

  leaf = aNode.get_lower_level();
  until = 0;


  if (aNode.get_pos()>-1)
    aNode.pos_down();


  if (aNode.get_pos() < 0)
  {
    rec = get_prev_key((MNode) aNode.get_prev());
    if (rec == -1)
    {
      return -1;
    }
    aNode.set_record_number(rec);
    aNode.read();
    aNode.set_pos(aNode.get_keys_in_this_Node() + until); // must be leaf node
    aNode.pos_down(); // offset is at zero not 1
  }        /* endif */

  leaf = aNode.get_lower_level();
  workNode =  aNode;
  if (leaf>0) {
    return (leaf);
    }
  return aNode.get_key_record_number();
}



public void anchor_write() throws IOException { mfile.anchor.write(); }


public  int  add_entry(NodeKey NDXkey,  int recno) throws   xBaseJException, IOException
{


  if (topNode != null)
  {
      find_entry(NDXkey, findAnyKey);
  }

  set_active_key(NDXkey);
  return update_entry((MNode)workNode, NDXkey, recno, 0);

}


public  int  update_entry(MNode aNode, NodeKey NDXkey,
                                      int recno,
                                      int oldrecno)     throws IOException, xBaseJException
{

  int savepos;
  if (topNode == null || topNode.get_record_number() == 0)
  {        /* we don't have any Index area yet so we must be adding the first
         * record */
    if (topNode == null)
         topNode = new MNode(mfile, key_per_Node, key_length, keyType, mfile.anchor.get_nextavailable(), false);
    workNode =  topNode;
    topNode.set_next(null);
    topNode.set_prev(null);
    topNode.set_pos(0);
    topNode.set_key_record_number(recno);

    topNode.set_key_value(NDXkey);
    topNode.set_keys_in_this_Node(1);

    tagHead.top_Node = mfile.anchor.get_nextavailable();

    topNode.set_record_number((int) tagHead.top_Node);
    topNode.set_lower_level(0);
    topNode.write();

    tagHead.top_Node = mfile.anchor.get_nextavailable();
    tagHead.pagesused += mfile.anchor.get_blocksize();
    tagHead.write();

    mfile.anchor.update_nextavailable();

    return 0;
}

  if (aNode == null)
  {        /* work  to split the top Node */
    MNode newNode = new MNode(mfile, key_per_Node, key_length, keyType, mfile.anchor.get_nextavailable(), true);
    newNode.set_next(null);
    newNode.set_prev(null);
    topNode = newNode;

    newNode.set_pos(0);
    newNode.set_key_record_number((int) recno);
    newNode.set_key_value(NDXkey);
    newNode.set_pos(1);
    newNode.set_key_record_number((int) oldrecno);
    newNode.set_pos(0);

    newNode.set_keys_in_this_Node(1);

    tagHead.top_Node = mfile.anchor.get_nextavailable();

    newNode.set_record_number((int) tagHead.top_Node);
    newNode.write();

    tagHead.pagesused += mfile.anchor.get_blocksize();
    tagHead.write();

    mfile.anchor.update_nextavailable();


    return 0;
  }

  savepos = aNode.get_pos();
  if (savepos < (aNode.get_keys_in_this_Node()) )
  {
    int ptr, recn, i;
    NodeKey buf;
    i = aNode.get_keys_in_this_Node();
    aNode.set_pos(i);
    ptr = aNode.get_lower_level();
    aNode.pos_up();
    aNode.set_lower_level(ptr);
    /* then move all the other subNodes */
    aNode.set_pos(i);    /* should be at last one in list */
    for (; //i is pointing to last Nodelet
   i > -1 && i >=savepos; i--)
    {
      ptr = aNode.get_lower_level();
      recn = aNode.get_key_record_number();
      buf = aNode.get_key_value();
      aNode.pos_up();
      aNode.set_lower_level(ptr);
      aNode.set_key_record_number(recn);
      aNode.set_key_value(buf);
      aNode.set_pos(i - 1);
    }        /* endfor */
   aNode.set_pos(savepos)/* reposition after falling out */
    aNode.set_lower_level(recno);
    aNode.set_key_record_number(recno);
    aNode.set_key_value(NDXkey);
    if (oldrecno > 0)
    {
      aNode.pos_up();
      aNode.set_lower_level(oldrecno);
      aNode.pos_down();
    }
  }
  else
  {
    aNode.set_pos(aNode.get_keys_in_this_Node());
    aNode.set_lower_level(recno);
    aNode.set_key_record_number(recno);
    aNode.set_key_value(NDXkey);
    if (oldrecno > 0)
    {
      aNode.pos_up();
      aNode.set_lower_level(oldrecno);
      aNode.pos_down();
    }
  }
  aNode.set_keys_in_this_Node(aNode.get_keys_in_this_Node() + 1);
  aNode.write();


  if (aNode.get_keys_in_this_Node() > key_per_Node)
    splitNode(aNode, savepos);

  return 0;
}


public void splitNode(MNode aNode, int savepos) throws xBaseJException, IOException
{
    int i, j, k;
    int left, right;
    MNode bNode;

    /* this is where we do the famous split */
    /* first split one Node and preserve it on the file */
    /* then the new Node with half the old data can use the ending logic */
    /* which simply updates it in place */
    /* if pos < half way point in record */
    /* fix and write last (#allowed /2) +1 thru #allowed */
    /* split from 1 to #allowed /2 */
    /* add our new Index */
    /* write our new Index */
    /* add entry to Node above. last entry in our new Node */
    bNode = new MNode(mfile, key_per_Node, key_length, keyType, 0, aNode.isBranch());
    bNode.set_pos(0);
    aNode.set_pos(0);
    for (k = 0; k < aNode.get_keys_in_this_Node(); k++)
    {
      bNode.set_lower_level(aNode.get_lower_level());
      bNode.set_key_record_number(aNode.get_key_record_number());
      bNode.set_key_value(aNode.get_key_value());
      bNode.pos_up();
      aNode.pos_up();
    }        /* endfor */
    bNode.set_lower_level(aNode.get_lower_level());
//    bNode.set_key_record_number(0);
    bNode.set_key_value("");
    i = aNode.get_keys_in_this_Node() / 2;
    j = aNode.get_keys_in_this_Node() - i;

    if (savepos > i )
    {
      bNode.set_keys_in_this_Node(i);
      if (aNode.get_next() != null)
          aNode.set_keys_in_this_Node(i-1);
      else
          aNode.set_keys_in_this_Node(i)/* for top level split */
      left = aNode.get_record_number();
      aNode.write();
      right =  mfile.anchor.get_nextavailable();
      mfile.anchor.update_nextavailable();
      if (aNode.get_prev() != null)
      {
  bNode.set_pos(i-1);
  update_entry( (MNode) aNode.get_prev(), bNode.get_key_value(), left, right);
      }
      aNode.set_pos(0);
      bNode.set_pos(i);
      for (k = 0; k <= j; k++)
      {
  aNode.set_lower_level(bNode.get_lower_level());
  aNode.set_key_record_number(bNode.get_key_record_number());
  aNode.set_key_value(bNode.get_key_value());
  aNode.pos_up();
  bNode.pos_up();
      }
      /* the right side is already one short */
      aNode.set_keys_in_this_Node(j);
      aNode.set_pos(savepos - i);
      aNode.set_record_number(right);
      aNode.write();
      if (aNode.get_prev() == null)
      {
  //create a new top Node
    bNode.set_pos(i-1);
  //use new Node because it has the old data in it, at pos(i) is the last key
   update_entry(null,
            bNode.get_key_value(),
            left, right);
         aNode.set_prev(topNode);
         topNode.set_next(aNode);
      }
    }
    else
    {        /* create new second half and use the first half to put  new key in */
      right = aNode.get_record_number();
      aNode.set_pos(0);
      bNode.set_pos(j);
      for (k = 0; k <= i; k++)
      {
        aNode.set_lower_level(bNode.get_lower_level());
  aNode.set_key_record_number(bNode.get_key_record_number());
  aNode.set_key_value(bNode.get_key_value());
  aNode.pos_up();
  bNode.pos_up();
      }
      aNode.set_keys_in_this_Node(i);
      aNode.write();

      bNode.set_keys_in_this_Node(i);
      aNode.set_pos(0);
      bNode.set_pos(0);
      for (k = 0; k < key_per_Node; k++)
      {
  aNode.set_lower_level(bNode.get_lower_level());
  aNode.set_key_record_number(bNode.get_key_record_number());
  aNode.set_key_value(bNode.get_key_value());
  aNode.pos_up();
  bNode.pos_up();
      }
      aNode.set_record_number(mfile.anchor.get_nextavailable()); // did a split renumber Node
      mfile.anchor.update_nextavailable();
      if (aNode.get_next() != null)
        aNode.set_keys_in_this_Node(j-1);
      else
           aNode.set_keys_in_this_Node(j);

      aNode.set_pos(j-1);
      aNode.write();
      left = aNode.get_record_number();
       update_entry( (MNodeaNode.get_prev(),
        aNode.get_key_value(),
      left, right);
       if (aNode.get_prev() == null){
         aNode.set_prev(topNode);
         topNode.set_next(aNode);
         }
    }
    bNode = null;
}


public void  del_entry(Node inNode) throws IOException, xBaseJException
{

  MNode aNode;
  int pos, k;

  aNode = (MNode) inNode;

  pos = aNode.get_pos();
  k = pos;
  aNode.set_keys_in_this_Node(aNode.get_keys_in_this_Node() - 1);

  if (aNode.get_lower_level() != 0 // pointer node
    && pos <= aNode.get_keys_in_this_Node())
   {
    for (k = pos-1; k < aNode.get_keys_in_this_Node(); k++)
    {
      int level, rec;
      NodeKey key;
      aNode.pos_up();
      level = aNode.get_lower_level();
      rec = aNode.get_key_record_number();
      key = aNode.get_key_value();
      aNode.pos_down();
      aNode.set_lower_level(level);
      aNode.set_key_record_number(rec);
      aNode.set_key_value(key);
      aNode.pos_up();
    }        /* endfor */
  } /* endif */
  else if (pos < aNode.get_keys_in_this_Node()) // record node
  {
    for (k = pos; k < aNode.get_keys_in_this_Node(); k++)
    {
      int level, rec;
      NodeKey key;
      aNode.pos_up();
      level = aNode.get_lower_level();
      rec = aNode.get_key_record_number();
      key = aNode.get_key_value();
      aNode.pos_down();
      aNode.set_lower_level(level);
      aNode.set_key_record_number(rec);
      aNode.set_key_value(key);
      aNode.pos_up();
    }        /* endfor */
  }        /* endif */
  if (aNode.get_prev() != null) // should we fix parent?
   {
    if (aNode.get_keys_in_this_Node() == 0)
     {
      if (aNode.get_lower_level() == 0) // record node so go fix its parent
        del_entry(aNode.get_prev());
      else ; // pointer node so don't fix unless negative
     }
    else
     {
      if (aNode.get_keys_in_this_Node() == -1)
        del_entry(aNode.get_prev());
     }
   }

  aNode.set_pos(pos);
  aNode.write();
}


}

TOP

Related Classes of org.xBaseJ.micro.indexes.MDX

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.