/** Opens the database and creates the Map. */
  private void open() throws Exception {

    // use a generic database configuration
    DatabaseConfig dbConfig = new DatabaseConfig();
    dbConfig.setTransactional(true);
    if (create) {
      dbConfig.setAllowCreate(true);
      dbConfig.setType(DatabaseType.BTREE);
    }

    // catalog is needed for serial bindings (java serialization)
    Database catalogDb = env.openDatabase(null, "catalog", null, dbConfig);
    catalog = new StoredClassCatalog(catalogDb);

    // use Integer tuple binding for key entries
    TupleBinding keyBinding = TupleBinding.getPrimitiveBinding(Integer.class);

    // use String serial binding for data entries
    SerialBinding dataBinding = new SerialBinding(catalog, String.class);

    this.db = env.openDatabase(null, "helloworld", null, dbConfig);

    // create a map view of the database
    this.map = new StoredSortedMap(db, keyBinding, dataBinding, true);
  }
예제 #2
0
  public void runTest(DatabaseType type) throws DatabaseException, FileNotFoundException {
    int i;
    DatabaseConfig conf = new DatabaseConfig();
    conf.setErrorStream(TestUtils.getErrorStream());
    conf.setErrorPrefix("HashCompareTest");
    conf.setType(type);
    if (type == DatabaseType.HASH) {
      conf.setHashComparator(new HashComparator());
    } else conf.setBtreeComparator(new BtreeComparator());
    conf.setAllowCreate(true);

    Database db = new Database(HASHCOMPARETEST_DBNAME, null, conf);

    DatabaseEntry key = new DatabaseEntry();
    DatabaseEntry data = new DatabaseEntry("world".getBytes());
    for (i = 0; i < 100; i++) {
      key.setData((new String("key" + i)).getBytes());
      db.put(null, key, data);
    }
    i = 0;
    Cursor dbc;
    dbc = db.openCursor(null, CursorConfig.DEFAULT);
    while (dbc.getNext(key, data, LockMode.DEFAULT) == OperationStatus.SUCCESS) {
      ++i;
    }
    //		System.out.println("retrieved " + i + " entries");
    dbc.close();
    db.close();
  }
예제 #3
0
  public static Database buildsecondary(Database std) {
    // Parse database loaded
    try {
      io.deleteFile("secondarydb");
      // SecondaryDatabases started
      DatabaseConfig dbConfig = new DatabaseConfig();
      dbConfig.setType(DatabaseType.HASH);
      dbConfig.setAllowCreate(true);
      dbConfig.setUnsortedDuplicates(true);
      Database secdb = new Database("secondarydb", null, dbConfig);
      // Cursors started
      Cursor stdcursor = std.openCursor(null, null);
      Cursor secdbcursor = secdb.openCursor(null, null);
      // Key and Data started
      DatabaseEntry stdkey = new DatabaseEntry();
      DatabaseEntry stddata = new DatabaseEntry();
      DatabaseEntry seckey = new DatabaseEntry();
      DatabaseEntry secdata = new DatabaseEntry();

      while (stdcursor.getNext(stdkey, stddata, LockMode.DEFAULT)
          == OperationStatus.SUCCESS) { // Writing into secondary db
        String[] key = new String(stdkey.getData()).split(",");
        String data = new String(stddata.getData());
        // DEBUG:
        // System.out.println("key 0:" + key[0] + " key 1:" + key[1] + " data:" + data);
        seckey.setData(key[1].getBytes());
        OperationStatus operation = secdbcursor.getSearchKey(seckey, secdata, LockMode.DEFAULT);

        String b = null;
        while (operation == OperationStatus.SUCCESS) {
          b = new String(secdata.getData());
          secdbcursor.delete();
          operation = secdbcursor.getNextDup(seckey, secdata, LockMode.DEFAULT);
        }
        if (b == null) {
          seckey.setData(key[1].getBytes());
          secdata.setData(("(" + key[0] + "," + data + ")").getBytes());
          secdb.put(null, seckey, secdata);
        }
        if (b != null) {
          secdata.setData(b.concat("(" + key[0] + "," + data + ")").getBytes());
          secdb.put(null, seckey, secdata);
        }
        seckey.setData(null);
        secdata.setData(null);

        stdkey.setData(null);
        stddata.setData(null);
      }
      // io.debugread(secdb);

      return secdb;
    } catch (Exception e) {
      System.out.println("Error creating <user>,<song,rating> secondary table!\n");
      System.out.println(e.getMessage());
    }
    return null; // SHOULD NEVER HAPPEN
  }
