コード例 #1
0
ファイル: RecordManager.java プロジェクト: gyuu/MiniSQL
  public int deleteRecord(String tableName, List<Condition> conditions)
      throws TableNotFoundException, Exception {
    Table table = cm.getTable(tableName);
    if (table == null) throw new TableNotFoundException(tableName);

    int count = 0;

    for (int blockOffset = 0; blockOffset < table.blockNum; blockOffset++) {
      BufferNode bn = bm.getBufferNode(table.name + ".table", blockOffset);
      byte[] block = bn.data;
      int recordNum = getRecordNum(block);
      int recordIndex = 0;
      int accessedRecordNum = 0;
      int nextDeleted = getInsertIndex(block);
      int prevDeleted = -1;

      ArrayList<Index> allTableIndices = cm.getAllIndicesOfTable(tableName);

      while (accessedRecordNum < recordNum) {
        int pos = getPositionFromIndex(table, recordIndex);
        if (block[pos] == EMPTY) { // record is empty, skip
          recordIndex++;
          continue;
        }

        byte[] recordBytes = bn.getBytes(pos + 1, table.totalLength);
        if (matchAllCond(table, recordBytes, conditions)) {
          block[pos] = EMPTY;
          if (recordIndex < nextDeleted) {
            setNextInsertIndex(block, table, prevDeleted, recordIndex);
            setNextInsertIndex(block, table, recordIndex, nextDeleted);
            prevDeleted = recordIndex;
          } else {
            int nextOfNext = getNextInsertIndex(block, table, nextDeleted);
            setNextInsertIndex(block, table, nextDeleted, recordIndex);
            setNextInsertIndex(block, table, recordIndex, nextOfNext);
            nextDeleted = nextOfNext;
            prevDeleted = recordIndex;
          }

          decRecordNum(block);
          // there remains some space for insertion
          if (table.nextInsertBlock > blockOffset) table.nextInsertBlock = blockOffset;

          // Delete in index
          for (Index idx : allTableIndices) {
            byte[] key = Arrays.copyOfRange(recordBytes, idx.pos, idx.pos + idx.columnLength);
            im.deleteKey(idx, key);
          }

          bn.isWritten = true;
          count++;
        }
        recordIndex++;
        accessedRecordNum++;
      }
    }
    return count;
  }
コード例 #2
0
ファイル: RecordManager.java プロジェクト: gyuu/MiniSQL
  public void insertRecord(String tableName, List<String> row)
      throws TableNotFoundException, UniqueKeyException, Exception {
    Table table = cm.getTable(tableName);
    if (table == null) throw new TableNotFoundException(tableName);

    byte[] bytesToInsert = getInsertBytes(table, row);

    // check uniqueness
    ArrayList<Index> allTableIndices = cm.getAllIndicesOfTable(tableName);
    for (Index idx : allTableIndices) {
      byte[] key = Arrays.copyOfRange(bytesToInsert, idx.pos, idx.pos + idx.columnLength);
      if (im.searchEqual(idx, key) != null) throw new UniqueKeyException(idx.indexName);
    }

    // Use free list for insertion and deletion
    int recordSize = table.totalLength + POINTER_SIZE;

    while (true) {
      // BufferNode bn = bm.getIfIsInBuffer(table.name + ".table", table.nextInsertBlock);
      BufferNode bn = bm.getBufferNode(table.name + ".table", table.nextInsertBlock);
      byte[] block = bn.data;
      int insertIndex = getInsertIndex(block);
      int pos = getPositionFromIndex(table, insertIndex);

      // No free space, get a new block
      if (pos + recordSize > BufferManager.BLOCK_SIZE) {
        table.nextInsertBlock++;
        if (table.nextInsertBlock >= table.blockNum) bm.addBlockInFile(table);
        continue;
      }

      // Write to buffer
      block[pos] = NOT_EMPTY;
      System.arraycopy(bytesToInsert, 0, block, pos + 1, table.totalLength);

      // Modify available insert index value and increase record number
      int nextIndex = getNextInsertIndex(block, table, insertIndex);
      setInsertIndex(block, nextIndex);
      incRecordNum(block);

      // Update index
      for (Attribute attr : table.attributes) {
        if (!attr.index.equals("")) { // has index
          Index idx = cm.getIndex(attr.index);
          byte[] key = Arrays.copyOfRange(bytesToInsert, idx.pos, idx.pos + idx.columnLength);
          im.insertKey(idx, key, table.nextInsertBlock, pos);
        }
      }

      bn.isWritten = true;
      return;
    }
  }
