5151import java .util .Collections ;
5252import java .util .Comparator ;
5353import java .util .HashMap ;
54- import java .util .HashSet ;
5554import java .util .Iterator ;
5655import java .util .List ;
5756import java .util .Map ;
@@ -70,6 +69,10 @@ public class TagManager {
7069 private static final String PREVIOUS_CONDITION =
7170 "before deleting it, tag key is %s, tag value is %s, tlog offset is %d, contains key %b" ;
7271
72+ // The tag index memory model adds one int-sized estimated overhead for each indexed key, value,
73+ // and measurement reference. This is an accounting estimate rather than a specific
74+ // ConcurrentHashMap or Set field.
75+ private static final long INDEX_ENTRY_OVERHEAD_ESTIMATE_BYTES = Integer .BYTES ;
7376 private static final Logger logger = LoggerFactory .getLogger (TagManager .class );
7477 private static final CommonConfig COMMON_CONFIG = CommonDescriptor .getInstance ().getConfig ();
7578
@@ -164,34 +167,31 @@ public void addIndex(String tagKey, String tagValue, IMeasurementMNode<?> measur
164167 return ;
165168 }
166169
167- int tagIndexOldSize = tagIndex .size ();
168- Map <String , Set <IMeasurementMNode <?>>> tagValueMap =
169- tagIndex .computeIfAbsent (tagKey , k -> new ConcurrentHashMap <>());
170- int tagIndexNewSize = tagIndex .size ();
171-
172- int tagValueMapOldSize = tagValueMap .size ();
173- Set <IMeasurementMNode <?>> measurementsSet =
174- tagValueMap .computeIfAbsent (tagValue , v -> Collections .synchronizedSet (new HashSet <>()));
175- int tagValueMapNewSize = tagValueMap .size ();
170+ tagIndex .compute (
171+ tagKey ,
172+ (key , tagValueMap ) -> {
173+ long memorySize = 0 ;
174+ if (tagValueMap == null ) {
175+ tagValueMap = new ConcurrentHashMap <>();
176+ memorySize += RamUsageEstimator .sizeOf (tagKey ) + INDEX_ENTRY_OVERHEAD_ESTIMATE_BYTES ;
177+ }
176178
177- int measurementsSetOldSize = measurementsSet .size ();
178- measurementsSet .add (measurementMNode );
179- int measurementsSetNewSize = measurementsSet .size ();
179+ Set <IMeasurementMNode <?>> measurementsSet = tagValueMap .get (tagValue );
180+ if (measurementsSet == null ) {
181+ measurementsSet = ConcurrentHashMap .newKeySet ();
182+ tagValueMap .put (tagValue , measurementsSet );
183+ memorySize += RamUsageEstimator .sizeOf (tagValue ) + INDEX_ENTRY_OVERHEAD_ESTIMATE_BYTES ;
184+ }
180185
181- long memorySize = 0 ;
182- if (tagIndexNewSize - tagIndexOldSize == 1 ) {
183- // the last 4 is the memory occupied by the size of tagvaluemap
184- memorySize += RamUsageEstimator .sizeOf (tagKey ) + 4 ;
185- }
186- if (tagValueMapNewSize - tagValueMapOldSize == 1 ) {
187- // the last 4 is the memory occupied by the size of measurementsSet
188- memorySize += RamUsageEstimator .sizeOf (tagValue ) + 4 ;
189- }
190- if (measurementsSetNewSize - measurementsSetOldSize == 1 ) {
191- // 8 is the memory occupied by the length of the IMeasurementMNode
192- memorySize += RamUsageEstimator .NUM_BYTES_OBJECT_REF + 4 ;
193- }
194- requestMemory (memorySize );
186+ if (measurementsSet .add (measurementMNode )) {
187+ memorySize +=
188+ RamUsageEstimator .NUM_BYTES_OBJECT_REF + INDEX_ENTRY_OVERHEAD_ESTIMATE_BYTES ;
189+ }
190+ if (memorySize > 0 ) {
191+ requestMemory (memorySize );
192+ }
193+ return tagValueMap ;
194+ });
195195 }
196196
197197 public void addIndex (Map <String , String > tagsMap , IMeasurementMNode <?> measurementMNode ) {
@@ -206,32 +206,47 @@ public void removeIndex(String tagKey, String tagValue, IMeasurementMNode<?> mea
206206 if (tagKey == null || tagValue == null || measurementMNode == null ) {
207207 return ;
208208 }
209- // init memory size
210- long memorySize = 0 ;
211- if (tagIndex .get (tagKey ).get (tagValue ).remove (measurementMNode )) {
212- memorySize += RamUsageEstimator .NUM_BYTES_OBJECT_REF + 4 ;
213- }
214- if (tagIndex .get (tagKey ).get (tagValue ).isEmpty ()) {
215- if (tagIndex .get (tagKey ).remove (tagValue ) != null ) {
216- // the last 4 is the memory occupied by the size of IMeasurementMNodeSet
217- memorySize += RamUsageEstimator .sizeOf (tagValue ) + 4 ;
218- }
219- }
220- if (tagIndex .get (tagKey ).isEmpty ()) {
221- if (tagIndex .remove (tagKey ) != null ) {
222- // the last 4 is the memory occupied by the size of tagValueMap
223- memorySize += RamUsageEstimator .sizeOf (tagKey ) + 4 ;
224- }
225- }
226- releaseMemory (memorySize );
209+ tagIndex .computeIfPresent (
210+ tagKey ,
211+ (key , tagValueMap ) -> {
212+ long memorySize = 0 ;
213+ Set <IMeasurementMNode <?>> measurementsSet = tagValueMap .get (tagValue );
214+ if (measurementsSet == null ) {
215+ return tagValueMap ;
216+ }
217+
218+ if (measurementsSet .remove (measurementMNode )) {
219+ memorySize +=
220+ RamUsageEstimator .NUM_BYTES_OBJECT_REF + INDEX_ENTRY_OVERHEAD_ESTIMATE_BYTES ;
221+ }
222+ if (measurementsSet .isEmpty ()) {
223+ if (tagValueMap .remove (tagValue , measurementsSet )) {
224+ memorySize +=
225+ RamUsageEstimator .sizeOf (tagValue ) + INDEX_ENTRY_OVERHEAD_ESTIMATE_BYTES ;
226+ }
227+ }
228+ if (tagValueMap .isEmpty ()) {
229+ memorySize += RamUsageEstimator .sizeOf (tagKey ) + INDEX_ENTRY_OVERHEAD_ESTIMATE_BYTES ;
230+ if (memorySize > 0 ) {
231+ releaseMemory (memorySize );
232+ }
233+ return null ;
234+ }
235+ if (memorySize > 0 ) {
236+ releaseMemory (memorySize );
237+ }
238+ return tagValueMap ;
239+ });
240+ }
241+
242+ private boolean containsIndex (String tagKey , String tagValue ) {
243+ Map <String , Set <IMeasurementMNode <?>>> tagValueMap = tagIndex .get (tagKey );
244+ return tagValueMap != null && tagValueMap .containsKey (tagValue );
227245 }
228246
229247 private List <IMeasurementMNode <?>> getMatchedTimeseriesInIndex (TagFilter tagFilter ) {
230- if (!tagIndex .containsKey (tagFilter .getKey ())) {
231- return Collections .emptyList ();
232- }
233248 Map <String , Set <IMeasurementMNode <?>>> value2Node = tagIndex .get (tagFilter .getKey ());
234- if (value2Node .isEmpty ()) {
249+ if (value2Node == null || value2Node .isEmpty ()) {
235250 return Collections .emptyList ();
236251 }
237252
@@ -362,8 +377,7 @@ public void removeFromTagInvertedIndex(IMeasurementMNode<?> node) throws IOExcep
362377 Map <String , String > tagMap = tagLogFile .readTag (node .getOffset ());
363378 if (tagMap != null ) {
364379 for (Map .Entry <String , String > entry : tagMap .entrySet ()) {
365- if (tagIndex .containsKey (entry .getKey ())
366- && tagIndex .get (entry .getKey ()).containsKey (entry .getValue ())) {
380+ if (containsIndex (entry .getKey (), entry .getValue ())) {
367381 if (logger .isDebugEnabled ()) {
368382 logger .debug (
369383 String .format (
@@ -415,7 +429,7 @@ public void updateTagsAndAttributes(
415429 // we should remove before key-value from inverted index map
416430 if (beforeValue != null && !beforeValue .equals (value )) {
417431
418- if (tagIndex . containsKey (key ) && tagIndex . get ( key ). containsKey ( beforeValue )) {
432+ if (containsIndex (key , beforeValue )) {
419433 if (logger .isDebugEnabled ()) {
420434 logger .debug (
421435 String .format (
@@ -548,8 +562,7 @@ public void dropTagsOrAttributes(
548562
549563 if (!deleteTag .isEmpty ()) {
550564 for (Map .Entry <String , String > entry : deleteTag .entrySet ()) {
551- if (tagIndex .containsKey ((entry .getKey ()))
552- && tagIndex .get (entry .getKey ()).containsKey (entry .getValue ())) {
565+ if (containsIndex (entry .getKey (), entry .getValue ())) {
553566 if (logger .isDebugEnabled ()) {
554567 logger .debug (
555568 String .format (
@@ -618,7 +631,7 @@ public void setTagsOrAttributesValue(
618631 String beforeValue = entry .getValue ();
619632 String currentValue = newTagValue .get (key );
620633 // change the tag inverted index map
621- if (tagIndex . containsKey (key ) && tagIndex . get ( key ). containsKey ( beforeValue )) {
634+ if (containsIndex (key , beforeValue )) {
622635
623636 if (logger .isDebugEnabled ()) {
624637 logger .debug (
@@ -676,7 +689,7 @@ public void renameTagOrAttributeKey(
676689 // persist the change to disk
677690 tagLogFile .write (pair .left , pair .right , leafMNode .getOffset ());
678691 // change the tag inverted index map
679- if (tagIndex . containsKey (oldKey ) && tagIndex . get ( oldKey ). containsKey ( value )) {
692+ if (containsIndex (oldKey , value )) {
680693
681694 if (logger .isDebugEnabled ()) {
682695 logger .debug (
0 commit comments