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 + -
显示快捷键?