arrayvalueimpl.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 981 行 · 第 1/2 页

JAVA
981
字号
    Entry entry = getEntry(index);    if (entry != null) {      // php/3d48, php/39aj      Value arg = entry.toArg();      return arg;    }    else {      // php/3d49      return new ArgGetValue(this, index);    }  }  /**   * Returns the field value, creating an object if it's unset.   */  @Override  public Value getObject(Env env, Value fieldName)  {    Value value = get(fieldName);    if (! value.isset()) {      value = env.createObject();      put(fieldName, value);    }        return value;  }  /**   * Returns the value as an array.   */  public Value getArray(Value index)  {    if (_isDirty)      copyOnWrite();        Value value = get(index);    Value array = value.toAutoArray();        if (value != array) {      value = array;      put(index, value);    }    return value;  }  /**   * Returns the value as an array, using copy on write if necessary.   */  public Value getDirty(Value index)  {    if (_isDirty)      copyOnWrite();        return get(index);  }    /**   * Add   */  public Value put(Value value)  {    if (_isDirty)       copyOnWrite();        Value key = createTailKey();    put(key, value);    return value;  }  /**   * Sets the array ref.   */  public Value putRef()  {    if (_isDirty)       copyOnWrite();        // 0d0d    Value tailKey = createTailKey();        return getRef(tailKey);  }  /**   * Creatse a tail index.   */  public Value createTailKey()  {    return LongValue.create(_nextAvailableIndex);  }  /**   * Gets a new value.   */  public Value get(Value key)  {    key = key.toKey();    int hashMask = _hashMask;    int hash = key.hashCode() & hashMask;    for (Entry entry = _entries[hash];         entry != null;         entry = entry._nextHash) {      if (key.equals(entry._key))        return entry._value.toValue(); // quercus/39a1    }    return UnsetValue.UNSET;  }  /**   * Returns the value in the array as-is.   * (i.e. without calling toValue() on it).   */  @Override  public Value getRaw(Value key)  {    key = key.toKey();    int hashMask = _hashMask;    int hash = key.hashCode() & hashMask;    for (Entry entry = _entries[hash];         entry != null;         entry = entry._nextHash) {      if (key.equals(entry._key))        return entry._value;    }    return UnsetValue.UNSET;  }    /**   * Gets a new value.   */  public Value containsKey(Value key)  {    Entry entry = getEntry(key);    if (entry != null)      return entry.getValue();    else      return null;  }  /**   * Gets a new value.   */  private Entry getEntry(Value key)  {    key = key.toKey();    int hash = key.hashCode() & _hashMask;    for (Entry entry = _entries[hash];         entry != null;         entry = entry._nextHash) {      if (key.equals(entry._key))	return entry;    }    return null;  }  /**   * Returns true if the value is set.   */  @Override  public boolean isset(Value key)  {    key = key.toKey();    int hash = key.hashCode() & _hashMask;    for (Entry entry = _entries[hash];         entry != null;         entry = entry._nextHash) {      if (key.equals(entry._key))	return true;    }    return false;  }  /**   * Removes a value.   */  @Override  public Value remove(Value key)  {    if (_isDirty)      copyOnWrite();        int capacity = _entries.length;    key = key.toKey();    int hash = key.hashCode() & _hashMask;    for (Entry entry = _entries[hash];         entry != null;         entry = entry._nextHash) {      if (key.equals(entry._key)) {        Entry nextHash = entry._nextHash;        Entry prevHash = entry._prevHash;        if (nextHash != null)          nextHash._prevHash = prevHash;        if (prevHash != null)          prevHash._nextHash = nextHash;        else          _entries[hash] = nextHash;                Entry next = entry._next;        Entry prev = entry._prev;        	if (prev != null)	  prev._next = next;	else	  _head = next;		if (next != null)	  next._prev = prev;	else	  _tail = prev;	entry._prev = null;	entry._next = null;	_current = _head;	_size--;	Value value = entry.getValue();	if (key.nextIndex(-1) == _nextAvailableIndex) {	  updateNextAvailableIndex();	}	return value;      }    }        return UnsetValue.UNSET;  }  /**   * Returns the array ref.   */  public Var getRef(Value index)  {    if (_isDirty)      copyOnWrite();        Entry entry = createEntry(index);    // quercus/0431    Value value = entry._value;    if (value instanceof Var)      return (Var) value;    Var var = new Var(value);    entry.setValue(var);        return var;  }  /**   * Creates the entry for a key.   */  private Entry createEntry(Value key)  {    // XXX: "A key may be either an integer or a string. If a key is    //       the standard representation of an integer, it will be    //       interpreted as such (i.e. "8" will be interpreted as 8,    //       while "08" will be interpreted as "08")."    //    //            http://us3.php.net/types.array    if (_isDirty)      copyOnWrite();        key = key.toKey();        int hashMask = _hashMask;    int hash = key.hashCode() & hashMask;    for (Entry entry = _entries[hash];         entry != null;         entry = entry._nextHash) {      if (key.equals(entry._key))	return entry;    }        _size++;    Entry newEntry = new Entry(key);    _nextAvailableIndex = key.nextIndex(_nextAvailableIndex);    Entry head = _entries[hash];    if (head != null)      head._prevHash = newEntry;    newEntry._nextHash = head;    _entries[hash] = newEntry;    newEntry._index = hash;    if (_head == null) {      newEntry._prev = null;      newEntry._next = null;            _head = newEntry;      _tail = newEntry;      _current = newEntry;    }    else {      newEntry._prev = _tail;      newEntry._next = null;            _tail._next = newEntry;      _tail = newEntry;    }    if (_entries.length <= 2 * _size)      expand();    return newEntry;  }  private void expand()  {    Entry []entries = _entries;        _entries = new Entry[2 * entries.length];    _hashMask = _entries.length - 1;    for (Entry entry = _head; entry != null; entry = entry._next) {      addEntry(entry);    }  }  private void addEntry(Entry entry)  {    int capacity = _entries.length;    int hash = entry._key.hashCode() & _hashMask;    Entry head = _entries[hash];    entry._nextHash = head;    entry._prevHash = null;    if (head != null)      head._prevHash = entry;    _entries[hash] = entry;    _nextAvailableIndex = entry._key.nextIndex(_nextAvailableIndex);    entry._index = hash;  }  /**   * Updates _nextAvailableIndex on a remove of the highest value   */  private void updateNextAvailableIndex()  {    _nextAvailableIndex = 0;    for (Entry entry = _head; entry != null; entry = entry._next) {      _nextAvailableIndex = entry._key.nextIndex(_nextAvailableIndex);    }  }  /**   * Pops the top value.   */  public Value pop()  {    if (_isDirty)      copyOnWrite();        if (_tail != null) {      Value value = remove(_tail._key);            return value;    }    else      return BooleanValue.FALSE;  }  public Entry getHead()  {    return _head;  }  protected Entry getTail()  {    return _tail;  }  /**   * Shuffles the array   */  public void shuffle()  {    if (_isDirty)      copyOnWrite();        Entry []values = new Entry[size()];    int length = values.length;    if (length == 0)      return;    int i = 0;    for (Entry ptr = _head; ptr != null; ptr = ptr._next)      values[i++] = ptr;    for (i = 0; i < length; i++) {      int rand = RandomUtil.nextInt(length);      Entry temp = values[rand];      values[rand] = values[i];      values[i] = temp;    }    _head = values[0];    _head._prev = null;        _tail = values[values.length - 1];    _tail._next = null;        for (i = 0; i < length; i++) {      if (i > 0)	values[i]._prev = values[i - 1];      if (i < length - 1)	values[i]._next = values[i + 1];    }    _current = _head;  }  //  // Java serialization code  //    private void writeObject(ObjectOutputStream out)    throws IOException  {    out.writeInt(_size);        for (Map.Entry<Value,Value> entry : entrySet()) {      out.writeObject(entry.getKey());      out.writeObject(entry.getValue());    }  }    private void readObject(ObjectInputStream in)    throws ClassNotFoundException, IOException  {    int size = in.readInt();        int capacity = DEFAULT_SIZE;    while (capacity < 4 * size) {      capacity *= 2;    }    _entries = new Entry[capacity];    _hashMask = _entries.length - 1;    for (int i = 0; i < size; i++) {      put((Value) in.readObject(), (Value) in.readObject());    }  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?