コード例 #3
0
  public static void createIndex(String tableName, Index index) {
    Value table_ = cm.GetTableInformation(tableName);
    Value attr_;
    BPlusTree thisTree = new BPlusTree(index);

    String filename = tableName;
    try {
      mapInsert(tableName, index);
      RM_FileHandler rmf = RM_Manager.getInstance().openFile(filename);
      RM_FileScan rmfs =
          new RM_FileScan(
              rmf, Constant.TYPE.INT, 4, 0, Constant.COMP_OP.NO_OP, PF_Manager.intTobyteArray(1));
      RM_Record rmr = rmfs.getNextRec();

      while (rmr != null) {
        byte[] Record = rmr.getData();
        byte[] key = getColumnValue(tableName, index, Record);
        thisTree.insert(key, rmr.getRid().getPageNum(), rmr.getRid().getSlotNum());
        rmr = rmfs.getNextRec();
      }
    } catch (NullPointerException e) {
      e.printStackTrace();
      System.err.println("must not be null for key.");
    } catch (Exception e) {
      e.printStackTrace();
      System.err.println("the index has not been created.");
    }

    // index.rootNum=thisTree.myRootBlock.blockOffset;
    setIndexRoot(index.indexName, thisTree.myRootBlock.getPageNum());
    System.out.println("Create index successfully!");
  }
コード例 #4
0
ファイル: RecordManager.java プロジェクト: gyuu/MiniSQL
  public void selectRecord(String tableName, ArrayList<Condition> conditions)
      throws TableNotFoundException {
    Table table = cm.getTable(tableName);
    if (table == null) throw new TableNotFoundException(tableName);
    Data selectResult = new Data();

    for (int blockOffset = 0; blockOffset < table.blockNum; blockOffset++) {
      BufferNode bn = bm.getBufferNode(table.name + ".table", blockOffset);
      byte[] block = bn.data;
      int recordNum = getRecordNum(block);
      int recordIndex = 0;
      int accessedRecordNum = 0;

      while (accessedRecordNum < recordNum) {
        int pos = getPositionFromIndex(table, recordIndex);
        if (block[pos] == EMPTY) { // record is empty, skip
          recordIndex++;
          continue;
        }

        byte[] recordBytes = bn.getBytes(pos + 1, table.totalLength);
        if (matchAllCond(table, recordBytes, conditions)) {
          byte[] bytes = bn.getBytes(pos + 1, table.totalLength);
          selectResult.add(new Row(bytesToString(table, bytes)));
        }
        recordIndex++;
        accessedRecordNum++;
      }
    }

    displaySelectResult(table, selectResult);
  }
コード例 #5
0
  public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {

    Map model = new HashMap();

    List<Brand> brands = catalogManager.getBrands();

    model.put("brands", brands);

    return new ModelAndView("brand", "model", model);
  }
