diff --git a/src/main/java/org/spdx/storage/simple/InMemSpdxStore.java b/src/main/java/org/spdx/storage/simple/InMemSpdxStore.java
index e3e85edf9..794ee8b0c 100644
--- a/src/main/java/org/spdx/storage/simple/InMemSpdxStore.java
+++ b/src/main/java/org/spdx/storage/simple/InMemSpdxStore.java
@@ -2,7 +2,7 @@
* Copyright (c) 2019 Source Auditor Inc.
*
* SPDX-License-Identifier: Apache-2.0
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -22,7 +22,9 @@
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
@@ -47,21 +49,21 @@
/**
* @author Gary O'Neall
- *
+ *
* In memory implementation of an SPDX store.
- *
+ *
* This implementation primarily uses ConcurrentHashMaps
.
- *
+ *
* It is designed to be thread-safe and low CPU utilization. It may use significant amounts of memory
* for larger SPDX documents.
*
*/
public class InMemSpdxStore implements IModelStore {
-
+
static final Logger logger = LoggerFactory.getLogger(InMemSpdxStore.class.getName());
-
+
static final String GENERATED = "gnrtd";
- public static Pattern LICENSE_ID_PATTERN_GENERATED =
+ public static Pattern LICENSE_ID_PATTERN_GENERATED =
Pattern.compile(SpdxConstants.NON_STD_LICENSE_ID_PRENUM+GENERATED+"(\\d+)$"); // Pattern for generated license IDs
static Pattern DOCUMENT_ID_PATTERN_GENERATED = Pattern.compile(SpdxConstants.EXTERNAL_DOC_REF_PRENUM+GENERATED+"(\\d+)$");
@@ -69,40 +71,40 @@ public class InMemSpdxStore implements IModelStore {
static final String ANON_PREFIX = "__anon__";
static Pattern ANON_ID_PATTERN_GENERATED = Pattern.compile(ANON_PREFIX+GENERATED+"(\\d+)$");
private static final Set LITERAL_VALUE_SET = new HashSet(Arrays.asList(SpdxConstants.LITERAL_VALUES));
-
+
/**
* Map of Document URI to items stored in the document. The key for the items map is the lowercase of the item ID.
*/
- protected ConcurrentHashMap> documentValues = new ConcurrentHashMap<>();
+ protected Map> documentValues = Collections.synchronizedMap(new LinkedHashMap<>());
private int nextNextLicenseId = 0;
private int nextNextDocumentId = 0;
private int nextNextSpdxId = 0;
private int nextAnonId = 0;
-
+
private final ReadWriteLock transactionLock = new ReentrantReadWriteLock();
private final ReadWriteLock referenceCountLock = new ReentrantReadWriteLock();
-
+
private final IModelStoreLock readLock = new IModelStoreLock() {
@Override
public void unlock() {
transactionLock.readLock().unlock();
}
-
+
};
-
+
private final IModelStoreLock writeLock = new IModelStoreLock() {
@Override
public void unlock() {
transactionLock.writeLock().unlock();
}
-
+
};
-
+
@Override
public boolean exists(String documentUri, String id) {
- ConcurrentHashMap idMap = documentValues.get(documentUri);
+ Map idMap = documentValues.get(documentUri);
if (idMap == null) {
return false;
}
@@ -112,16 +114,16 @@ public boolean exists(String documentUri, String id) {
@Override
public void create(String documentUri, String id, String type) throws InvalidSPDXAnalysisException {
StoredTypedItem value = new StoredTypedItem(documentUri, id, type);
- ConcurrentHashMap idMap = documentValues.get(documentUri);
+ Map idMap = documentValues.get(documentUri);
while (idMap == null) {
- idMap = documentValues.putIfAbsent(documentUri, new ConcurrentHashMap());
+ idMap = documentValues.putIfAbsent(documentUri, Collections.synchronizedMap(new LinkedHashMap()));
}
updateNextIds(id);
if (Objects.nonNull(idMap.putIfAbsent(id.toLowerCase(), value))) {
throw new DuplicateSpdxIdException("ID "+id+" already exists.");
}
}
-
+
/**
* Check to see if the next ID indexes need to be updated based on the name provided
* @param id
@@ -192,7 +194,7 @@ private synchronized void checkUpdateNextLicenseId(Matcher licenseRefMatcher) {
* @throws InvalidSPDXAnalysisException
*/
protected StoredTypedItem getItem(String documentUri, String id) throws InvalidSPDXAnalysisException {
- ConcurrentHashMap idMap = documentValues.get(documentUri);
+ Map idMap = documentValues.get(documentUri);
if (idMap == null) {
throw new SpdxIdNotFoundException("Document URI "+documentUri+" was not found in the memory store. The ID must first be created before getting or setting property values.");
}
@@ -211,78 +213,78 @@ public List getPropertyValueNames(String documentUri, String id) throws
@Override
public void setValue(String documentUri, String id, String propertyName, Object value)
throws InvalidSPDXAnalysisException {
- if (value instanceof TypedValue) {
- referenceCountLock.writeLock().lock();
- try {
- StoredTypedItem itemToBeStored = getItem(documentUri, ((TypedValue)value).getId());
- getItem(documentUri, id).setValue(propertyName, value);
- itemToBeStored.incReferenceCount();
- } finally {
- referenceCountLock.writeLock().unlock();
- }
- } else {
- getItem(documentUri, id).setValue(propertyName, value);
- }
+ if (value instanceof TypedValue) {
+ referenceCountLock.writeLock().lock();
+ try {
+ StoredTypedItem itemToBeStored = getItem(documentUri, ((TypedValue)value).getId());
+ getItem(documentUri, id).setValue(propertyName, value);
+ itemToBeStored.incReferenceCount();
+ } finally {
+ referenceCountLock.writeLock().unlock();
+ }
+ } else {
+ getItem(documentUri, id).setValue(propertyName, value);
+ }
}
@Override
public void clearValueCollection(String documentUri, String id, String propertyName)
throws InvalidSPDXAnalysisException {
- referenceCountLock.writeLock().lock();
- try {
- List removedItems = new ArrayList<>();
- Iterator