예제 #4
0
  public static Database buildtertiary(Database std) {

    try {
      // configure new database instance
      io.deleteFile("tertiarydb");
      DatabaseConfig dbConfig = new DatabaseConfig();
      dbConfig.setType(DatabaseType.HASH);
      dbConfig.setAllowCreate(true);
      dbConfig.setUnsortedDuplicates(true);
      Database tdb = new Database("tertiarydb", null, dbConfig);

      // configure cursors and entries
      Cursor stdCurs = std.openCursor(null, null);
      Cursor tCurs = tdb.openCursor(null, null);
      DatabaseEntry stdKey = new DatabaseEntry();
      DatabaseEntry stdData = new DatabaseEntry();
      DatabaseEntry tKey = new DatabaseEntry();
      DatabaseEntry tData = new DatabaseEntry();

      // extract from linearly constructed database to populate <song>,<users> table, making
      // use of songs grouped by id
      String currUsers = "";
      String prevID = "default";
      boolean firstIter = true;
      while (stdCurs.getNext(stdKey, stdData, LockMode.DEFAULT) == OperationStatus.SUCCESS) {
        // get rating data from current row
        String[] currIDUser = (new String(stdKey.getData())).split(",");
        String currID = currIDUser[0].trim();
        String currUser = currIDUser[1].trim();
        String currRating = (new String(stdData.getData()));
        stdKey.setData(null);
        stdData.setData(null);
        if (currID.equals(prevID) || firstIter) {
          // concatenate new username with current string
          currUsers += "(" + currUser + "," + currRating + ")";
        } else if (!firstIter) {
          // insert completed <usernames> into table under key <song id>
          tKey.setData(prevID.getBytes());
          tData.setData(currUsers.substring(0, currUsers.length()).getBytes());
          tCurs.put(tKey, tData);
          tKey.setData(null);
          tData.setData(null);
          // DEBUG:
          // System.out.println(prevID+","+currUsers.substring(0, currUsers.length()-1));
          // start the new <usernames> for the next song (in currID)
          currUsers = "(" + currUser + "," + currRating + ")";
        }
        prevID = currID;
        firstIter = false;
      }
      // repeat iteration for last song
      tKey.setData(prevID.getBytes());
      tData.setData(currUsers.substring(0, currUsers.length()).getBytes());
      tCurs.put(tKey, tData);
      tKey.setData(null);
      tData.setData(null);

      // DEBUG:
      // io.debugread(tdb);
      tCurs.close();

      return tdb;

    } catch (Exception e) {
      System.out.println(" error creating <song>,<users> tertiary table\n");
      System.out.println(e.getMessage());
    }
    return null; // should never happen
  }