コード例 #6
0
  /**
   * {@inheritDoc}
   *
   * @see
   *     com.continuent.tungsten.replicator.plugin.ReplicatorPlugin#prepare(com.continuent.tungsten.replicator.plugin.PluginContext)
   */
  public synchronized void prepare(PluginContext context)
      throws ReplicatorException, InterruptedException {
    // Prepare database connection.
    if (url != null && url.trim().length() > 0) {
      logger.info("Preparing SQL catalog tables");
      ReplicatorRuntime runtime = (ReplicatorRuntime) context;
      String metadataSchema = context.getReplicatorSchemaName();
      catalog = new CatalogManager(runtime);
      catalog.connect(url, user, password, metadataSchema, vendor);
      catalog.prepareSchema();
    } else logger.info("SQL catalog tables are disabled");

    // Configure and prepare the log.
    diskLog = new DiskLog();
    diskLog.setDoChecksum(doChecksum);
    diskLog.setEventSerializerClass(eventSerializer);
    diskLog.setLogDir(logDir);
    diskLog.setLogFileSize(logFileSize);
    diskLog.setLogFileRetainMillis(logFileRetainMillis);
    diskLog.setLogConnectionTimeoutMillis(logConnectionTimeout * 1000);
    diskLog.setBufferSize(bufferSize);
    diskLog.setFsyncOnFlush(fsyncOnFlush);
    if (fsyncOnFlush) {
      // Only used with fsync.
      diskLog.setFlushIntervalMillis(flushIntervalMillis);
    }
    diskLog.setReadOnly(readOnly);
    diskLog.prepare();
    logger.info("Log preparation is complete");

    // Start server for THL connections.
    if (context.isRemoteService() == false) {
      try {
        server = new Server(context, sequencer, this);
        server.start();
      } catch (IOException e) {
        throw new ReplicatorException("Unable to start THL server", e);
      }
    }
  }
コード例 #7
0
ファイル: LwdStar.java プロジェクト: jankotek/Pixy2
  /**
   * Gets the list of the hierarchical folders.
   *
   * @return the list of the hierarchical folders.
   */
  public Vector getHierarchicalFolders() {
    Vector folder_list = new Vector();

    folder_list.addElement(CatalogManager.getCatalogCategoryFolder(getCatalogCategoryNumber()));
    folder_list.addElement(getCatalogFolderCode());

    int number = Integer.parseInt(name) / 100;
    number *= 100;

    folder_list.addElement(String.valueOf(number));

    return folder_list;
  }
コード例 #8
0
ファイル: EdinburghStar.java プロジェクト: jankotek/Pixy2
  /**
   * Gets the list of the hierarchical folders.
   *
   * @return the list of the hierarchical folders.
   */
  public Vector getHierarchicalFolders() {
    Vector folder_list = new Vector();

    folder_list.addElement(CatalogManager.getCatalogCategoryFolder(getCatalogCategoryNumber()));
    folder_list.addElement(getCatalogFolderCode());

    folder_list.addElement(name.substring(0, 1));

    int number = Format.intValueOf(name.substring(2)) / 100;
    number *= 100;
    folder_list.addElement(String.valueOf(number));

    return folder_list;
  }
コード例 #9
0
ファイル: AsasStar.java プロジェクト: jankotek/Pixy2
  /**
   * Gets the list of the hierarchical folders.
   *
   * @return the list of the hierarchical folders.
   */
  public Vector getHierarchicalFolders() {
    Vector folder_list = new Vector();

    folder_list.addElement(CatalogManager.getCatalogCategoryFolder(getCatalogCategoryNumber()));
    folder_list.addElement(getCatalogFolderCode());

    int p = name.indexOf('+');
    if (p < 0) p = name.indexOf('-');

    folder_list.addElement(name.substring(0, 2));
    folder_list.addElement(name.substring(p, p + 2) + "0");

    return folder_list;
  }
コード例 #10
0
 /**
  * Updates the sequence number stored in the catalog trep_commit_seqno. If the catalog is disabled
  * we do nothing, which allows us to run unit tests easily without a DBMS present.
  *
  * @throws ReplicatorException Thrown if update is unsuccessful
  */
 public void updateCommitSeqno(THLEvent thlEvent) throws ReplicatorException {
   if (catalog == null) {
     if (logger.isDebugEnabled())
       logger.debug("Seqno update is disabled: seqno=" + thlEvent.getSeqno());
   } else {
     try {
       catalog.updateCommitSeqnoTable(thlEvent);
     } catch (SQLException e) {
       throw new THLException(
           "Unable to update commit sequence number: seqno="
               + thlEvent.getSeqno()
               + " event id="
               + thlEvent.getEventId(),
           e);
     }
   }
 }
