/**
  * Get the objects that have been cached.
  *
  * @return
  */
 public Collection<? extends Cacheable> objectValues() {
   Collection<Cacheable> objects = new ArrayList<Cacheable>();
   for (CachedObject co : values()) {
     objects.add((Cacheable) co.getValue());
   }
   return objects;
 }
  /**
   * Reduces the number of rows held in this Cache object.
   *
   * <p>Cleanup is done by checking the accessCount of the Rows and removing the rows with the
   * lowest access count.
   *
   * <p>Index operations require that up to 5 recently accessed rows remain in the cache.
   */
  private synchronized void cleanUp() throws IOException {

    int removeCount = cacheMap.size() / 2;
    int accessTarget = cacheMap.getAccessCountCeiling(removeCount, removeCount / 8);
    ObjectCacheHashMap.ObjectCacheIterator it = cacheMap.iterator();
    int savecount = 0;

    for (; it.hasNext(); ) {
      CachedObject r = (CachedObject) it.next();

      if (it.getAccessCount() <= accessTarget) {
        if (!r.isKeepInMemory()) {
          if (r.hasChanged()) {
            rowTable[savecount++] = r;
          }

          it.remove();

          cacheBytesLength -= r.getStorageSize();
        }
      }
    }

    cacheMap.setAccessCountFloor(accessTarget);
    saveRows(savecount);
  }
  /**
   * Used when a row is deleted as a result of some DML or DDL command. Adds the file space for the
   * row to the list of free positions. If there exists more than MAX_FREE_COUNT free positions,
   * then they are probably all too small, so we start a new list.
   *
   * <p>todo: This is wrong when deleting lots of records
   *
   * <p>Then remove the row from the cache data structures.
   */
  public void remove(int i, PersistentStore store) throws HsqlException {

    CachedObject r = release(i);
    int size = r == null ? getStorageSize(i) : r.getStorageSize();

    freeBlocks.add(i, size);
  }
示例#4
0
 public boolean containsValue(Object value) {
   if (null != value) {
     for (CachedObject<V> cache : map.values()) {
       if (value.equals(cache.get())) return true;
     }
   }
   return false;
 }
  /**
   * Writes out the specified Row. Will write only the Nodes or both Nodes and table row data
   * depending on what is not already persisted to disk.
   */
  private void saveRow(CachedObject row) throws IOException {

    setFileModified();
    rowOut.reset();
    row.write(rowOut);
    dataFile.seek((long) row.getPos() * cacheFileScale);
    dataFile.write(rowOut.getOutputStream().getBuffer(), 0, rowOut.getOutputStream().size());
  }
示例#6
0
  public V remove(Object key) {
    CachedObject<V> cache = map.remove(key);

    if (cache == null) {
      return null;
    }
    V obj = cache.get();
    return obj;
  }
  public void add(CachedObject object) {

    int size = object.getRealSize(cache.rowOut);

    size = cache.rowOut.getStorageSize(size);

    object.setStorageSize(size);
    cache.add(object);
  }
  public synchronized int getStorageSize(int i) throws IOException {

    CachedObject value = cache.get(i);

    if (value != null) {
      return value.getStorageSize();
    }

    return readSize(i);
  }
 /**
  * Convenience method to add an object with its key to the cache. This creates the CachedObject
  * wrapper to manage its state. If the object already exists in the cache, it updates its value.
  *
  * @param cacheable
  * @return
  */
 public CachedObject add(Cacheable cacheable) {
   Identifier key = cacheable.getIdentifier();
   CachedObject co = get(key);
   if (co == null) {
     co = new CachedObject();
     co.setKey(key.toString());
     put(key, co);
   }
   co.setValue(cacheable);
   return co;
 }
示例#10
0
 public void updateObject(String name, Date date, X object) {
   CachedObject<X> obj;
   if (cache.containsKey(name)) {
     obj = cache.get(name);
   } else {
     obj = new CachedObject<X>(name);
     cache.put(name, obj);
   }
   obj.date = date;
   obj.object = object;
 }
示例#11
0
  /** Removes an object from memory cache. Does not release the file storage. */
  public synchronized CachedObject release(int i) {

    CachedObject r = (CachedObject) cacheMap.remove(i);

    if (r == null) {
      return null;
    }

    cacheBytesLength -= r.getStorageSize();

    return r;
  }
示例#12
0
  /**
   * Store an object in the map. The object's timeout period will start from the current system
   * time.
   */
  public V put(K key, V value) {

    CachedObject<V> cache = map.get(key);

    if (cache == null) {
      map.put(key, new CachedObject<V>(value, timeout));
      return null;
    }
    V old = cache.get();
    cache.set(value);
    return old;
  }
