public boolean createSecondaryKey(
        SecondaryDatabase secondaryDb,
        DatabaseEntry keyEntry,
        DatabaseEntry dataEntry,
        DatabaseEntry resultEntry) {

      /*
       * Convert the data entry to a MyData object, extract the secondary
       * key value from it, and then convert it to the resulting
       * secondary key entry.
       */
      MyData data = dataBinding.entryToObject(dataEntry);
      String key = data.getMessage();
      if (key != null) {
        secKeyBinding.objectToEntry(key, resultEntry);
        return true;
      } else {

        /*
         * The message property of MyData is optional, so if it is null
         * then return false to prevent it from being indexed.  Note
         * that if a required key is missing or an error occurs, an
         * exception should be thrown by this method.
         */
        return false;
      }
    }
 @Override
 public synchronized void putBallot(Long instance, int ballot) {
   keyBinding.objectToEntry(instance, key);
   ballotBinding.objectToEntry(ballot, ballot_data);
   OperationStatus status = db.put(null, key, ballot_data);
   if (logger.isDebugEnabled()) {
     logger.debug("DB put ballot " + ballot + " for instance " + instance + " " + status.name());
   }
 }
 @Override
 public synchronized void putDecision(Long instance, Decision decision) {
   keyBinding.objectToEntry(instance, key);
   dataBinding.objectToEntry(decision, data);
   OperationStatus status = db.put(null, key, data);
   if (logger.isDebugEnabled()) {
     logger.debug("DB put " + decision + " " + status.name());
   }
 }
  /** Debug method */
  public synchronized void listAll() {
    Cursor cursor = db.openCursor(null, null);
    while (cursor.getNext(key, data, LockMode.DEFAULT) == OperationStatus.SUCCESS) {

      Long instance = keyBinding.entryToObject(key);
      Decision decision = dataBinding.entryToObject(data);
      System.out.println("instance " + instance + " -> " + decision + "");
    }
    cursor.close();
  }
 @Override
 public synchronized Decision getDecision(Long instance) {
   keyBinding.objectToEntry(instance, key);
   Decision decision = null;
   OperationStatus status = db.get(null, key, data, LockMode.DEFAULT);
   if (status == OperationStatus.SUCCESS) {
     decision = dataBinding.entryToObject(data);
   }
   if (logger.isDebugEnabled()) {
     logger.debug("DB get " + decision + " " + status.name());
   }
   return decision;
 }
 @Override
 public synchronized int getBallot(Long instance) {
   keyBinding.objectToEntry(instance, key);
   Integer ballot = null;
   OperationStatus status = db.get(null, key, ballot_data, LockMode.DEFAULT);
   if (status == OperationStatus.SUCCESS) {
     ballot = ballotBinding.entryToObject(ballot_data);
   }
   if (logger.isDebugEnabled()) {
     logger.debug("DB get ballot " + ballot + " for instance " + instance + " " + status.name());
   }
   return ballot.intValue();
 }