コード例 #11
0
 private static byte[] getColumnValue(String tableName, Index index, byte[] row) {
   /*		Value table_ = cm.GetTableInformation(tableName);
   Value attr_;
   int st = 0,  en = 0;
   for(int i = 0; i <= table_.getLength(); i++){
   	attr_ = cm.GetAttrInformation(tableName, i);
   	st = en;
   	en += attr_.getLength();
   }*/
   int st = 0, en = 0;
   for (int i = 0; i < index.column; i++) {
     st = en;
     en += cm.GetAttrInformation(tableName, i).getLength();
   }
   byte[] colValue = new byte[en - st];
   for (int j = 0; j < en - st; j++) {
     colValue[j] = row[st + j];
   }
   return colValue;
 }
コード例 #12
0
  /**
   * Get the last applied event. We first try the disk log then if that is absent try the catalog.
   * If there is nothing there we must be starting from scratch and return null.
   *
   * @return An event header or null if log is newly initialized
   * @throws InterruptedException
   * @throws ReplicatorException
   */
  public ReplDBMSHeader getLastAppliedEvent() throws ReplicatorException, InterruptedException {
    // Look for maximum sequence number in log and use that if available.
    if (diskLog != null) {

      long maxSeqno = diskLog.getMaxSeqno();
      if (maxSeqno > -1) {
        LogConnection conn = null;
        try {
          // Try to connect and find the event.
          THLEvent thlEvent = null;
          conn = diskLog.connect(true);
          conn.seek(maxSeqno);
          while ((thlEvent = conn.next(false)) != null && thlEvent.getSeqno() == maxSeqno) {
            // Return only the last fragment.
            if (thlEvent.getLastFrag()) {
              ReplEvent event = thlEvent.getReplEvent();
              if (event instanceof ReplDBMSEvent) return (ReplDBMSEvent) event;
              else if (event instanceof ReplControlEvent)
                return ((ReplControlEvent) event).getHeader();
            }
          }

          // If we did not find the last fragment of the event
          // we need to warn somebody.
          if (thlEvent != null)
            logger.warn("Unable to find last fragment of event: seqno=" + maxSeqno);
        } finally {
          conn.release();
        }
      }
    }

    // If that does not work, try the catalog.
    if (catalog != null) {
      return catalog.getLastEvent();
    }

    // If we get to this point, the log is newly initialized and there is no
    // such event to return.
    return null;
  }
コード例 #13
0
  /**
   * {@inheritDoc}
   *
   * @see
   *     com.continuent.tungsten.replicator.plugin.ReplicatorPlugin#release(com.continuent.tungsten.replicator.plugin.PluginContext)
   */
  public synchronized void release(PluginContext context)
      throws InterruptedException, ReplicatorException {
    // Cancel server.
    if (server != null) {
      try {
        server.stop();
      } catch (InterruptedException e) {
        logger.warn("Server stop operation was unexpectedly interrupted", e);
      } finally {
        server = null;
      }
    }

    if (catalog != null) {
      catalog.close();
      catalog = null;
    }
    if (diskLog != null) {
      diskLog.release();
      diskLog = null;
    }
  }