예제 #5
0
  public static String top3(String line, Database secdb, Database tdb)
      throws DatabaseException, FileNotFoundException {
    // configure sqSum db for keeping track of cumulative squaresums
    io.deleteFile("sqSumdb");
    DatabaseConfig dbConfig = new DatabaseConfig();
    dbConfig.setType(DatabaseType.HASH);
    dbConfig.setAllowCreate(true);
    dbConfig.setUnsortedDuplicates(true);
    Database sqSumdb = new Database("sqSumdb", null, dbConfig);

    Cursor sqSumCurs = sqSumdb.openCursor(null, null);
    DatabaseEntry sqSumKey = new DatabaseEntry();
    DatabaseEntry sqSumData = new DatabaseEntry();

    Cursor secCurs = secdb.openCursor(null, null);
    Cursor tCurs = tdb.openCursor(null, null);
    DatabaseEntry secKey = new DatabaseEntry();
    DatabaseEntry secData = new DatabaseEntry();
    DatabaseEntry tKey = new DatabaseEntry();
    DatabaseEntry tData = new DatabaseEntry();

    // get input song users and ratings
    tKey.setData(line.getBytes());
    if (tCurs.getSearchKey(tKey, tData, LockMode.DEFAULT) == OperationStatus.SUCCESS) {
      // for each user in input song, get songs and ratings
      HashMap<String, String> iRatings = parseBrace(new String(tData.getData()));
      for (String user : iRatings.keySet()) {
        // get current user's rating for input song
        int inputRating = Integer.parseInt(iRatings.get(user));
        // get songs and ratings for user
        secKey.setData(null);
        secData.setData(null);
        secKey.setData(user.getBytes());
        if (secCurs.getSearchKey(secKey, secData, null) == OperationStatus.SUCCESS) {
          // for each song rated by user
          HashMap<String, String> currSongs = parseBrace(new String(secData.getData()));
          for (String song : currSongs.keySet()) {
            // input song should not be compared to itself, otherwise get the users and ratings for
            // it
            if (song.equals(line)) continue;
            // current user's rating for song under inspection
            int songRating = Integer.parseInt(currSongs.get(song));
            sqSumKey.setData(null);
            sqSumData.setData(null);
            sqSumKey.setData(song.getBytes());
            if (sqSumCurs.getSearchKey(sqSumKey, sqSumData, null) == OperationStatus.SUCCESS) {
              // if song is already in sqSum,N db, add to it
              String[] sumN = (new String(sqSumData.getData())).split(",");

              // add the new square sum to the previous and increment N
              int sum = Integer.parseInt(sumN[0]);
              int N = Integer.parseInt(sumN[1]);
              sum += (inputRating - songRating) * (inputRating - songRating);
              N += 1;
              String encoded = Integer.toString(sum) + "," + Integer.toString(N);

              // remove old entry for current song and replace it with the new one
              sqSumCurs.delete();
              sqSumKey.setData(null);
              sqSumData.setData(null);
              sqSumKey.setData(song.getBytes());
              sqSumData.setData(encoded.getBytes());
              sqSumdb.put(null, sqSumKey, sqSumData);

            } else {
              // if song in not already in sqSum,N db, create it
              int sum = (inputRating - songRating) * (inputRating - songRating);
              int N = 1;
              String encoded = Integer.toString(sum) + "," + Integer.toString(N);
              sqSumKey.setData(null);
              sqSumData.setData(null);
              sqSumKey.setData(song.getBytes());
              sqSumData.setData(encoded.getBytes());
              sqSumdb.put(null, sqSumKey, sqSumData);
            }
          }
        } else {
          System.out.println("ERROR:  user " + user + " not in secondary database.");
        }
      }
    } else {
      return line + " has not been rated by any user.";
    }
    // DEBUG
    // io.debugread(sqSumdb);

    // calculate distance for each song in, inserting into the top 3 spots as we iterate through
    String ranked = rank(sqSumdb);
    return line + ", " + ranked;
  }