示例#13
0
  /** {@inheritDoc} */
  @Override
  public T get(K key) {
    synchronized (cacheMap) {
      CachedObject c = (CachedObject) cacheMap.get(key);

      if (c == null) return null;
      else {
        c.lastAccessed = System.currentTimeMillis();
        return c.value;
      }
    }
  }
  public void add(CachedObject object) throws IOException {

    int size = object.getRealSize(rowOut);

    size = ((size + cachedRowPadding - 1) / cachedRowPadding) * cachedRowPadding;

    object.setStorageSize(size);

    int i = setFilePos(object);

    cache.put(i, object);

    // for text tables
    if (storeOnInsert) {
      saveRow(object);
    }
  }
  public synchronized int getStorageSize(int i) throws HsqlException {

    try {
      CachedObject value = cache.get(i);

      if (value != null) {
        return value.getStorageSize();
      }

      return readSize(i);
    } catch (IOException e) {
      database.logger.appLog.logContext(e);

      throw Trace.error(
          Trace.DATA_FILE_ERROR, Trace.DataFileCache_makeRow, new Object[] {e, fileName});
    }
  }
示例#16
0
  /**
   * Using this rather than {@link #add} will let you cache anything you please, even objects (like
   * connections to servers) that are not inherently {@link
   * edu.uiuc.ncsa.security.core.Identifiable}.
   *
   * @param key
   * @param value
   * @return
   */
  public CachedObject put(Identifier key, CachedObject value) {
    // issue is that the sorted list is a list -- adding the same cached value
    // repeatedly will result in duplicates. The real cache vets these by key.
    // It is entirely possible that a user will add a new cached object that will replace
    // a currently cached object, effectively changing how the retention policy will work with
    // it.

    CachedObject oldCO = getTheRealCache().get(key);
    if (oldCO == null) {
      // it's new
      getTheRealCache().put(key, value);
      getSortedList().add(value);

    } else {
      oldCO.setTimestamp(value.getTimestamp());
    }
    return oldCO;
  }
  /**
   * For a CacheObject that had been previously released from the cache. A new version is
   * introduced, using the preallocated space for the object.
   */
  public void restore(CachedObject object) throws IOException {

    int i = object.getPos();

    cache.put(i, object);

    // for text tables
    if (storeOnInsert) {
      saveRow(object);
    }
  }
  /**
   * For a CacheObject that had been previously released from the cache. A new version is
   * introduced, using the preallocated space for the object.
   */
  public synchronized void restore(CachedObject object) throws IOException {

    int i = object.getPos();

    cache.put(i, object);

    // was previously used for text tables
    if (storeOnInsert) {
      saveRow(object);
    }
  }
示例#19
0
  /** Writes out all modified cached Rows. */
  public synchronized void saveAll() throws IOException {

    Iterator it = cacheMap.iterator();
    int savecount = 0;

    for (; it.hasNext(); ) {
      CachedObject r = (CachedObject) it.next();

      if (r.hasChanged()) {
        rowTable[savecount++] = r;
      }
    }

    saveRows(savecount);
    Trace.printSystemOut(saveAllTimer.elapsedTimeToMessage("Cache.saveRow() total row save time"));
    Trace.printSystemOut("Cache.saveRow() total row save count = " + saveRowCount);
    Trace.printSystemOut(makeRowTimer.elapsedTimeToMessage("Cache.makeRow() total row load time"));
    Trace.printSystemOut("Cache.makeRow() total row load count = " + makeRowCount);
    Trace.printSystemOut(sortTimer.elapsedTimeToMessage("Cache.sort() total time"));
  }
  /**
   * Allocates file space for the row.
   *
   * <p>A Row is added by walking the list of CacheFree objects to see if there is available space
   * to store it, reusing space if it exists. Otherwise the file is grown to accommodate it.
   */
  private int setFilePos(CachedObject r) throws IOException {

    int rowSize = r.getStorageSize();
    int i = freeBlocks == null ? -1 : freeBlocks.get(rowSize);

    if (i == -1) {
      i = (int) (fileFreePosition / cacheFileScale);

      long newFreePosition = fileFreePosition + rowSize;

      if (newFreePosition > maxDataFileSize) {
        throw new IOException(Trace.getMessage(Trace.DATA_FILE_IS_FULL));
      }

      fileFreePosition = newFreePosition;
    }

    r.setPos(i);

    return i;
  }