コード例 #14
0
  @Test
  public void deleteCourseSoftly() {
    Identity coach = JunitTestHelper.createAndPersistIdentityAsRndUser("re-soft-");
    Identity coachGroup = JunitTestHelper.createAndPersistIdentityAsRndUser("re-soft-");
    Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("re-soft-");
    Identity initialAuthor = JunitTestHelper.createAndPersistIdentityAsRndUser("auth-del-1");
    RepositoryEntry re = JunitTestHelper.deployDemoCourse(initialAuthor);
    dbInstance.commitAndCloseSession();

    // add business group
    BusinessGroup group =
        businessGroupService.createBusinessGroup(
            coachGroup, "Relation 1", "tg", null, null, false, false, re);
    businessGroupService.addResourceTo(group, re);
    dbInstance.commit();

    // catalog
    List<CatalogEntry> rootEntries = catalogManager.getRootCatalogEntries();
    CatalogEntry catEntry = catalogManager.createCatalogEntry();
    catEntry.setName("Soft");
    catEntry.setRepositoryEntry(re);
    catEntry.setParent(rootEntries.get(0));
    catEntry.setOwnerGroup(securityManager.createAndPersistSecurityGroup());
    catalogManager.saveCatalogEntry(catEntry);
    dbInstance.commit();

    // check the catalog
    List<CatalogEntry> catEntries = catalogManager.getCatalogCategoriesFor(re);
    Assert.assertNotNull(catEntries);
    Assert.assertEquals(1, catEntries.size());

    // add owner, coach...
    repositoryEntryRelationDao.addRole(coach, re, GroupRoles.coach.name());
    repositoryEntryRelationDao.addRole(participant, re, GroupRoles.participant.name());
    dbInstance.commit();

    // kill it softly like A. Keys
    repositoryService.deleteSoftly(re, initialAuthor, false);
    dbInstance.commit();

    // check that the members are removed
    List<Identity> coachAndParticipants =
        repositoryEntryRelationDao.getMembers(
            re,
            RepositoryEntryRelationType.both,
            GroupRoles.coach.name(),
            GroupRoles.participant.name());
    Assert.assertNotNull(coachAndParticipants);
    Assert.assertEquals(0, coachAndParticipants.size());

    // check the relations between course and business groups
    SearchBusinessGroupParams params = new SearchBusinessGroupParams();
    List<BusinessGroup> groups = businessGroupService.findBusinessGroups(params, re, 0, -1);
    Assert.assertNotNull(groups);
    Assert.assertEquals(0, groups.size());

    // check the catalog
    List<CatalogEntry> removedCatEntries = catalogManager.getCatalogCategoriesFor(re);
    Assert.assertNotNull(removedCatEntries);
    Assert.assertEquals(0, removedCatEntries.size());

    RepositoryEntry reloadEntry = repositoryService.loadByKey(re.getKey());
    Assert.assertNotNull(reloadEntry);
    Assert.assertEquals(0, reloadEntry.getAccess());
    Assert.assertNotNull(reloadEntry.getDeletionDate());
    Assert.assertEquals(initialAuthor, reloadEntry.getDeletedBy());
  }
コード例 #15
0
public class IndexManager {
  private static CatalogManager cm = CatalogManager.getInstance();
  private static RM_Manager rm = RM_Manager.getInstance();
  private static TreeMap<String, Integer> mapIndexRoot = new TreeMap<String, Integer>();
  private static TreeMap<String, HashSet<Index>> mapName2Index =
      new TreeMap<String, HashSet<Index>>();
  /*	public static Buffer buf;

  IndexManager(Buffer buffer){
  	buf = buffer;
  } */
  private static IndexManager Instant = new IndexManager();

  public static IndexManager getInstance() {
    return Instant;
  }

  private static byte[] getColumnValue(String tableName, Index index, byte[] row) {
    /*		Value table_ = cm.GetTableInformation(tableName);
    Value attr_;
    int st = 0,  en = 0;
    for(int i = 0; i <= table_.getLength(); i++){
    	attr_ = cm.GetAttrInformation(tableName, i);
    	st = en;
    	en += attr_.getLength();
    }*/
    int st = 0, en = 0;
    for (int i = 0; i < index.column; i++) {
      st = en;
      en += cm.GetAttrInformation(tableName, i).getLength();
    }
    byte[] colValue = new byte[en - st];
    for (int j = 0; j < en - st; j++) {
      colValue[j] = row[st + j];
    }
    return colValue;
  }

  static boolean mapInsert(String key, Index value) {
    if (mapName2Index.containsKey(key)) {
      HashSet<Index> set = mapName2Index.get(key);
      if (set.contains(value)) return false;
      set.add(value);
    } else {
      HashSet<Index> set = new HashSet<Index>();
      set.add(value);
      mapName2Index.put(key, set);
    }
    return true;
  }

