考虑一个带有以下接口的简单对象存储:
// add an object with ‘blob’ content into the system and return an id
int put(string blob);
// retrieve the contents of an object identified by ‘id’. NULL if doesn’t exist
string get(int);
// delete an object identified by ‘id’
void delete(int id);
//number of (non duplicate) objects stored in the object store
int size();
要求
对象库必须重复删除对象。如果相同的字节序列存储两次 - 那么存储不能存储两次数据。对象
可以相当大 - 比如说 - 大小从1K到5MB不等。 Blob是不可变的..
我们正在寻找这些API调用的标准顺序一致性语义。如果某个对象被“放入” - 那么下一个即时“获取”调用 -
应该返回先前放置的值。例如。如果客户端执行以下操作:
Id = objectstore.put(data);
data1 = objectstore.get(id);
第二个操作必须返回与'data'指向的字节序列相同的字节。没有其他客户端/进程/线程应该能够 干扰那个。
到目前为止我的代码:
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class ObjectStore {
String blobString;
Object objectId;
public ObjectStore(String blobString, Object objectId) {
this.blobString = blobString;
this.objectId = objectId;
}
@Override
public boolean equals(Object o){
if(!(o instanceof ObjectStore)){
return false;
}
if((o == null) || (o.getClass() != this.getClass()))
return false;
// object must be Test at this point
ObjectStore store = (ObjectStore)o;
return blobString.toString() == store.blobString &&
(objectId != null && objectId.equals(store.objectId));
}
@Override
public int hashCode() {
int hash = 7;
hash = 31 * hash + blobString.hashCode();
hash = 31 * hash + ((objectId == null) ? 0 : objectId.hashCode());
return hash;
}
Set<String> set = new HashSet<String>();
/**
* Put object into store and return id.
* @param blobString
* @return
*/
public int put(String blobString) {
set.add(blobString);
return 0;
}
/**
* Get object corresponding to id. Return null if no such object exists.
* @param objectId
* @return
*/
public String get(int objectId) {
return null;
}
/**
* Release object - don't need it anymore.
* @param objectId
*/
public void delete(int objectId) {
// stub
}
/**
* Number of distinct blobs stored in the objectStore
* @return
*/
public int size() {
// stub
return 0;
}
public static void main(String[] args) {
Map<String, Object> map = new HashMap<String, Object>();
}
}
我无法确定我需要使用Map或Set接口,因为put()方法返回对象id。
答案 0 :(得分:0)
在将对象映射到整数ID时使用Map
。集合不一定映射数据,它们只是没有重复元素的集合。
但是,由于您似乎在编写接口,因此实现的内部结构无关紧要。使用最有效的方法,并使用接口要求。
编辑2:
如果我实现这个,我会使用整数来生成put
操作的唯一ID。这将提供最多约40亿put
次操作的独特ID。
还需要第二张地图来检查之前是否添加了一些blob序列。这样您就可以使用与第一次相同的密钥替换旧blob。
int idProvider=0;
HashMap<Integer, String> map1 = new HashMap<Integer, String>();
HashMap<String, Integer> map2 = new HashMap<String, Integer>();
public int put(String blob){
int id = -1;
if(map2.containsKey(blob)){
id = map2.get(blob);
}else{
id = idProvider;
idProvider+=1;
map2.put(blob, id);
}
map1.put(id, blob);
return id;
}
public void delete(int id){
String blob = map1.remove(id);
if(blob!=null){
map2.remove(blob);
}
}
String get(int id){
String blob = map1.get(id);
return blob;
}
int size(){
return map1.size();
}
这应该符合您问题中的所有条件,除非线程安全是个问题。如果是这种情况,只需同步访问。我编译并测试了这段代码。
测试:
ObjectStore store = new ObjectStore();
int id1 = store.put("hello");
int id2 = store.put("world");
int id3 = store.put("world");
if(store.size()!=2)
throw new RuntimeException("Wrong size");
if (id2 != id3)
throw new RuntimeException("Ids not equal?");
String strHello = store.get(id1);
String strWorld = store.get(id3);
if (!strHello.equals("hello") || !strWorld.equals("world"))
throw new RuntimeException();
store.delete(id3);
String strShouldBeNull = store.get(id3);
if(strShouldBeNull!=null)
throw new RuntimeException();