Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.python.core.PyStringMap Maven / Gradle / Ivy
Go to download
Jython is an implementation of the high-level, dynamic, object-oriented
language Python written in 100% Pure Java, and seamlessly integrated with
the Java platform. It thus allows you to run Python on any Java platform.
/*
* Copyright (c) Corporation for National Research Initiatives
* Copyright (c) Jython Developers
*/
package org.python.core;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.AbstractSet;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.python.core.AbstractDict.ValuesIter;
import org.python.core.AbstractDict.KeysIter;
import org.python.core.AbstractDict.ItemsIter;
import org.python.core.PyMapSet.PySetIter;
import org.python.expose.ExposedClassMethod;
import org.python.expose.ExposedMethod;
import org.python.expose.ExposedNew;
import org.python.expose.ExposedType;
import org.python.expose.MethodType;
import org.python.util.Generic;
/**
* Special fast dict implementation for __dict__ instances. Allows interned String keys in addition
* to PyObject unlike PyDictionary.
*/
@ExposedType(name = "stringmap", base = PyObject.class, isBaseType = false)
public class PyStringMap extends AbstractDict implements Traverseproc {
/**
* TYPE computed lazily, PyStringMap is used early in the bootstrap process and
* statically calling fromClass(PyStringMap.class) is unsafe.
*/
private static PyType lazyType;
private final ConcurrentMap table;
public ConcurrentMap getMap() {
return table;
}
public PyStringMap() {
this(4);
}
public PyStringMap(int capacity) {
super(getLazyType());
table = new ConcurrentHashMap(capacity, Generic.CHM_LOAD_FACTOR,
Generic.CHM_CONCURRENCY_LEVEL);
}
public PyStringMap(Map map) {
this(Math.max((int) (map.size() / Generic.CHM_LOAD_FACTOR) + 1,
Generic.CHM_INITIAL_CAPACITY));
table.putAll(map);
}
public PyStringMap(PyObject elements[]) {
this(elements.length);
for (int i = 0; i < elements.length; i += 2) {
__setitem__(elements[i], elements[i + 1]);
}
}
private static PyType getLazyType() {
if (lazyType == null) {
lazyType = PyType.fromClass(PyStringMap.class);
}
return lazyType;
}
@ExposedNew
final static PyObject stringmap_new(PyNewWrapper new_, boolean init, PyType subtype,
PyObject[] args, String[] keywords) {
PyStringMap map = new PyStringMap();
map.stringmap_update(args, keywords);
return map;
}
public static PyObject fromkeys(PyObject keys) {
return fromkeys(keys, Py.None);
}
public static PyObject fromkeys(PyObject keys, PyObject value) {
return stringmap_fromkeys(TYPE, keys, value);
}
@ExposedClassMethod(defaults = "Py.None", doc = BuiltinDocs.dict_fromkeys_doc)
static PyObject stringmap_fromkeys(PyType type, PyObject keys, PyObject value) {
PyObject d = type.__call__();
for (PyObject o : keys.asIterable()) {
d.__setitem__(o, value);
}
return d;
}
@Override
public int __len__() {
return stringmap___len__();
}
@ExposedMethod(doc = BuiltinDocs.dict___len___doc)
final int stringmap___len__() {
return table.size();
}
@Override
public boolean __nonzero__() {
return table.size() != 0;
}
@Override
public PyObject __finditem__(String key) {
if (key == null) {
return null;
}
return table.get(key);
}
@Override
public PyObject __finditem__(PyObject key) {
if (key instanceof PyString) {
return __finditem__(((PyString)key).internedString());
}
return table.get(key);
}
public PyObject __getitem__(String key) {
PyObject o = __finditem__(key);
if (null == o) {
throw Py.KeyError(key);
} else {
return o;
}
}
@Override
public PyObject __getitem__(PyObject key) {
return stringmap___getitem__(key);
}
@ExposedMethod(doc = BuiltinDocs.dict___getitem___doc)
final PyObject stringmap___getitem__(PyObject key) {
if (key instanceof PyString) {
return __getitem__(((PyString)key).internedString());
} else {
PyObject o = __finditem__(key);
if (null == o) {
throw Py.KeyError(key);
} else {
return o;
}
}
}
@Override
public PyObject __iter__() {
return stringmap___iter__();
}
@ExposedMethod(doc = BuiltinDocs.dict___iter___doc)
final PyObject stringmap___iter__() {
return stringmap_iterkeys();
}
@Override
public void __setitem__(String key, PyObject value) {
if (value == null) {
table.remove(key);
} else {
table.put(key, value);
}
}
@Override
public void __setitem__(PyObject key, PyObject value) {
stringmap___setitem__(key, value);
}
@ExposedMethod(doc = BuiltinDocs.dict___setitem___doc)
final void stringmap___setitem__(PyObject key, PyObject value) {
if (value == null) {
table.remove(pyToKey(key));
} else if (key instanceof PyString) {
__setitem__(((PyString)key).internedString(), value);
} else {
table.put(key, value);
}
}
@Override
public void __delitem__(String key) {
Object ret = table.remove(key);
if (ret == null) {
throw Py.KeyError(key);
}
}
@Override
public void __delitem__(PyObject key) {
stringmap___delitem__(key);
}
@ExposedMethod(doc = BuiltinDocs.dict___delitem___doc)
final void stringmap___delitem__(PyObject key) {
if (key instanceof PyString) {
__delitem__(((PyString)key).internedString());
} else {
Object ret = table.remove(key);
if (ret == null) {
throw Py.KeyError(key);
}
}
}
/**
* Remove all items from the dictionary.
*/
public void clear() {
stringmap_clear();
}
@ExposedMethod(doc = BuiltinDocs.dict_clear_doc)
final void stringmap_clear() {
table.clear();
}
@Override
public String toString() {
return stringmap_toString();
}
@ExposedMethod(names = {"__repr__", "__str__"}, doc = BuiltinDocs.dict___str___doc)
final String stringmap_toString() {
ThreadState ts = Py.getThreadState();
if (!ts.enterRepr(this)) {
return "{...}";
}
StringBuilder buf = new StringBuilder("{");
for (Entry entry : table.entrySet()) {
Object key = entry.getKey();
if (key instanceof String) {
/* This is a bit complicated, but prevents us to duplicate
PyString#__repr__ logic here. */
buf.append(new PyString((String)key).__repr__().toString());
} else {
buf.append(((PyObject)key).__repr__().toString());
}
buf.append(": ");
buf.append(entry.getValue().__repr__().toString());
buf.append(", ");
}
if (buf.length() > 1) {
buf.delete(buf.length() - 2, buf.length());
}
buf.append("}");
ts.exitRepr(this);
return buf.toString();
}
@Override
public int __cmp__(PyObject other) {
return stringmap___cmp__(other);
}
@ExposedMethod(type = MethodType.CMP, doc = BuiltinDocs.dict___cmp___doc)
final int stringmap___cmp__(PyObject other) {
if (!(other instanceof AbstractDict)) {
return -2;
}
int an = __len__();
int bn = other.__len__();
if (an < bn) {
return -1;
}
if (an > bn) {
return 1;
}
PyList akeys = keys();
PyList bkeys = ((AbstractDict) other).keys();
akeys.sort();
bkeys.sort();
for (int i = 0; i < bn; i++) {
PyObject akey = akeys.pyget(i);
PyObject bkey = bkeys.pyget(i);
int c = akey._cmp(bkey);
if (c != 0) {
return c;
}
PyObject avalue = __finditem__(akey);
PyObject bvalue = other.__finditem__(bkey);
c = avalue._cmp(bvalue);
if (c != 0) {
return c;
}
}
return 0;
}
/**
* Return true if the key exist in the dictionary.
*/
public boolean has_key(String key) {
return table.containsKey(key);
}
public boolean has_key(PyObject key) {
return stringmap_has_key(key);
}
@ExposedMethod(doc = BuiltinDocs.dict_has_key_doc)
final boolean stringmap_has_key(PyObject key) {
return table.containsKey(pyToKey(key));
}
@Override
public boolean __contains__(PyObject o) {
return stringmap___contains__(o);
}
@ExposedMethod(doc = BuiltinDocs.dict___contains___doc)
final boolean stringmap___contains__(PyObject o) {
return stringmap_has_key(o);
}
/**
* Return this[key] if the key exists in the mapping, defaultObj is returned otherwise.
*
* @param key
* the key to lookup in the mapping.
* @param defaultObj
* the value to return if the key does not exists in the mapping.
*/
public PyObject get(PyObject key, PyObject defaultObj) {
return stringmap_get(key, defaultObj);
}
@ExposedMethod(defaults = "Py.None", doc = BuiltinDocs.dict_get_doc)
final PyObject stringmap_get(PyObject key, PyObject defaultObj) {
PyObject obj = __finditem__(key);
return obj == null ? defaultObj : obj;
}
/**
* Return this[key] if the key exists in the mapping, None is returned otherwise.
*
* @param key
* the key to lookup in the mapping.
*/
public PyObject get(PyObject key) {
return stringmap_get(key, Py.None);
}
/**
* Return a shallow copy of the dictionary.
*/
public PyStringMap copy() {
return stringmap_copy();
}
@ExposedMethod(doc = BuiltinDocs.dict_copy_doc)
final PyStringMap stringmap_copy() {
return new PyStringMap(table);
}
public void update(PyObject other) {
stringmap_update(new PyObject[] {other}, Py.NoKeywords);
}
/**
* Insert all the key:value pairs from dict
into this mapping.
*/
@ExposedMethod(doc = BuiltinDocs.dict_update_doc)
final void stringmap_update(PyObject[] args, String[] keywords) {
int nargs = args.length - keywords.length;
if (nargs > 1) {
throw PyBuiltinCallable.DefaultInfo.unexpectedCall(nargs, false, "update", 0, 1);
}
if (nargs == 1) {
PyObject arg = args[0];
if (arg.__findattr__("keys") != null) {
merge(arg);
} else {
mergeFromSeq(arg);
}
}
for (int i = 0; i < keywords.length; i++) {
__setitem__(keywords[i], args[nargs + i]);
}
}
/**
* Merge another PyObject that supports keys() with this
* dict.
*
* @param other a PyObject with a keys() method
*/
private void merge(PyObject other) {
if (other instanceof PyStringMap) {
table.putAll(((PyStringMap)other).table);
} else if (other instanceof PyDictionary) {
mergeFromKeys(other, ((PyDictionary)other).keys());
} else {
mergeFromKeys(other, other.invoke("keys"));
}
}
/**
* Merge another PyObject that supports keys() with this
* dict.
*
* @param other a PyObject with a keys() method
* @param override if true, the value from other is used on key-collision
*/
public void merge(PyObject other, boolean override) {
synchronized(table) {
if (override) {
merge(other);
} else {
if (other instanceof PyStringMap) {
Set> entrySet =
((PyStringMap)other).table.entrySet();
for (Map.Entry ent: entrySet) {
if (!table.containsKey(ent.getKey())) {
table.put(ent.getKey(), ent.getValue());
}
}
} else if (other instanceof PyDictionary) {
mergeFromKeys(other, ((PyDictionary)other).keys(), override);
} else {
mergeFromKeys(other, other.invoke("keys"), override);
}
}
}
}
/**
* Merge another PyObject via its keys() method
*
* @param other a PyObject with a keys() method
* @param keys the result of other's keys() method
*/
private void mergeFromKeys(PyObject other, PyObject keys) {
for (PyObject key : keys.asIterable()) {
__setitem__(key, other.__getitem__(key));
}
}
/**
* Merge another PyObject via its keys() method
*
* @param other a PyObject with a keys() method
* @param keys the result of other's keys() method
* @param override if true, the value from other is used on key-collision
*/
public void mergeFromKeys(PyObject other, PyObject keys, boolean override) {
synchronized(table) {
if (override) {
mergeFromKeys(other, keys);
} else {
for (PyObject key : keys.asIterable()) {
if (!__contains__(key)) {
__setitem__(key, other.__getitem__(key));
}
}
}
}
}
/**
* Merge any iterable object producing iterable objects of length
* 2 into this dict.
*
* @param other another PyObject
*/
private void mergeFromSeq(PyObject other) {
PyObject pairs = other.__iter__();
PyObject pair;
for (int i = 0; (pair = pairs.__iternext__()) != null; i++) {
try {
pair = PySequence.fastSequence(pair, "");
} catch(PyException pye) {
if (pye.match(Py.TypeError)) {
throw Py.TypeError(String.format("cannot convert dictionary update sequence "
+ "element #%d to a sequence", i));
}
throw pye;
}
int n;
if ((n = pair.__len__()) != 2) {
throw Py.ValueError(String.format("dictionary update sequence element #%d "
+ "has length %d; 2 is required", i, n));
}
__setitem__(pair.__getitem__(0), pair.__getitem__(1));
}
}
/**
* Merge any iterable object producing iterable objects of length
* 2 into this dict.
*
* @param other another PyObject
* @param override if true, the value from other is used on key-collision
*/
public void mergeFromSeq(PyObject other, boolean override) {
synchronized(table) {
if (override) {
mergeFromSeq(other);
} else {
PyObject pairs = other.__iter__();
PyObject pair;
for (int i = 0; (pair = pairs.__iternext__()) != null; i++) {
try {
pair = PySequence.fastSequence(pair, "");
} catch(PyException pye) {
if (pye.match(Py.TypeError)) {
throw Py.TypeError(String.format("cannot convert dictionary update sequence "
+ "element #%d to a sequence", i));
}
throw pye;
}
int n;
if ((n = pair.__len__()) != 2) {
throw Py.ValueError(String.format("dictionary update sequence element #%d "
+ "has length %d; 2 is required", i, n));
}
if (!__contains__(pair.__getitem__(0))) {
__setitem__(pair.__getitem__(0), pair.__getitem__(1));
}
}
}
}
}
/**
* Return this[key] if the key exist, otherwise insert key with a None value and return None.
*
* @param key
* the key to lookup in the mapping.
*/
public PyObject setdefault(PyObject key) {
return setdefault(key, Py.None);
}
/**
* Return this[key] if the key exist, otherwise insert key with the value of failobj and return
* failobj
*
* @param key
* the key to lookup in the mapping.
* @param failobj
* the default value to insert in the mapping if key does not already exist.
*/
public PyObject setdefault(PyObject key, PyObject failobj) {
return stringmap_setdefault(key, failobj);
}
@ExposedMethod(defaults = "Py.None", doc = BuiltinDocs.dict_setdefault_doc)
final PyObject stringmap_setdefault(PyObject key, PyObject failobj) {
Object internedKey = (key instanceof PyString) ? ((PyString)key).internedString() : key;
PyObject oldValue = table.putIfAbsent(internedKey, failobj);
return oldValue == null ? failobj : oldValue;
}
/**
* Return a random (key, value) tuple pair and remove the pair from the mapping.
*/
public PyObject popitem() {
return stringmap_popitem();
}
@ExposedMethod(doc = BuiltinDocs.dict_popitem_doc)
final PyObject stringmap_popitem() {
Iterator> it = table.entrySet().iterator();
if (!it.hasNext()) {
throw Py.KeyError("popitem(): dictionary is empty");
}
PyTuple tuple = itemTuple(it.next());
it.remove();
return tuple;
}
/* not correct - we need to determine size and remove at the same time! */
public PyObject pop(PyObject key) {
if (table.size() == 0) {
throw Py.KeyError("pop(): dictionary is empty");
}
return stringmap_pop(key, null);
}
public PyObject pop(PyObject key, PyObject failobj) {
return stringmap_pop(key, failobj);
}
@ExposedMethod(defaults = "null", doc = BuiltinDocs.dict_pop_doc)
final PyObject stringmap_pop(PyObject key, PyObject failobj) {
PyObject value = table.remove(pyToKey(key));
if (value == null) {
if (failobj == null) {
throw Py.KeyError(key);
} else {
return failobj;
}
}
return value;
}
/**
* Return a copy of the mappings list of (key, value) tuple pairs.
*/
public PyList items() {
return stringmap_items();
}
@ExposedMethod(doc = BuiltinDocs.dict_items_doc)
final PyList stringmap_items() {
return new PyList(stringmap_iteritems());
}
private PyTuple itemTuple(Entry entry) {
return new PyTuple(keyToPy(entry.getKey()), entry.getValue());
}
/**
* Return a copy of the mappings list of keys. We have to take in account that we could be
* storing String or PyObject objects
*/
public PyList keys() {
return stringmap_keys();
}
@ExposedMethod(doc = BuiltinDocs.dict_keys_doc)
final PyList stringmap_keys() {
Object[] keys = table.keySet().toArray();
PyObject[] keyArray = new PyObject[keys.length];
int i = 0;
for (Object key : keys) {
keyArray[i++] = keyToPy(key);
}
return new PyList(keyArray);
}
/**
* Return a copy of the mappings list of values.
*/
public PyList values() {
return stringmap_values();
}
@ExposedMethod(doc = BuiltinDocs.dict_values_doc)
final PyList stringmap_values() {
return new PyList(table.values());
}
/**
* return an iterator over (key, value) pairs
*/
public PyObject iteritems() {
return stringmap_iteritems();
}
@ExposedMethod(doc = BuiltinDocs.dict_iteritems_doc)
final PyObject stringmap_iteritems() {
return new StringMapItemsIter(table.entrySet());
}
/**
* return an iterator over the keys
*/
public PyObject iterkeys() {
return stringmap_iterkeys();
}
@ExposedMethod(doc = BuiltinDocs.dict_iterkeys_doc)
final PyObject stringmap_iterkeys() {
/* Python allows one to change the dict while iterating over it, including
deletion. Java does not. Can we resolve with CHM? */
return new StringMapKeysIter(table.keySet());
}
/**
* return an iterator over the values
*/
public PyObject itervalues() {
return stringmap_itervalues();
}
@ExposedMethod(doc = BuiltinDocs.dict_itervalues_doc)
final PyObject stringmap_itervalues() {
return new StringMapValuesIter(table.values());
}
@Override
public int hashCode() {
return stringmap___hash__();
}
@ExposedMethod(doc = BuiltinDocs.dict___hash___doc)
final int stringmap___hash__() {
throw Py.TypeError(String.format("unhashable type: '%.200s'", getType().fastGetName()));
}
@Override
public boolean isMappingType() {
return true;
}
@Override
public boolean isSequenceType() {
return false;
}
private class StringMapValuesIter extends ValuesIter {
public StringMapValuesIter(Collection c) {
super(c);
}
@Override
public PyObject __iternext__() {
check(table.size());
if (!iterator.hasNext()) {
return null;
}
return iterator.next();
}
}
private class StringMapKeysIter extends KeysIter {
public StringMapKeysIter(Set s) {
super(s);
}
@Override
public PyObject __iternext__() {
check(table.size());
if (!iterator.hasNext()) {
return null;
}
return keyToPy(iterator.next());
}
}
private class StringMapItemsIter extends ItemsIter {
public StringMapItemsIter(Set> s) {
super(s);
}
@Override
public PyObject __iternext__() {
check(table.size());
if (!iterator.hasNext()) {
return null;
}
return itemTuple(iterator.next());
}
}
private static PyObject keyToPy(Object objKey){
if (objKey instanceof String) {
return PyString.fromInterned((String)objKey);
} else {
return (PyObject)objKey;
}
}
private static Object pyToKey(PyObject pyKey) {
if (pyKey instanceof PyString) {
return ((PyString)pyKey).internedString();
} else {
return pyKey;
}
}
private static class PyStringMapKeySetWrapper extends AbstractSet
{
Set backend;
PyStringMapKeySetWrapper(Set backend) {
this.backend = backend;
}
class PyStringMapKeySetIter implements Iterator {
Iterator itr;
PyStringMapKeySetIter(Iterator itr) {
this.itr = itr;
}
public boolean hasNext() {
return itr.hasNext();
}
public PyObject next() {
return keyToPy(itr.next());
}
public void remove() {
itr.remove();
}
}
@Override
public Iterator iterator() {
return new PyStringMapKeySetIter(backend.iterator());
}
@Override
public int size() {
return backend.size();
}
}
public Set pyKeySet() {
return new PyStringMapKeySetWrapper(table.keySet());
}
/** @see java.util.Map#entrySet() */
public Set entrySet() {
return new PyMapEntrySet(getMap().entrySet());
}
/**
* Returns a dict_keys on the dictionary's keys
*/
@ExposedMethod(doc = BuiltinDocs.dict_viewkeys_doc)
public PyObject viewkeys() {
return super.viewkeys();
}
/**
* Returns a dict_items on the dictionary's items
*/
@ExposedMethod(doc = BuiltinDocs.dict_viewitems_doc)
public PyObject viewitems() {
return super.viewitems();
}
/**
* Returns a dict_values on the dictionary's values
*/
@ExposedMethod(doc = BuiltinDocs.dict_viewvalues_doc)
public PyObject viewvalues() {
return super.viewvalues();
}
/* Traverseproc implementation */
@Override
public int traverse(Visitproc visit, Object arg) {
int retVal;
Object key;
PyObject value;
for (Map.Entry ent: table.entrySet()) {
key = ent.getKey();
value = ent.getValue();
if (key instanceof PyObject) {
retVal = visit.visit((PyObject) key, arg);
if (retVal != 0) return retVal;
}
if (value != null) {
retVal = visit.visit(value, arg);
if (retVal != 0) return retVal;
}
}
return 0;
}
@Override
public boolean refersDirectlyTo(PyObject ob) {
return ob != null && (table.containsKey(ob) || table.containsValue(ob));
}
}