  public static void createIndex(String tableName, Index index) {
    Value table_ = cm.GetTableInformation(tableName);
    Value attr_;
    BPlusTree thisTree = new BPlusTree(index);

    String filename = tableName;
    try {
      mapInsert(tableName, index);
      RM_FileHandler rmf = RM_Manager.getInstance().openFile(filename);
      RM_FileScan rmfs =
          new RM_FileScan(
              rmf, Constant.TYPE.INT, 4, 0, Constant.COMP_OP.NO_OP, PF_Manager.intTobyteArray(1));
      RM_Record rmr = rmfs.getNextRec();

      while (rmr != null) {
        byte[] Record = rmr.getData();
        byte[] key = getColumnValue(tableName, index, Record);
        thisTree.insert(key, rmr.getRid().getPageNum(), rmr.getRid().getSlotNum());
        rmr = rmfs.getNextRec();
      }
    } catch (NullPointerException e) {
      e.printStackTrace();
      System.err.println("must not be null for key.");
    } catch (Exception e) {
      e.printStackTrace();
      System.err.println("the index has not been created.");
    }

    // index.rootNum=thisTree.myRootBlock.blockOffset;
    setIndexRoot(index.indexName, thisTree.myRootBlock.getPageNum());
    System.out.println("Create index successfully!");
  }

  public static void dropIndex(String filename) {
    filename += ".index";
    File file = new File(filename);

    try {
      if (file.exists()) {
        if (file.delete()) System.out.println("The index file has been deleted.");
      } else System.out.println("The file " + filename + " has not been found.");
    } catch (Exception e) {
      System.out.println(e.getMessage());
      System.out.println("Delete index unsuccessfully!");
    }

    // buf.setInvalid(filename);  //将buf中所有与此索引相关的缓冲块都置为无效
    System.out.println("Delete index successfully!");
  }

  public static void dropTable(String filename) {
    HashSet<Index> i = mapName2Index.get(filename);
    for (Index j : i) {
      dropIndex(j.indexName);
    }
    mapName2Index.remove(filename, i);
  }

  public static RID searchEqual(Index index, byte[] key) throws Exception {
    RID off = new RID();
    try {
      // Index inx=CatalogManager.getIndex(index.indexName);
      BPlusTree thisTree = new BPlusTree(index, index.rootNum); /*This place has bugs.*/
      off = thisTree.searchKey(key);
      return off;
    } catch (NullPointerException e) {
      System.err.println();
      return null;
    }
  }

  public static void insertKey(Index index, byte[] key, int blockOffset, int offset)
      throws Exception {
    try {
      // Index inx=CatalogManager.getIndex(index.indexName);
      BPlusTree thisTree = new BPlusTree(index, index.rootNum); /*This place has bugs.*/
      thisTree.insert(key, blockOffset, offset);
      // index.rootNum=thisTree.myRootBlock.blockOffset;
      setIndexRoot(index.indexName, thisTree.myRootBlock.getPageNum());
    } catch (NullPointerException e) {
      System.err.println();
    }
  }

  public static void deleteKey(Index index, byte[] deleteKey) throws Exception {
    try {
      // Index inx=CatalogManager.getIndex(index.indexName);
      BPlusTree thisTree = new BPlusTree(index, index.rootNum); /*This place has bugs.*/
      thisTree.delete(deleteKey);
      // index.rootNum=thisTree.myRootBlock.blockOffset;
      setIndexRoot(index.indexName, thisTree.myRootBlock.getPageNum());
    } catch (NullPointerException e) {
      System.err.println();
    }
  }

  public static void setIndexRoot(String indexName, int number) {
    ;
    if (mapIndexRoot.containsKey(indexName)) {
      mapIndexRoot.replace(indexName, number);
    } else mapIndexRoot.put(indexName, number);
  }

  // 获得索引根块在文件中的block偏移量, 如果该index不存在则返回-1
  public static int getIndexRoot(String indexName) {
    if (mapIndexRoot.containsKey(indexName)) return mapIndexRoot.get(indexName);
    else return -1;
  }
}