示例#7
0
  public static void main(String[] args) {
    Environment env = null;
    Database db = null;
    EnvironmentConfig envconfig = new EnvironmentConfig();
    envconfig.setAllowCreate(true);
    try {
      env = new Environment(new File("D://bdb"), envconfig);
      DatabaseConfig dbconfig = new DatabaseConfig();
      dbconfig.setAllowCreate(true);
      db = env.openDatabase(null, "dbac.db", dbconfig);
      String key = "mykey";
      DatabaseEntry thekey = new DatabaseEntry();
      thekey.setData(key.getBytes("utf-8"));

      Long value = new Long(123456);
      DatabaseEntry thevalue = new DatabaseEntry();
      EntryBinding myBinging = TupleBinding.getPrimitiveBinding(Long.class);
      myBinging.objectToEntry(value, thevalue);
      // LongBinding myLongBinging=(LongBinding)TupleBinding.getPrimitiveBinding(Long.class);
      // myLongBinging.objectToEntry(value, thevalue);
      db.put(null, thekey, thevalue);
      DatabaseEntry valueEntry = new DatabaseEntry();
      OperationStatus status = db.get(null, thekey, valueEntry, LockMode.DEFAULT);
      if (status == OperationStatus.SUCCESS) {
        // Long number=myLongBinging.entryToObject(valueEntry);
        Long number = (Long) myBinging.entryToObject(valueEntry);
        System.out.println(env.getDatabaseNames());
        System.out.println(number);
      }
    } catch (EnvironmentLockedException e) {
      e.printStackTrace();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      if (db != null) {
        try {
          db.close();
        } catch (DatabaseException e) {
          e.printStackTrace();
        }
      }
      if (env != null) {
        try {
          env.cleanLog();
          env.close();
        } catch (DatabaseException e) {
          e.printStackTrace();
        }
      }
    }
  }
  /**
   * Delete all CrawlURIs matching the given expression.
   *
   * @param match
   * @param queue
   * @param headKey
   * @return count of deleted items
   * @throws DatabaseException
   * @throws DatabaseException
   */
  public long deleteMatchingFromQueue(String match, String queue, DatabaseEntry headKey)
      throws DatabaseException {
    long deletedCount = 0;
    Pattern pattern = Pattern.compile(match);
    DatabaseEntry key = headKey;
    DatabaseEntry value = new DatabaseEntry();
    Cursor cursor = null;
    try {
      cursor = pendingUrisDB.openCursor(null, null);
      OperationStatus result = cursor.getSearchKeyRange(headKey, value, null);

      while (result == OperationStatus.SUCCESS) {
        if (value.getData().length > 0) {
          CrawlURI curi = (CrawlURI) crawlUriBinding.entryToObject(value);
          if (!curi.getClassKey().equals(queue)) {
            // rolled into next queue; finished with this queue
            break;
          }
          if (pattern.matcher(curi.toString()).matches()) {
            cursor.delete();
            deletedCount++;
          }
        }
        result = cursor.getNext(key, value, null);
      }
    } finally {
      if (cursor != null) {
        cursor.close();
      }
    }

    return deletedCount;
  }
示例#9
0
  public boolean delete(Transaction txn, K key) throws DatabaseException {

    DatabaseEntry keyEntry = new DatabaseEntry();
    keyBinding.objectToEntry(key, keyEntry);

    OperationStatus status = db.delete(txn, keyEntry);
    return (status == OperationStatus.SUCCESS);
  }
  /**
   * Get the next nearest item after the given key. Relies on external discipline -- we'll look at
   * the queues count of how many items it has -- to avoid asking for something from a range where
   * there are no associated items -- otherwise could get first item of next 'queue' by mistake.
   *
   * <p>TODO: hold within a queue's range
   *
   * @param headKey Key prefix that demarks the beginning of the range in <code>pendingUrisDB</code>
   *     we're interested in.
   * @return CrawlURI.
   * @throws DatabaseException
   */
  public CrawlURI get(DatabaseEntry headKey) throws DatabaseException {
    DatabaseEntry result = new DatabaseEntry();

    // From Linda Lee of sleepycat:
    // "You want to check the status returned from Cursor.getSearchKeyRange
    // to make sure that you have OperationStatus.SUCCESS. In that case,
    // you have found a valid data record, and result.getData()
    // (called by internally by the binding code, in this case) will be
    // non-null. The other possible status return is
    // OperationStatus.NOTFOUND, in which case no data record matched
    // the criteria. "
    OperationStatus status = getNextNearestItem(headKey, result);
    CrawlURI retVal = null;
    if (status != OperationStatus.SUCCESS) {
      LOGGER.severe(
          "See '1219854 NPE je-2.0 "
              + "entryToObject...'. OperationStatus "
              + " was not SUCCESS: "
              + status
              + ", headKey "
              + BdbWorkQueue.getPrefixClassKey(headKey.getData()));
      return null;
    }

    try {
      retVal = (CrawlURI) crawlUriBinding.entryToObject(result);
    } catch (ClassCastException cce) {
      Object obj = crawlUriBinding.entryToObject(result);
      LOGGER.log(
          Level.SEVERE,
          "see [#HER-1283]: deserialized "
              + obj.getClass()
              + " has ClassLoader "
              + obj.getClass().getClassLoader().getClass(),
          cce);
      return null;
    } catch (RuntimeExceptionWrapper rw) {
      LOGGER.log(
          Level.SEVERE,
          "expected object missing in queue " + BdbWorkQueue.getPrefixClassKey(headKey.getData()),
          rw);
      return null;
    }
    retVal.setHolderKey(headKey);
    return retVal;
  }