예제 #6
0
  ObjectStore(
      String facet,
      String facetType,
      boolean createDb,
      EvictorI evictor,
      java.util.List<Index> indices,
      boolean populateEmptyIndices) {
    _cache = new Cache(this);

    _facet = facet;

    _evictor = evictor;
    _indices = indices;
    _communicator = evictor.communicator();
    _encoding = evictor.encoding();
    _keepStats = false;

    if (facet.equals("")) {
      _dbName = EvictorI.defaultDb;
    } else {
      _dbName = facet;
    }

    if (facetType != null) {
      //
      // Create a sample servant with this type
      //
      Ice.ValueFactory factory = _communicator.getValueFactoryManager().find(facetType);
      if (factory == null) {
        throw new DatabaseException(
            _evictor.errorPrefix() + "No value factory registered for type-id '" + facetType + "'");
      }

      _sampleServant = factory.create(facetType);
    }

    Connection connection = Util.createConnection(_communicator, evictor.dbEnv().getEnvName());

    try {
      Catalog catalog = new Catalog(connection, Util.catalogName(), true);
      CatalogData catalogData = catalog.get(evictor.filename());

      if (catalogData != null) {
        if (catalogData.evictor) {
          _keepStats = catalogData.value.isEmpty();
        } else {
          DatabaseException ex = new DatabaseException();
          ex.message = _evictor.errorPrefix() + evictor.filename() + " is not an evictor database";
          throw ex;
        }
      }

      com.sleepycat.db.Environment dbEnv = evictor.dbEnv().getEnv();

      //
      // TODO: FREEZE_DB_MODE
      //
      com.sleepycat.db.DatabaseConfig config = new com.sleepycat.db.DatabaseConfig();
      config.setType(com.sleepycat.db.DatabaseType.BTREE);
      config.setAllowCreate(createDb);

      Ice.Properties properties = _evictor.communicator().getProperties();
      String propPrefix = "Freeze.Evictor." + _evictor.filename() + ".";

      int btreeMinKey = properties.getPropertyAsInt(propPrefix + _dbName + ".BtreeMinKey");
      if (btreeMinKey > 2) {
        if (_evictor.trace() >= 1) {
          _evictor
              .communicator()
              .getLogger()
              .trace(
                  "Freeze.Evictor",
                  "Setting \""
                      + _evictor.filename()
                      + "."
                      + _dbName
                      + "\"'s btree minkey to "
                      + btreeMinKey);
        }
        config.setBtreeMinKey(btreeMinKey);
      }

      boolean checksum = properties.getPropertyAsInt(propPrefix + "Checksum") > 0;
      if (checksum) {
        if (_evictor.trace() >= 1) {
          _evictor
              .communicator()
              .getLogger()
              .trace("Freeze.Evictor", "Turning checksum on for \"" + _evictor.filename() + "\"");
        }

        config.setChecksum(true);
      }

      int pageSize = properties.getPropertyAsInt(propPrefix + "PageSize");
      if (pageSize > 0) {
        if (_evictor.trace() >= 1) {
          _evictor
              .communicator()
              .getLogger()
              .trace(
                  "Freeze.Evictor",
                  "Setting \"" + _evictor.filename() + "\"'s pagesize to " + pageSize);
        }
        config.setPageSize(pageSize);
      }

      try {
        Transaction tx = connection.beginTransaction();
        com.sleepycat.db.Transaction txn = Util.getTxn(tx);

        _db = dbEnv.openDatabase(txn, evictor.filename(), _dbName, config);

        for (Index index : _indices) {
          index.associate(this, txn, createDb, populateEmptyIndices);
        }

        if (catalogData == null) {
          catalogData = new CatalogData(true, "::Ice::Identity", "Object");
          catalog.put(evictor.filename(), catalogData);
        }

        tx.commit();
      } catch (java.io.FileNotFoundException dx) {
        throw new NotFoundException(_evictor.errorPrefix() + "Db.open: " + dx.getMessage(), dx);
      } catch (com.sleepycat.db.DatabaseException dx) {
        throw new DatabaseException(_evictor.errorPrefix() + "Db.open: " + dx.getMessage(), dx);
      } finally {
        Transaction tx = connection.currentTransaction();
        if (tx != null) {
          try {
            tx.rollback();
          } catch (DatabaseException de) {
          }
        }
      }
    } finally {
      connection.close();
    }
  }
