Exemple #1
0
  /**
   * Do a group update for data associated with a given key
   *
   * @param accessor accessor with the ability to pull from the current data
   * @param options see {@link AccessOption}
   * @param key the data identifier
   * @param record the data to be merged in
   * @return true if successful, false otherwise
   */
  public boolean commit(
      BaseDataAccessor<ZNRecord> accessor, int options, String key, ZNRecord record) {
    Queue queue = getQueue(key);
    Entry entry = new Entry(key, record);

    queue._pending.add(entry);

    while (!entry._sent.get()) {
      if (queue._running.compareAndSet(null, Thread.currentThread())) {
        ArrayList<Entry> processed = new ArrayList<Entry>();
        try {
          if (queue._pending.peek() == null) return true;

          // remove from queue
          Entry first = queue._pending.poll();
          processed.add(first);

          String mergedKey = first._key;
          // ZNRecord merged = _cache.get(mergedKey);
          ZNRecord merged = null;

          try {
            // accessor will fallback to zk if not found in cache
            merged = accessor.get(mergedKey, null, options);
          } catch (ZkNoNodeException e) {
            // OK.
          }

          /**
           * If the local cache does not contain a value, need to check if there is a value in ZK;
           * use it as initial value if exists
           */
          if (merged == null) {
            // ZNRecord valueOnZk = null;
            // try
            // {
            // valueOnZk = accessor.get(mergedKey, null, 0);
            // }
            // catch(Exception e)
            // {
            // LOG.info(e);
            // }
            // if(valueOnZk != null)
            // {
            // merged = valueOnZk;
            // merged.merge(first._record);
            // }
            // else // Zk path has null data. use the first record as initial record.
            {
              merged = new ZNRecord(first._record);
            }
          } else {
            merged.merge(first._record);
          }
          Iterator<Entry> it = queue._pending.iterator();
          while (it.hasNext()) {
            Entry ent = it.next();
            if (!ent._key.equals(mergedKey)) continue;
            processed.add(ent);
            merged.merge(ent._record);
            // System.out.println("After merging:" + merged);
            it.remove();
          }
          // System.out.println("size:"+ processed.size());
          accessor.set(mergedKey, merged, options);
          // accessor.set(mergedKey, merged, BaseDataAccessor.Option.PERSISTENT);
          // _cache.put(mergedKey, merged);
        } finally {
          queue._running.set(null);
          for (Entry e : processed) {
            synchronized (e) {
              e._sent.set(true);
              e.notify();
            }
          }
        }
      } else {
        synchronized (entry) {
          try {
            entry.wait(10);
          } catch (InterruptedException e) {
            e.printStackTrace();
            return false;
          }
        }
      }
    }
    return true;
  }