示例#11
0
  public boolean contains(Transaction txn, K key, LockMode lockMode) throws DatabaseException {

    DatabaseEntry keyEntry = new DatabaseEntry();
    DatabaseEntry dataEntry = NO_RETURN_ENTRY;
    keyBinding.objectToEntry(key, keyEntry);

    OperationStatus status = db.get(txn, keyEntry, dataEntry, lockMode);
    return (status == OperationStatus.SUCCESS);
  }
 @Override
 public synchronized boolean containsDecision(Long instance) {
   boolean found = false;
   keyBinding.objectToEntry(instance, key);
   OperationStatus status = db.get(null, key, data, LockMode.DEFAULT);
   if (status == OperationStatus.SUCCESS) {
     found = true;
   }
   if (logger.isDebugEnabled()) {
     logger.debug("DB contains " + instance + " " + found + " (" + status.name() + ")");
   }
   return found;
 }
 /**
  * Utility method to perform action for all pending CrawlURI instances.
  *
  * @param c Closure action to perform
  * @throws DatabaseException
  */
 protected void forAllPendingDo(Closure c) throws DatabaseException {
   DatabaseEntry key = new DatabaseEntry();
   DatabaseEntry value = new DatabaseEntry();
   Cursor cursor = pendingUrisDB.openCursor(null, null);
   while (cursor.getNext(key, value, null) == OperationStatus.SUCCESS) {
     if (value.getData().length == 0) {
       continue;
     }
     CrawlURI item = (CrawlURI) crawlUriBinding.entryToObject(value);
     c.execute(item);
   }
   cursor.close();
 }