예제 #7
0
  public int doloop() throws DatabaseException {
    Database db = null;

    for (; ; ) {
      if (db == null) {
        DatabaseConfig dbconf = new DatabaseConfig();
        dbconf.setType(DatabaseType.BTREE);
        if (dbenv.getIsMaster()) {
          /*
           * Open database allowing create only if this is a master
           * database.  A client database uses polling to attempt
           * to open the database without allowing create until
           * it is successful.
           *
           * This polling logic for allowing create can be
           * simplified under some circumstances.  For example, if
           * the application can be sure a database is already
           * there, it would never need to open it allowing create.
           */
          dbconf.setAllowCreate(true);
        }
        dbconf.setTransactional(true);

        try {
          db = dbenv.openDatabase(null, RepConfig.progname, null, dbconf);
        } catch (java.io.FileNotFoundException e) {
          System.err.println("no stock database available yet.");
          if (db != null) {
            db.close(true);
            db = null;
          }
          try {
            Thread.sleep(RepConfig.SLEEPTIME);
          } catch (InterruptedException ie) {
          }
          continue;
        }
      }

      BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));

      /* Listen for input, and add it to the database. */
      System.out.print("QUOTESERVER");
      if (!dbenv.getIsMaster()) System.out.print("(read-only)");
      System.out.print("> ");
      System.out.flush();
      String nextline = null;
      try {
        nextline = stdin.readLine();
      } catch (IOException ioe) {
        System.err.println("Unable to get data from stdin");
        break;
      }
      String[] words = nextline.split("\\s");

      /* A blank line causes the DB to be dumped to stdout. */
      if (words.length == 0 || (words.length == 1 && words[0].length() == 0)) {
        try {
          if (dbenv.getInClientSync())
            System.err.println("Cannot read data during client initialization - please try again.");
          else printStocks(db);
        } catch (DeadlockException de) {
          continue;
        } catch (DatabaseException e) {
          /*
           * This could be DB_REP_HANDLE_DEAD, which
           * should close the database and continue.
           */
          System.err.println("Got db exception reading replication" + "DB: " + e);
          System.err.println(
              "Expected if it was due to a dead "
                  + "replication handle, otherwise an unexpected error.");
          db.close(true); /* Close no sync. */
          db = null;
          continue;
        }
        continue;
      }

      if (words.length == 1
          && (words[0].compareToIgnoreCase("quit") == 0
              || words[0].compareToIgnoreCase("exit") == 0)) {
        dbenv.setAppFinished(true);
        break;
      } else if (words.length != 2) {
        System.err.println("Format: TICKER VALUE");
        continue;
      }

      if (!dbenv.getIsMaster()) {
        System.err.println("Can't update client.");
        continue;
      }

      DatabaseEntry key = new DatabaseEntry(words[0].getBytes());
      DatabaseEntry data = new DatabaseEntry(words[1].getBytes());

      db.put(null, key, data);
    }
    if (db != null) db.close(true);
    return 0;
  }