示例#21
0
  /** Adds a row to the cache. */
  public synchronized void put(int key, CachedObject row) throws IOException {

    int storageSize = row.getStorageSize();

    if (cacheMap.size() >= capacity || storageSize + cacheBytesLength > bytesCapacity) {
      cleanUp();
    }

    cacheMap.put(key, row);

    cacheBytesLength += storageSize;
  }
  public synchronized CachedObject get(int i, PersistentStore store, boolean keep)
      throws HsqlException {

    if (i < 0) {
      return null;
    }

    try {
      CachedObject object = cache.get(i);

      if (object == null) {
        RowInputInterface rowInput = readObject(i);

        if (rowInput == null) {
          return null;
        }

        object = store.get(rowInput);

        // for text tables with empty rows at the beginning,
        // pos may move forward in readObject
        i = object.getPos();

        cache.put(i, object);
      }

      if (keep) {
        object.keepInMemory(true);
      }

      return object;
    } catch (IOException e) {
      database.logger.appLog.logContext(SimpleLog.LOG_ERROR, fileName + " get pos: " + i);
      database.logger.appLog.logContext(e);

      throw Trace.error(
          Trace.DATA_FILE_ERROR, Trace.DataFileCache_makeRow, new Object[] {e, fileName});
    }
  }
  public synchronized CachedObject get(int i, PersistentStore store, boolean keep)
      throws HsqlException {

    if (i < 0) {
      return null;
    }

    try {
      CachedObject value = cache.get(i);

      if (value == null) {
        boolean result = readObject(i);

        if (!result) {
          return null;
        }

        value = store.get(rowIn);

        value.setPos(i);
        cache.put(i, value);
      }

      if (keep) {
        value.keepInMemory(true);
      }

      return value;
    } catch (IOException e) {
      database.logger.appLog.logContext("" + cache + " pos: " + i);
      database.logger.appLog.logContext(e);

      throw Trace.error(
          Trace.DATA_FILE_ERROR, Trace.DataFileCache_makeRow, new Object[] {e, fileName});
    }
  }
 public CachedObject get(CachedObject object, boolean keep) {
   return (CachedObject) rowIdMap.get(object.getPos());
 }
  int[] writeTableToDataFile(Table table) throws IOException {

    Session session = database.getSessionManager().getSysSession();
    PersistentStore store = session.sessionData.getRowStore(table);
    RowOutputInterface rowOut = new RowOutputBinary(1024, scale);
    DoubleIntIndex pointerLookup =
        new DoubleIntIndex(table.getPrimaryIndex().sizeEstimate(store), false);
    int[] rootsArray = table.getIndexRootsArray();
    long pos = fileOffset;
    int count = 0;

    pointerLookup.setKeysSearchTarget();
    Error.printSystemOut("lookup begins: " + stopw.elapsedTime());

    RowIterator it = table.rowIterator(session);

    for (; it.hasNext(); count++) {
      CachedObject row = it.getNextRow();

      pointerLookup.addUnsorted(row.getPos(), (int) (pos / scale));

      if (count % 50000 == 0) {
        Error.printSystemOut("pointer pair for row " + count + " " + row.getPos() + " " + pos);
      }

      pos += row.getStorageSize();
    }

    Error.printSystemOut(table.getName().name + " list done: " + stopw.elapsedTime());

    count = 0;
    it = table.rowIterator(session);

    for (; it.hasNext(); count++) {
      CachedObject row = it.getNextRow();

      rowOut.reset();
      row.write(rowOut, pointerLookup);
      fileStreamOut.write(rowOut.getOutputStream().getBuffer(), 0, rowOut.size());

      fileOffset += row.getStorageSize();

      if ((count) % 50000 == 0) {
        Error.printSystemOut(count + " rows " + stopw.elapsedTime());
      }
    }

    for (int i = 0; i < rootsArray.length; i++) {
      if (rootsArray[i] == -1) {
        continue;
      }

      int lookupIndex = pointerLookup.findFirstEqualKeyIndex(rootsArray[i]);

      if (lookupIndex == -1) {
        throw Error.error(ErrorCode.DATA_FILE_ERROR);
      }

      rootsArray[i] = pointerLookup.getValue(lookupIndex);
    }

    setTransactionRowLookups(pointerLookup);
    Error.printSystemOut(table.getName().name + " : table converted");

    return rootsArray;
  }
示例#26
0
 public void put(CachedObject co) {
   put(new BasicIdentifier(co.getKey()), co);
 }