示例#14
0
  private <V> EntityCursor<V> cursor(
      Transaction txn,
      K fromKey,
      boolean fromInclusive,
      K toKey,
      boolean toInclusive,
      ValueAdapter<V> adapter,
      CursorConfig config)
      throws DatabaseException {

    DatabaseEntry fromEntry = null;
    if (fromKey != null) {
      fromEntry = new DatabaseEntry();
      keyBinding.objectToEntry(fromKey, fromEntry);
    }
    DatabaseEntry toEntry = null;
    if (toKey != null) {
      toEntry = new DatabaseEntry();
      keyBinding.objectToEntry(toKey, toEntry);
    }
    KeyRange range = emptyRange.subRange(fromEntry, fromInclusive, toEntry, toInclusive);
    return cursor(txn, range, adapter, config);
  }
  /**
   * Put the given CrawlURI in at the appropriate place.
   *
   * @param curi
   * @throws DatabaseException
   */
  public void put(CrawlURI curi, boolean overwriteIfPresent) throws DatabaseException {
    DatabaseEntry insertKey = (DatabaseEntry) curi.getHolderKey();
    if (insertKey == null) {
      insertKey = calculateInsertKey(curi);
      curi.setHolderKey(insertKey);
    }
    DatabaseEntry value = new DatabaseEntry();
    crawlUriBinding.objectToEntry(curi, value);
    // Output tally on avg. size if level is FINE or greater.
    if (LOGGER.isLoggable(Level.FINE)) {
      tallyAverageEntrySize(curi, value);
    }
    OperationStatus status;
    if (overwriteIfPresent) {
      status = pendingUrisDB.put(null, insertKey, value);
    } else {
      status = pendingUrisDB.putNoOverwrite(null, insertKey, value);
    }

    if (status != OperationStatus.SUCCESS) {
      LOGGER.log(
          Level.SEVERE, "URI enqueueing failed; " + status + " " + curi, new RuntimeException());
    }
  }
 @Override
 public synchronized boolean trim(Long instance) {
   if (instance == 0) {
     return true;
   } // fast track
   Transaction t = null;
   if (db.getConfig().getTransactional()) {
     t = env.beginTransaction(null, null);
   }
   Cursor cursor = db.openCursor(t, null);
   boolean dirty = false;
   try {
     while (cursor.getNext(key, data, LockMode.READ_UNCOMMITTED) == OperationStatus.SUCCESS) {
       Long i = keyBinding.entryToObject(key);
       if (i < instance && cursor.delete() != OperationStatus.SUCCESS) {
         logger.error("Error deleting instance " + i + " from DB!");
         dirty = true;
       }
     }
   } finally {
     cursor.close();
     if (!dirty) {
       if (t != null) {
         t.commit();
       }
     } else {
       if (t != null) {
         t.abort();
       }
       return false;
     }
   }
   putDecision(-1L, new Decision(0, instance, 0, null));
   logger.debug("DB deltete up to instance " + instance);
   return true;
 }
  /** Insert or retrieve data */
  public void run() throws DatabaseException {
    /* Create a new, transactional database environment */
    EnvironmentConfig envConfig = new EnvironmentConfig();
    envConfig.setTransactional(true);
    envConfig.setAllowCreate(true);
    Environment exampleEnv = new Environment(envDir, envConfig);

    /* Make a database within that environment */
    Transaction txn = exampleEnv.beginTransaction(null, null);
    DatabaseConfig dbConfig = new DatabaseConfig();
    dbConfig.setTransactional(true);
    dbConfig.setAllowCreate(true);
    dbConfig.setSortedDuplicates(true);
    Database exampleDb = exampleEnv.openDatabase(txn, "bindingsDb", dbConfig);

    /*
     * In our example, the database record is composed of an integer
     * key and and instance of the MyData class as data.
     *
     * A class catalog database is needed for storing class descriptions
     * for the serial binding used below.  This avoids storing class
     * descriptions redundantly in each record.
     */
    DatabaseConfig catalogConfig = new DatabaseConfig();
    catalogConfig.setTransactional(true);
    catalogConfig.setAllowCreate(true);
    Database catalogDb = exampleEnv.openDatabase(txn, "catalogDb", catalogConfig);
    StoredClassCatalog catalog = new StoredClassCatalog(catalogDb);

    /*
     * Create a serial binding for MyData data objects.  Serial bindings
     * can be used to store any Serializable object.
     */
    EntryBinding<MyData> dataBinding = new SerialBinding<MyData>(catalog, MyData.class);

    txn.commit();

    /*
     * Further below we'll use a tuple binding (IntegerBinding
     * specifically) for integer keys.  Tuples, unlike serialized Java
     * objects, have a well defined sort order.
     */

    /* DatabaseEntry represents the key and data of each record */
    DatabaseEntry keyEntry = new DatabaseEntry();
    DatabaseEntry dataEntry = new DatabaseEntry();

    if (doInsert) {

      /* put some data in */
      for (int i = offset; i < numRecords + offset; i++) {

        StringBuilder stars = new StringBuilder();
        for (int j = 0; j < i; j++) {
          stars.append('*');
        }
        MyData data = new MyData(i, stars.toString());

        IntegerBinding.intToEntry(i, keyEntry);
        dataBinding.objectToEntry(data, dataEntry);

        txn = exampleEnv.beginTransaction(null, null);
        OperationStatus status = exampleDb.put(txn, keyEntry, dataEntry);

        /*
         * Note that put will throw a DatabaseException when
         * error conditions are found such as deadlock.
         * However, the status return conveys a variety of
         * information. For example, the put might succeed,
         * or it might not succeed if the record exists
         * and duplicates were not
         */
        if (status != OperationStatus.SUCCESS) {
          throw new RuntimeException("Data insertion got status " + status);
        }
        txn.commit();
      }
    } else {

      /* retrieve the data */
      Cursor cursor = exampleDb.openCursor(null, null);

      while (cursor.getNext(keyEntry, dataEntry, LockMode.DEFAULT) == OperationStatus.SUCCESS) {

        int key = IntegerBinding.entryToInt(keyEntry);
        MyData data = dataBinding.entryToObject(dataEntry);

        System.out.println("key=" + key + " data=" + data);
      }
      cursor.close();
    }

    catalogDb.close();
    exampleDb.close();
    exampleEnv.close();
  }
  /** Insert or retrieve data. */
  public void run() throws DatabaseException {

    /* Create a new, transactional database environment. */
    EnvironmentConfig envConfig = new EnvironmentConfig();
    envConfig.setTransactional(true);
    envConfig.setAllowCreate(true);
    Environment exampleEnv = new Environment(envDir, envConfig);

    /*
     * Make a database within that environment. Because this will be used
     * as a primary database, it must not allow duplicates. The primary key
     * of a primary database must be unique.
     */
    Transaction txn = exampleEnv.beginTransaction(null, null);
    DatabaseConfig dbConfig = new DatabaseConfig();
    dbConfig.setTransactional(true);
    dbConfig.setAllowCreate(true);
    Database exampleDb = exampleEnv.openDatabase(txn, "bindingsDb", dbConfig);

    /*
     * In our example, the database record is composed of an integer key
     * and and instance of the MyData class as data.
     *
     * A class catalog database is needed for storing class descriptions
     * for the serial binding used below.  This avoids storing class
     * descriptions redundantly in each record.
     */
    DatabaseConfig catalogConfig = new DatabaseConfig();
    catalogConfig.setTransactional(true);
    catalogConfig.setAllowCreate(true);
    Database catalogDb = exampleEnv.openDatabase(txn, "catalogDb", catalogConfig);
    StoredClassCatalog catalog = new StoredClassCatalog(catalogDb);

    /*
     * Create a serial binding for MyData data objects.  Serial
     * bindings can be used to store any Serializable object.
     */
    EntryBinding<MyData> dataBinding = new SerialBinding<MyData>(catalog, MyData.class);

    /*
     * Further below we'll use a tuple binding (IntegerBinding
     * specifically) for integer keys.  Tuples, unlike serialized
     * Java objects, have a well defined sort order.
     */

    /*
     * Define a String tuple binding for a secondary key.  The
     * secondary key is the msg field of the MyData object.
     */
    EntryBinding<String> secKeyBinding = TupleBinding.getPrimitiveBinding(String.class);

    /*
     * Open a secondary database to allow accessing the primary
     * database by the secondary key value.
     */
    SecondaryConfig secConfig = new SecondaryConfig();
    secConfig.setTransactional(true);
    secConfig.setAllowCreate(true);
    secConfig.setSortedDuplicates(true);
    secConfig.setKeyCreator(new MyKeyCreator(secKeyBinding, dataBinding));
    SecondaryDatabase exampleSecDb =
        exampleEnv.openSecondaryDatabase(txn, "bindingsSecDb", exampleDb, secConfig);
    txn.commit();

    /* DatabaseEntry represents the key and data of each record. */
    DatabaseEntry keyEntry = new DatabaseEntry();
    DatabaseEntry dataEntry = new DatabaseEntry();

    if (doInsert) {

      /*
       * Put some data in.  Note that the primary database is always used
       * to add data.  Adding or changing data in the secondary database
       * is not allowed; however, deleting through the secondary database
       * is allowed.
       */
      for (int i = offset; i < numRecords + offset; i++) {
        txn = exampleEnv.beginTransaction(null, null);
        StringBuffer stars = new StringBuffer();
        for (int j = 0; j < i; j++) {
          stars.append('*');
        }
        MyData data = new MyData(i, stars.toString());

        IntegerBinding.intToEntry(i, keyEntry);
        dataBinding.objectToEntry(data, dataEntry);

        OperationStatus status = exampleDb.put(txn, keyEntry, dataEntry);

        /*
         * Note that put will throw a DatabaseException when error
         * conditions are found such as deadlock.  However, the status
         * return conveys a variety of information. For example, the
         * put might succeed, or it might not succeed if the record
         * exists and duplicates were not
         */
        if (status != OperationStatus.SUCCESS) {
          throw new RuntimeException("Data insertion got status " + status);
        }
        txn.commit();
      }
    } else {

      /*
       * Retrieve the data by secondary key by opening a cursor on the
       * secondary database.  The key parameter for a secondary cursor is
       * always the secondary key, but the data parameter is always the
       * data of the primary database.  You can cast the cursor to a
       * SecondaryCursor and use additional method signatures for
       * retrieving the primary key also.  Or you can call
       * openSecondaryCursor() to avoid casting.
       */
      txn = exampleEnv.beginTransaction(null, null);
      Cursor cursor = exampleSecDb.openCursor(txn, null);

      while (cursor.getNext(keyEntry, dataEntry, LockMode.DEFAULT) == OperationStatus.SUCCESS) {

        String key = secKeyBinding.entryToObject(keyEntry);
        MyData data = dataBinding.entryToObject(dataEntry);

        System.out.println("key=" + key + " data=" + data);
      }
      cursor.close();
      txn.commit();
    }

    /*
     * Always close secondary databases before closing their associated
     * primary database.
     */
    catalogDb.close();
    exampleSecDb.close();
    exampleDb.close();
    exampleEnv.close();
  }
 public V entryToValue(DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data) {
   return (V) keyBinding.entryToObject(pkey);
 }
  /**
   * @param m marker or null to start with first entry
   * @param maxMatches
   * @return list of matches starting from marker position
   * @throws DatabaseException
   */
  public CompositeData getFrom(String m, int maxMatches, Pattern pattern, boolean verbose)
      throws DatabaseException {
    int matches = 0;
    int tries = 0;
    ArrayList<String> results = new ArrayList<String>(maxMatches);

    DatabaseEntry key;
    if (m == null) {
      key = getFirstKey();
    } else {
      byte[] marker = m.getBytes(); // = FrontierJMXTypes.fromString(m);
      key = new DatabaseEntry(marker);
    }

    DatabaseEntry value = new DatabaseEntry();

    Cursor cursor = null;
    OperationStatus result = null;
    try {
      cursor = pendingUrisDB.openCursor(null, null);
      result = cursor.getSearchKey(key, value, null);

      while (matches < maxMatches && result == OperationStatus.SUCCESS) {
        if (value.getData().length > 0) {
          CrawlURI curi = (CrawlURI) crawlUriBinding.entryToObject(value);
          if (pattern.matcher(curi.toString()).matches()) {
            if (verbose) {
              results.add("[" + curi.getClassKey() + "] " + curi.shortReportLine());
            } else {
              results.add(curi.toString());
            }
            matches++;
          }
          tries++;
        }
        result = cursor.getNext(key, value, null);
      }
    } finally {
      if (cursor != null) {
        cursor.close();
      }
    }

    if (result != OperationStatus.SUCCESS) {
      // end of scan
      m = null;
    } else {
      m = new String(key.getData()); // = FrontierJMXTypes.toString(key.getData());
    }

    String[] arr = results.toArray(new String[results.size()]);
    CompositeData cd;
    try {
      cd =
          new CompositeDataSupport(
              /*FrontierJMXTypes.URI_LIST_DATA*/ null,
              new String[] {"list", "marker"},
              new Object[] {arr, m});
    } catch (OpenDataException e) {
      throw new IllegalStateException(e);
    }
    return cd;
  }