예제 #8
0
  /** Open all storage containers, indices, and catalogs. */
  public SampleDatabase(String homeDirectory) throws DatabaseException, FileNotFoundException {

    // Open the Berkeley DB environment in transactional mode.
    //
    System.out.println("Opening environment in: " + homeDirectory);
    EnvironmentConfig envConfig = new EnvironmentConfig();
    envConfig.setTransactional(true);
    envConfig.setAllowCreate(true);
    envConfig.setInitializeCache(true);
    envConfig.setInitializeLocking(true);
    env = new Environment(new File(homeDirectory), envConfig);

    // Set the Berkeley DB config for opening all stores.
    //
    DatabaseConfig dbConfig = new DatabaseConfig();
    dbConfig.setTransactional(true);
    dbConfig.setAllowCreate(true);
    dbConfig.setType(DatabaseType.BTREE);

    // Create the Serial class catalog.  This holds the serialized class
    // format for all database records of serial format.
    //
    Database catalogDb = env.openDatabase(null, CLASS_CATALOG, null, dbConfig);
    javaCatalog = new StoredClassCatalog(catalogDb);

    // Open the Berkeley DB database for the part, supplier and shipment
    // stores.  The stores are opened with no duplicate keys allowed.
    //
    partDb = env.openDatabase(null, PART_STORE, null, dbConfig);

    supplierDb = env.openDatabase(null, SUPPLIER_STORE, null, dbConfig);

    shipmentDb = env.openDatabase(null, SHIPMENT_STORE, null, dbConfig);

    // Open the SecondaryDatabase for the city index of the supplier store,
    // and for the part and supplier indices of the shipment store.
    // Duplicate keys are allowed since more than one supplier may be in
    // the same city, and more than one shipment may exist for the same
    // supplier or part.  A foreign key constraint is defined for the
    // supplier and part indices to ensure that a shipment only refers to
    // existing part and supplier keys.  The CASCADE delete action means
    // that shipments will be deleted if their associated part or supplier
    // is deleted.
    //
    SecondaryConfig secConfig = new SecondaryConfig();
    secConfig.setTransactional(true);
    secConfig.setAllowCreate(true);
    secConfig.setType(DatabaseType.BTREE);
    secConfig.setSortedDuplicates(true);

    secConfig.setKeyCreator(
        new SupplierByCityKeyCreator(
            javaCatalog, SupplierKey.class, SupplierData.class, String.class));
    supplierByCityDb =
        env.openSecondaryDatabase(null, SUPPLIER_CITY_INDEX, null, supplierDb, secConfig);

    secConfig.setForeignKeyDatabase(partDb);
    secConfig.setForeignKeyDeleteAction(ForeignKeyDeleteAction.CASCADE);
    secConfig.setKeyCreator(
        new ShipmentByPartKeyCreator(
            javaCatalog, ShipmentKey.class, ShipmentData.class, PartKey.class));
    shipmentByPartDb =
        env.openSecondaryDatabase(null, SHIPMENT_PART_INDEX, null, shipmentDb, secConfig);

    secConfig.setForeignKeyDatabase(supplierDb);
    secConfig.setForeignKeyDeleteAction(ForeignKeyDeleteAction.CASCADE);
    secConfig.setKeyCreator(
        new ShipmentBySupplierKeyCreator(
            javaCatalog, ShipmentKey.class, ShipmentData.class, SupplierKey.class));
    shipmentBySupplierDb =
        env.openSecondaryDatabase(null, SHIPMENT_SUPPLIER_INDEX, null, shipmentDb, secConfig);
  }
예제 #9
0
  //
  // Initialize the database to the number of accounts, branches,
  // history records, and tellers given to the constructor.
  //
  public void populate() {
    Database dbp = null;

    int err;
    int balance, idnum;
    int end_anum, end_bnum, end_tnum;
    int start_anum, start_bnum, start_tnum;
    int h_nelem;

    idnum = BEGID;
    balance = 500000;

    h_nelem = accounts;

    try {
      DatabaseConfig config = new DatabaseConfig();
      config.setType(DatabaseType.HASH);
      config.setHashNumElements(h_nelem);
      config.setAllowCreate(true);
      dbp = dbenv.openDatabase(null, "account", null, config);
    } catch (Exception e1) {
      // can be DatabaseException or FileNotFoundException
      errExit(e1, "Open of account file failed");
    }

    start_anum = idnum;
    populateTable(dbp, idnum, balance, h_nelem, "account");
    idnum += h_nelem;
    end_anum = idnum - 1;
    try {
      dbp.close();
    } catch (DatabaseException e2) {
      errExit(e2, "Account file close failed");
    }

    if (verbose)
      System.out.println(
          "Populated accounts: " + String.valueOf(start_anum) + " - " + String.valueOf(end_anum));

    //
    // Since the number of branches is very small, we want to use very
    // small pages and only 1 key per page.  This is the poor-man's way
    // of getting key locking instead of page locking.
    //
    h_nelem = (int) branches;

    try {
      DatabaseConfig config = new DatabaseConfig();
      config.setType(DatabaseType.HASH);
      config.setHashNumElements(h_nelem);
      config.setHashFillFactor(1);
      config.setPageSize(512);
      config.setAllowCreate(true);
      dbp = dbenv.openDatabase(null, "branch", null, config);
    } catch (Exception e3) {
      // can be DatabaseException or FileNotFoundException
      errExit(e3, "Branch file create failed");
    }

    start_bnum = idnum;
    populateTable(dbp, idnum, balance, h_nelem, "branch");
    idnum += h_nelem;
    end_bnum = idnum - 1;

    try {
      dbp.close();
    } catch (DatabaseException dbe4) {
      errExit(dbe4, "Close of branch file failed");
    }

    if (verbose)
      System.out.println(
          "Populated branches: " + String.valueOf(start_bnum) + " - " + String.valueOf(end_bnum));

    //
    // In the case of tellers, we also want small pages, but we'll let
    // the fill factor dynamically adjust itself.
    //
    h_nelem = (int) tellers;

    try {
      DatabaseConfig config = new DatabaseConfig();
      config.setType(DatabaseType.HASH);
      config.setHashNumElements(h_nelem);
      config.setHashFillFactor(0);
      config.setPageSize(512);
      config.setAllowCreate(true);
      dbp = dbenv.openDatabase(null, "teller", null, config);
    } catch (Exception e5) {
      // can be DatabaseException or FileNotFoundException
      errExit(e5, "Teller file create failed");
    }

    start_tnum = idnum;
    populateTable(dbp, idnum, balance, h_nelem, "teller");
    idnum += h_nelem;
    end_tnum = idnum - 1;

    try {
      dbp.close();
    } catch (DatabaseException e6) {
      errExit(e6, "Close of teller file failed");
    }

    if (verbose)
      System.out.println(
          "Populated tellers: " + String.valueOf(start_tnum) + " - " + String.valueOf(end_tnum));

    try {
      DatabaseConfig config = new DatabaseConfig();
      config.setType(DatabaseType.RECNO);
      config.setRecordLength(HISTORY_LEN);
      config.setAllowCreate(true);
      dbp = dbenv.openDatabase(null, "history", null, config);
    } catch (Exception e7) {
      // can be DatabaseException or FileNotFoundException
      errExit(e7, "Create of history file failed");
    }

    populateHistory(dbp);

    try {
      dbp.close();
    } catch (DatabaseException e8) {
      errExit(e8, "Close of history file failed");
    }
  }
예제 #10
0
  @Test
  public void testDraining() throws Exception {
    EnvironmentConfig masterConfig = makeBasicConfig();
    masterConfig.setReplicationLimit(100000000);
    ReplicationManagerSiteConfig site = new ReplicationManagerSiteConfig("localhost", masterPort);
    site.setLocalSite(true);
    site.setLegacy(true);
    masterConfig.addReplicationManagerSite(site);

    site = new ReplicationManagerSiteConfig("localhost", clientPort);
    site.setLegacy(true);
    masterConfig.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", client2Port);
    site.setLegacy(true);
    masterConfig.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", client3Port);
    site.setLegacy(true);
    masterConfig.addReplicationManagerSite(site);

    Environment master = new Environment(mkdir("master"), masterConfig);
    setTimeouts(master);
    // Prevent connection retries, so that all connections
    // originate from clients
    master.setReplicationTimeout(ReplicationTimeoutType.CONNECTION_RETRY, Integer.MAX_VALUE);
    master.replicationManagerStart(2, ReplicationManagerStartPolicy.REP_MASTER);

    DatabaseConfig dc = new DatabaseConfig();
    dc.setTransactional(true);
    dc.setAllowCreate(true);
    dc.setType(DatabaseType.BTREE);
    dc.setPageSize(4096);
    Database db = master.openDatabase(null, "test.db", null, dc);

    DatabaseEntry key = new DatabaseEntry();
    DatabaseEntry value = new DatabaseEntry();
    value.setData(data);

    for (int i = 0; ((BtreeStats) db.getStats(null, null)).getPageCount() < 500; i++) {
      String k = "The record number is: " + i;
      key.setData(k.getBytes());
      db.put(null, key, value);
    }

    // tell fiddler to stop reading once it sees a PAGE message
    Socket s = new Socket("localhost", mgrPort);
    OutputStreamWriter w = new OutputStreamWriter(s.getOutputStream());

    String path1 = "{" + masterPort + "," + clientPort + "}"; // looks like {6000,6001}
    w.write("{init," + path1 + ",page_clog}\r\n");
    w.flush();
    BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
    br.readLine();
    assertEquals("ok", br.readLine());
    // create client
    //
    EnvironmentConfig ec = makeBasicConfig();
    site = new ReplicationManagerSiteConfig("localhost", clientPort);
    site.setLocalSite(true);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", masterPort);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", client2Port);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", client3Port);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    Environment client = new Environment(mkdir("client"), ec);
    setTimeouts(client);
    client.replicationManagerStart(1, ReplicationManagerStartPolicy.REP_CLIENT);

    // wait til it gets stuck
    Thread.sleep(5000); // FIXME

    // Do the same for another client, because the master has 2
    // msg processing threads.  (It's no longer possible to
    // configure just 1.)
    String path2 = "{" + masterPort + "," + client2Port + "}";
    w.write("{init," + path2 + ",page_clog}\r\n");
    w.flush();
    br = new BufferedReader(new InputStreamReader(s.getInputStream()));
    br.readLine();
    assertEquals("ok", br.readLine());

    ec = makeBasicConfig();
    site = new ReplicationManagerSiteConfig("localhost", client2Port);
    site.setLocalSite(true);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", masterPort);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", clientPort);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", client3Port);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    Environment client2 = new Environment(mkdir("client2"), ec);
    setTimeouts(client2);
    client2.replicationManagerStart(1, ReplicationManagerStartPolicy.REP_CLIENT);

    // wait til it gets stuck
    Thread.sleep(5000);

    // With the connection stuck, the master cannot write out log
    // records for new "live" transactions.  Knowing we didn't
    // write the record, we should not bother waiting for an ack
    // that cannot possibly arrive; so we should simply return
    // quickly.  The duration should be very quick, but anything
    // less than the ack timeout indicates correct behavior (in
    // case this test runs on a slow, overloaded system).
    //
    long startTime = System.currentTimeMillis();
    key.setData("one extra record".getBytes());
    db.put(null, key, value);
    long duration = System.currentTimeMillis() - startTime;
    assertTrue("txn duration: " + duration, duration < 29000);
    System.out.println("txn duration: " + duration);
    db.close();

    // Tell fiddler to close the connections.  That should trigger
    // us to abandon the timeout.  Then create another client and
    // see that it can complete its internal init quickly.  Since
    // we have limited threads at the master, this demonstrates
    // that they were abandoned.
    //
    path1 = "{" + clientPort + "," + masterPort + "}"; // looks like {6001,6000}
    w.write("{" + path1 + ",shutdown}\r\n");
    w.flush();
    assertEquals("ok", br.readLine());
    path2 = "{" + client2Port + "," + masterPort + "}"; // looks like {6001,6000}
    w.write("{" + path2 + ",shutdown}\r\n");
    w.flush();
    assertEquals("ok", br.readLine());

    ec = makeBasicConfig();
    site = new ReplicationManagerSiteConfig("localhost", client3Port);
    site.setLocalSite(true);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", masterPort);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", clientPort);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", client2Port);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);

    EventHandler clientMonitor = new EventHandler();
    ec.setEventHandler(clientMonitor);
    Environment client3 = new Environment(mkdir("client3"), ec);
    setTimeouts(client3);
    startTime = System.currentTimeMillis();
    client3.replicationManagerStart(2, ReplicationManagerStartPolicy.REP_CLIENT);
    clientMonitor.await();
    duration = System.currentTimeMillis() - startTime;
    assertTrue("sync duration: " + duration, duration < 20000); // 20 seconds should be plenty

    client3.close();
    master.close();

    w.write("shutdown\r\n");
    w.flush();
    assertEquals("ok", br.readLine());
    s.close();
  }