Active Ming Qin – ActiveMQ

Computing for embedded devices, tablets and computers

ArmerTac Model FS-T709 LED Motion-Activated Nite Lite which is triangle Shape and emitting pure white light ( not yellowish at all).

20160818_19363820160818_19355120160818_193646

 

Java 8 Stream Pitfall- Not Step Twice into the Same Stream

“You could not step twice into the same water”-Heraclitus of Ephesus

  A Stream does not store its elements.

I got caught by Stream’s not storing its elements.  My code created a Stream object  for type String. After evaluation of the emptiness of Stream object, that object is  “vanished” which throws exception as “stream has already been operated  upon or closed” if that Stream object is referenced again.

public static void main ( String[] args) throws Throwable {
   String input="usa_ca-culvercity";
   //words object is created.
   Stream<String> words = Stream.of(input.trim().split("[_-]")).skip(1);
   // words object is referenced  first time.
   if ( words.count()==0)  { throw new Exception(" input formatting is wrong  "+ input); }
   else{
   // words object could not be referenced anymore.
   // code throws exception
   //in thread "main" java.lang.IllegalStateException: <strong>stream has already been operated upon or closed</strong>
      System.out.println ( (String)  words.toArray()[0]);
   }
 } 

Lambda Expression-Using Function as first-class Member of Java to Detect Recurrence Value inside An Array

I find the best words to explain of Lambda from Oracle Lambda Quick Star web page. Here it is “Lambda expressions provide a clear and concise way to represent one method interface using an expression. Lambda expressions also improve the Collection libraries making it easier to iterate through, filter, and extract data from a Collection. In addition, new concurrency features improve performance in multicore environments.”

This blog is about my coding practice on using Lambda Express  to find recurrence value in an array of integer.

The problem is to figure out the number of recurrence value in an array of integer, which is bigger or equal to the half of length of that array.

Below code snippet shows a solution without utilizing Lambda Expression. The code sorts the array in ascending order, then compare the equality of next two elements in the array to the last element in there. There are two basic operations in this solution- measure equality of two integers and looping through the array.

import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.function.BiPredicate;

/**
 *
 * @author MingQin
 */
public class RecurrenceIntValueInArray {

    public static void main(String[] args) throws IOException {
        Integer[] ia = new Integer[]{1, 1, 6, 6, 8, 5, 7, 6, 6, 6};

        Arrays.sort(ia);
        System.out.println(" inputArray size : " + ia.length);
        int benchMark = ia.length / 2;
        int recurrenceCount = 1;
        
        for (int i = 0; i < ia.length - 1; i++) {             
                   if (ia[i].equals(ia[i+1])) {               
                         recurrenceCount++;                
                         if (recurrenceCount >= benchMark) {
                    break;
                }
            } else {
                recurrenceCount = 1;
          // replacing above line to return-1, the ia array will be stored
          // in descending order

            }

        }//end for 
        if (recurrenceCount >= benchMark) {
            System.out.println(" Yes :  " + (recurrenceCount));
        } else {
            System.out.println(" No");
        }

    }//end main

}


I want to use Lambda Expression to replace those two operations. First starting point is working on operation of the equality of two integers.

Since a lambda expression can be a substitute of Function Interface, if a Function Interface provides abstract method to take two type parameters as inputs and return another type, then they are pretty good to be considered. Comparator and BiPredicate function interface are merged.

import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.function.BiPredicate;

/**
 *
 * @author MingQin
 */
public class RecurrenceIntValueInArray {

    public static void main(String[] args) throws IOException {
        Integer[] ia = new Integer[]{1, 1, 6, 6, 8, 5, 7, 6, 6, 6};

        Arrays.sort(ia);
        System.out.println(" inputArray size : " + ia.length);
        int benchMark = ia.length / 2;
        int recurrenceCount = 1;
         //Comparator Lambda Expression
        recurrenceCount = 1;
        Comparator<Integer> comp = 
        (first, second) -> Integer.compare(first.intValue(),second.intValue());
        for (int i = 0; i < ia.length - 1; i++) {             
               int result = comp.compare(ia[i], ia[i + 1]);            
               recurrenceCount = (result == 0) ? recurrenceCount + 1 : 1;           
               if (recurrenceCount >= benchMark) {
                break;
            }

        }//end for 

        if (recurrenceCount >= benchMark) {
            System.out.println(" Yes :  " + (recurrenceCount));
        } else {
            System.out.println(" No");
        }

        //BiPrdicate Lambda Expression
        recurrenceCount = 1;
        BiPredicate<Integer, Integer> biPredicate = (x, y) -> x.equals(y);
        for (int i = 0; i < ia.length - 1; i++) {           
                 boolean result = biPredicate.test(ia[i], ia[i + 1]);            
                 recurrenceCount = (result) ? recurrenceCount + 1 : 1;           
                 if (recurrenceCount >= benchMark) {
                break;
            }

        }//end for 
        if (recurrenceCount >= benchMark) {
            System.out.println(" Yes :  " + (recurrenceCount));
        } else {
            System.out.println(" No");
        }
        

    }//end main

}

Now, I come to the last task replacing for loop with Lambda Express. The approach is using a Lambda Expression as an instance of Comparator Function Interface in Arrays.sort( T[] a , Comparator<? Super T> c).

import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.function.BiPredicate;

/**
 *
 * @author Ming Qin
 */
public class RecurrenceIntValueInArrayLambda {

    public static void main(String[] args) throws IOException {
        Integer[] ia = new Integer[]{1, 1, 6, 6, 8, 5, 7, 6, 6, 6};

        Arrays.sort(ia);
        System.out.println(" inputArray size : " + ia.length);
        int benchMark = ia.length / 2;
        
        final int[] count = new int[1];
        count[0] = 1;
        BiPredicate<Integer, Integer> biPredicate = (x, y) -> x.equals(y);
    
        Arrays.sort(ia, (tail, head) -> {
            boolean result = biPredicate.test(head, tail);
            if (result) {
                count[0]++;
            } else {
                count[0] = 1;
            }
            System.out.println(" ++++++++++  :" + count[0] + " head : " + head
                    + "  tail:" + tail);
            if (count[0] >= benchMark) {
                System.out.println(" Yes :  " + count[0]);       
            }
            return count[0];
        });
    }//end main
}

Coming back the statement of Lambda Expression  definition-
Lambda expressions also improve the Collection libraries making it easier to iterate through, filter,
and extract data from a Collection

Ha, Is above statement meaning that I could utilize Stream API and filter method for another solution?

What a journey.


import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.Optional;
import java.util.stream.Collectors;
/**
 *
 * @author mqin
 */
public class RecurrenceIntValueInArrayLambda {

    public static void main(String[] args) throws IOException {
        Integer[] ia = new Integer[]{1, 1, 6, 6, 8, 5, 7, 6, 6, 6};
        List<Integer> ilist = Arrays.asList(ia);

        Optional<Integer> result0= ilist.stream().filter(
                    x->ilist.stream().filter (
                         y->y.equals(x)
                       ).count()>=ia.length/2
                   ).findFirst();
        if ( result0.isPresent()) System.out.println ( "Yes, it is " + result.get());


// another stream solution.        
         
        Set<Integer> result = ilist.stream().filter(x -> ilist.stream().filter(
                y -> y.equals(x)).count() >= ia.length / 2
        ).collect(Collectors.toSet());
        
        if (!result.isEmpty()) System.out.println ( "Yes");

    }//end main

}


Apache Avro IDL Composes Avro Schema by AvroHubTools

                        Simple is better than complex

Nowadays, data storage cost is cheap ( almost free),  but data bandwidth is costly( thinking about monthly fees paid towards smart phone data transfer and house internet access). As more and more things ( watch, refrigerator , car, etc) are connected to each other through internet,  the online traffic could be notorious analogy to freeway 405 in Great Los Angeles.   Apache Avro can be helpful on this situation with its compact binary data representation since avro data size is much less verbose than  text-based XML or JSON.

In another blog, I mentioned the usage of Apache Avro schema to model data as replacement of XML and JSON. After that, I developed AvroHubTools to author Avro schema by Apache Avro IDL. In this blog, I will try to demonstrate employing Avro IDL to generate Avro schema in conjunction with AvroHubTools, in below topics:

  •   How to encapsulate Avro schemas and build standalone scheme out of multiple, external and independent  Avro schema files.
  •   How to reuse Avro schemas through inheritance.
  •   How to apply polymorphism in data modeling by Avro schemas.

AvroHubTools ( obf-avro-hub-tools-1.0-SNAPSHOT.jar) can be downloaded from this link and has been tested with JDK 1.6.45 and Apache Avro 1.7.7 release.  AvroHubTools can support other Apache Avro versions, please make request by leaving comments on this blog.

Encapsulating ( data hiding)  with Apache Avro Schemas

Encapsulation in here means the packing of date into a single Avro Schema. Let’s assume ones like to model data in Avro scheme about baseball team.  We get player, play position, coach as components , as well as name since player and coach reference name component.  A play can be assigned to multiple coaches.   baseball.avdl Avro IDL to pack four Avro schema files in order to generate Team.avsc

baseball.avdl is defined as below.

@namespace("avro.examples.baseball")
protocol Baseball {
   import schema "name.avsc";
   import schema "coache.avsc";
   import schema "position.avsc";
   import schema "player.avsc";
  
   record Team {
      
       Player player;
       Coache  coache;
         
  }
}

Below are team Avro schema components: name.avsc, position.avsc, coache.avsc and play.avsc

name.avsc

{"type":"record", "name":"Name", "namespace": "avro.examples.baseball",
  "fields": [
   {"name": "first_name", "type": "string"},
   {"name": "last_name", "type": "string"}
  ]
}

position.avsc

{"type":"enum", "name": "Position", "namespace": "avro.examples.baseball",
    "symbols": ["P", "C", "B1", "B2", "B3", "SS", "LF", "CF", "RF", "DH"]
}

coache.avsc

{"type":"record", "name":"Coache", "namespace": "avro.examples.baseball",
  "fields": [
   {"name": "name", "type": "Name"}
 
  ]
}

play.avsc

<pre>{"type":"record", "name":"Player", "namespace": "avro.examples.baseball",
  "fields": [
   {"name": "number", "type": "int"},
   {"name": "name", "type": "Name"},
   {"name": "positions", "type": {"type": "array", "items": "Position"} },
   {"name": "coaches", "type": {"type": "array", "items": "Coache"} }
  ]
}

To generate Team.avsc, run below line by utilizing AvroHubTools.
java -jar obf-avro-hub-tools-1.0-SNAPSHOT.jar   idlavsc   baseball.avdl avro.examples.baseball.Team   baseballTeam.avsc

Here is generated baseballTeam.avse

{
  "type" : "record",
  "name" : "Team",
  "namespace" : "avro.examples.baseball",
  "fields" : [ {
    "name" : "player",
    "type" : {
      "type" : "record",
      "name" : "Player",
      "fields" : [ {
        "name" : "number",
        "type" : "int"
      }, {
        "name" : "name",
        "type" : {
          "type" : "record",
          "name" : "Name",
          "fields" : [ {
            "name" : "first_name",
            "type" : "string"
          }, {
            "name" : "last_name",
            "type" : "string"
          } ]
        }
      }, {
        "name" : "positions",
        "type" : {
          "type" : "array",
          "items" : {
            "type" : "enum",
            "name" : "Position",
            "symbols" : [ "P", "C", "B1", "B2", "B3", "SS", "LF", "CF", "RF", "DH" ]
          }
        }
      }, {
        "name" : "coaches",
        "type" : {
          "type" : "array",
          "items" : {
            "type" : "record",
            "name" : "Coache",
            "fields" : [ {
              "name" : "name",
              "type" : "Name"
            } ]
          }
        }
      } ]
    }
  }, {
    "name" : "coache",
    "type" : "Coache"
  } ]
}

To Be Continued……..

Apache Avro Object Container File Format Examination-Header

Understating is more important than technique

First to me,  apache avro is a file storage mechanism can be used for NOSQL data storage as well as an alternative binary data representation in replacement of text XML or JSON (  avro schema and idl-avsc,avdl VS xsd, avro object container file VS xml) for enterprise computing, mobile device, embedded linux motherboard or  SOA data inter-exchange .

After reading the apache avro Spec of Object Container File, I decided to generate an avro object container file ( Header and Blocks) to understand its binary content layout. Below picture depicts the overall avro object container file  binary structure.  I  drill down the only header portion of it.

avro object container file format

Apache Avro -1.8.0-SNAPSHOT source codes ware loaded into Netbean 8.o on CentOS-6.4 hosted by VMWare Workstation 11 running on window 8.1

My avro schema named as legopiece.avsc which was defined as below snippet .

   {
    "namespace":"com.example.avroSample.model",
    "type":"record",
    "name":"LegoPiece",
    "fields":[
        {
            "name":"modelName",
            "type":"string"
        },
        {
            "name":"modelYear",
            "type":"int"
        },
        {
            "name":"stubNumber",
            "type":"string"
        }   
    ]   
}

Below codes are used to generate an avro object container file- legopieoce.avro which describes a  lego brick has two stubs, model year is 2147483647( java max int positive number), model name is Brick 1×2 Green (15-character length text).

green brick two stubs

......
       private static final File outputFile = new File("target/avro/legopiece.avro");
       LegoPiece legoPiece = LegoPiece.newBuilder()
                .setModelName("Brick 1X2 Green").setModelYear(2147483647)
                .setStubNumber("2").build();
                               
        DatumWriter<LegoPiece> datumWriter = new SpecificDatumWriter<LegoPiece>(
                LegoPiece.class);
        DataFileWriter<LegoPiece> fileWriter = new DataFileWriter<LegoPiece>(
                datumWriter);
        try {
            // creating legopieice.avro -object container file for containing
            // binary format of legoPiece object
            fileWriter.create(legoPiece.getSchema(), outputFile);
            fileWriter.append(legoPiece);
            fileWriter.close();
        } catch (IOException e) {
            LOGGER.error("Error while trying to write the object to file <"
                    + outputFile.getAbsolutePath() + ">.", e);
        }
....

Here is the picture of legopiece.avro displayed in Hex Editor Neo( window version).

CaptureAvroLegoPiece

It is the time to turn on the java debugger and go through codes in maven sub model named as “Apache Avro”  to figure out how those bytes  were written to legopiece.avro  .

DataFileWriter

A few breakpoints were set up inside DataFileWriter.java‘s method DataFileWriter<D> create(Schema, OutputStream outs).  This method made bytes representing following items of object container file header:

  • Four bytes,  ‘O’, ‘b’, ‘j’ , followed by  ‘1’  – referencing legopiece.avro’s Hex layout picture, we could find  the corresponding first four bytes as UTF-8 codes of  4f , 62, 6a , 01. Here is UTF-8 codepage layout to  help understanding UTF-8 code’s matching characters.
  • File metadata, including the schema and their values’ lengths being measured in int values using firstly  zig-zag,  secondly  variable-length coding

    public static int encodeInt(int n, byte[] buf, int pos) {
    // move sign to low-order bit, and flip others if negative
    n = (n << 1) ^ (n >> 31);
    int start = pos;
    if ((n & ~0x7F) != 0) {
     buf[pos++] = (byte)((n | 0x80) & 0xFF);
     n >>>= 7;
      if (n > 0x7F) {
        buf[pos++] = (byte)((n | 0x80) & 0xFF);
        n >>>= 7;
        if (n > 0x7F) {
          buf[pos++] = (byte)((n | 0x80) & 0xFF);
          n >>>= 7;
          if (n > 0x7F) {
          buf[pos++] = (byte)((n | 0x80) & 0xFF);
          n >>>= 7;
         }
        }
      }
    }
    buf[pos++] = (byte) n;
    return pos - start;
    }
    
  • The 16-type , randomly-generated sync marker for legopiece.avro

AvroLegoPieceHeader

If  someones like to figure out how blocks portion of legopiece.avro are generated. Method of void writeBlockTo(BinaryEncoder e, byte[] sync) throws IOException  inside DataFilesStream.java is worth exploring.

Next Post: Apache Avro IDL Compose Avro Schema By AvroHubTool

RESOURCES:

What is Apache Avro?

Apache Avro’s starter Doug Cutting had a video on this blog could tell the purpose of Avro. For the impatient,  to start listening at 8 minutes of the video.

Java 8 Stream API measured By JMH-Java Microbenchmark Harness

From my studying on the new features of Java 8, such as declarative style programming , functional programming,   default method and  lambda expression,   I would say those new features are all designed  for centrally supporting parallelism Stream API.   To master Java 8,  ones must get good understanding about Stream API.

Java 8 claimed that Stream API would employ multi-core CPUs  to process data in parallel fashion which would eliminate difficulties  of  dealing with multi-thread  codes , as well as gaining performance advantages obtained from  multicored CPUs.

As we all knew  that Stream API would cause some overhead associated with java thread pool and Fork-Join programming paradigm.  Developers need a handy tool to scrutinize and rationalize the adopting Stream API on daily coding task, in order to validate whether performance enhancement is obtained .  JMH seems a handy one for this purpose.  Watching this video for the insight of JMH.

I created   a JMH( version 1.3.3)  maven project with  a class JMHSample_01_HelloWorld to measure the throughputs of getting sum of integer addition in four fashions: foo loop, iteration , Stream parallel and Stream sequential.  From the outputs generated by running this command from Window console

java -jar target/benchmarks.jar JMHSample_01 -wi 5 -t 1 -i 5 -f 1

Stream parallel one is the slowest one among four approaches of summing  integers in array.

Benchmark                 Mode  Samples   Score       Error  Units
parallelSumIntegers    thrpt        5         26.902 ▒ 3.997  ops/s

Attached with screenshot of all four JMH measured results.

jmh_result

My machine is installed with Window 8.1 64 bit operating System ;processor is Intel(R) Core(TM) i7-4500U CPU having 4 cores ; RAM is 16 GB; JDK : Oracle 1.8u25-windows-x64.

Below section lists codes to generate above results.

package org.sample;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

@State(Scope.Benchmark)
public class JMHSample_01_HelloWorld {
   volatile int counts = 9999999;
   volatile List<Integer> values = new ArrayList<>(counts);
   volatile int processors = Runtime.getRuntime().availableProcessors();

@Setup
public void setup() {
    populate(values);
}

public  void populate ( List<Integer>  list){
  for ( int i=0; i<counts ; i++){
       if ( i < counts/2){
         list.add(i, i );
       }else {
         list.add (i, i-counts);
      }
   }

}

@Benchmark
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
public int iteratorSumIntegers(){
   int result =0;
   Iterator ite = values.iterator();
   while ( ite.hasNext()){
     result += (int)ite.next();
    }

   return result;
}

@Benchmark
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
public int fooEachSumIntegers(){
   int result =0;
   for (Integer value :values) {
       result += value.intValue();
    }
    return result;
}

@Benchmark
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
public int parallelSumIntegers( ){
   int result = values.parallelStream()
       .mapToInt(i->i)
       .sum();

       return result;

}

@Benchmark
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
public int sequentialSumIntegers( ){
    int result = values.stream()
         .mapToInt(i->i)
         .sum();

        return result;

}

public static void main(String[] args) throws RunnerException {

  Options opt = new OptionsBuilder()
          .include(JMHSample_01_HelloWorld.class.getSimpleName())
          .forks(1)
          .build();

          new Runner(opt).run();
}

}

AngularJS scope API ($watch) and directives to implement Cascading Dropdown

Cascading drop-downs  are a hierarchical   ( parent-children ) relationship exists among multiple html drop-down components. When I try to implement cascading dropdown with AngularJS,  it is intuitive to me to depict that  the data representation of model is dynamically changed by events of selections( clickings). This impression leads me to give the first attempt of implementation with AngularJS scope ($watch) API, since ($watch) API is utilized by scope to observe model mutations.

Below codes illustrate scope watch API implementation on three-tier dropdowns. Top one is countries dropdown, middle one is states dropdown, and last one is cities dropdown.

<html>
    <head>
        <meta charset="UTF-8">
        <title>Cascading Dropdowns by Scope Watch</title>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular.min.js"></script>
    </head>
    <body ng-app="cascadingDropListApp">

        <div  ng-controller="CountryController" >
            <div>
                Country:
                <select id="country" ng-model="country" ng-options="country for country in countries">
                    <option value=''>Select</option>
                </select>
            </div>
            <div>
                City:
                <select id="state" ng-disabled="!states" ng-model="state" ng-options="state for state in states">
                    <option value=''>Select</option>
                </select>
            </div>
            <div>
                Suburb:
                <select id="city" ng-disabled="!cities" ng-model="city" ng-options="city for city in cities">
                    <option value=''>Select</option>
                </select>

            </div>

        </div>
            <script>
                        angular.module('cascadingDropListApp', [])
                                .controller('CountryController', ['$scope', function ($scope) {
                                        $scope.countries = ['china', 'united states'];
                                        $scope.$watch('country', function (newVal) {
                                            if (newVal ==='china')
                                                $scope.states = ['BeiJing', 'ShangHai'];
                                            if (newVal ==='united states')
                                                $scope.states = ['California', 'Mississippi'];
                                        });
                                        $scope.$watch('state', function (newVal) {
                                            if (newVal=== 'ShangHai')
                                                $scope.cities = ['JiaDing', 'HongQian', 'PuDong'];
                                            if (newVal=== 'BeiJing')
                                                $scope.cities = ['HaiDian', 'TianAnMen'];
                                            if (newVal=== 'California')
                                                $scope.cities = ['Los Angeles', 'Santa Barbara'];
                                            if (newVal=== 'Mississippi')
                                                $scope.cities = ['Jackson', 'Oxford'];
                                        });

                                    }]);

            </script>
    </body>
</html>

There is another pure directives implementation without involving scope watch API, it is shown in below.


<html>
<head>
<meta charset="UTF-8">
<title>Cascading Dropdowns </title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular.min.js"></script>
</head>
<body ng-app="cascadingDropListApp">

<div  ng-controller="CountryController" >
<div>
Country:
<select id="country" ng-model="states" ng-options="country for (country, states) in countries">
<option value=''>Select</option>
</select>
</div>
<div>
States: <select id="state" ng-disabled="!states" ng-model="cities" ng-options="state for (state,cities) in states"><option value=''>Select</option></select>
</div>
<div>
City: <select id="city" ng-disabled="!cities || !states" ng-model="city" ng-options="city for city in cities"><option value=''>Select</option></select>
</div>
</div>

<script>
angular.module('cascadingDropListApp', [])
.controller ('CountryController', ['$scope', function($scope) {
$scope.countries = {
'China': {
'BeiJing': ['HaiDian', 'TianAnMen' ],
'ShangHai': ['JiaDing', 'HongQiao','PuDong']

},
'USA': {
'California': ['Los Angeles', 'Santa Barbara'],
'Mississippi': ['Jackson', 'Oxford']
}
};
}]);
</script>
</body>
</html>

Angular Scope events propagation and scope hierarchies are most valuable features
to pay a great attentions.

Object Oriented JavaScript( OOJS) Function Constructor to Demonstrate JavaScript Variable Lexical Scope

Javascript adopts Lexical Scope for variables’ defining and looking up.  The Lexical Scope means the variables are not determined  dynamically at runtime, rather they are defined and resolved as code blocks being written, top-down in place.

Let us take a look below codes which shows JavaScript Engine ( Java 8 Nashorn ) implementation of Lexical Scope on variables ( mirroring_a  and mirrored_a).


function foo( parameterA ) {
   //private member, viriable declaration
   var mirroring_a;
   //private member, variable declaration and assignment
   var mirrored={
       mirrored_a : mirroring_a  // undefined.  due to lexical scope, mirrored_a
                                 // failed to find variable mirroring_a
   };
   
   //public methods
   this.getMirroring_A = function () {
       return mirroring_a;
   };
   
   this.setMirroring_A = function ( newA ) {
       mirroring_a= newA;
   };
   
   this.getMirrored = function () {
       return mirrored;
   };
   // constructor code ,  assign parameter to variable mirroring_a
   this.setMirroring_A( parameterA);
   
   
 }
 
 var objFoo = new foo (  10);
 
for (var prop in  objFoo.getMirrored()) {
    if (prop === 'mirrored_a') {
        print(prop + '=  ' + objFoo.getMirrored()[prop]);
    }
   
}
 

objFoo.getMirrored()['mirrored-a']=777;

print (  objFoo.getMirrored()['mirrored-a'] );

print ( objFoo.getMirroring_A());

Result of running above snippet codes:
mirrored_a=  undefined
777
10
BUILD SUCCESSFUL (total time: 0 seconds)

 

Let me move the block code after constructor codes  – this.setMirroring_A( parameterA).


function foo( parameterA ) {
   //private member, variable declaration
   var mirroring_a;
   
   
   //public methods
   this.getMirroring_A = function () {
       return mirroring_a;
   };
   
   this.setMirroring_A = function ( newA ) {
       mirroring_a= newA;
   };
   
   this.getMirrored = function () {
       return mirrored;
   };
   // constructor code ,  assign parameter to variable mirroring_a
   this.setMirroring_A( parameterA);
   
   
    //private member, variable declaration and assignment
   var mirrored={
       mirrored_a : mirroring_a  // 10
   };
   
 
   
   
 }
 
 var objFoo = new foo (  10);
 

for (var prop in  objFoo.getMirrored()) {
    if (prop === 'mirrored_a') {
        print(prop + '=  ' + objFoo.getMirrored()[prop]);
    }
   
}
 

objFoo.getMirrored()['mirrored-a']=777;

print (  objFoo.getMirrored()['mirrored-a'] );

print ( objFoo.getMirroring_A());

Here are outputs above codes
mirrored_a=  10
777
10
BUILD SUCCESSFUL (total time: 0 seconds)

Encapsulation in Javascript-Hiding Data of Object by Closure and Mirroring Variables

Since I engaged with AngularJS  to rescue the madness of Jquery, Object-Oriented Programming in  JavaScript( OOJS) is worth time and energy to explore.  One feature of Object Oriented  Software Design is Encapsulation-hiding data and methods that operate on those data. This post shows JavaScript implementation of Encapsulation- hiding Data through closure and mirroring  variables.

What is the closure in JavaScript?

Closure  is a protected variable space created by using nested functions allow to create variables to be accessed only by certain functions and preserved in between those function calls.

Below is an example of demo of closure.

function foo() {
    var a = 2;
    //create a closure who can access and preserve variable a
    function bar() {
        a *= 2;
        return a;
    }
    return bar;
}

var quz= foo();
print(quz());// 4
print(quz ());// 8

First thing first is to install Netbeans 8.0 as IDE for coding and testing Javascript.  I configured my Netbean IDE to use Java 1.8_05 as platform. To run javascript  in Netbeans, one can generate a file with file
extension as .js, then use Netbeans File->Open File… to load it into Netbeans IDE.
To run or debug it, right-clicking panel of loaded file ,then select Run File or Debug file.

 

javascriptRunInNetbeans

One general idiom of encapsulation of object-orient programming is to make all of instance variables private and provide accessor methods where necessary. Let’s use lego brick objects to demonstrate  privacy of instance variables and constrained accessing methods through closure.LegoBrick

My first attempt to implement encapsulation with closure is shown in below snippet, but it is failed. Through public function- getSpecs() ,  instance’s brick_width value can be altered.


function LegoBrick(brick_width, brick_height, brick_depth, brick_color) {

    //private members
    var specs = {
        specs_width: brick_width,
        specs_height: brick_height,
        specs_depth: brick_depth,
        specs_color: brick_color
    };
    // public function
    this.getSpecs = function ( ) {
        return specs;
    };
};

var firstBrick = new LegoBrick(10, 20, 30, 'red');

//'specs' is undefined, it is private
print(firstBrick.specs);

for (var prop in  firstBrick.getSpecs()) {

    if (prop === 'specs_width') {
        print(prop + '=  ' + firstBrick.getSpecs()[prop]);
    }
}
//  specs_width of specs of fiirstBrick is altered- data hiding is failed.
firstBrick.getSpecs()['specs_width'] = 999;

for (var prop in firstBrick.getSpecs()) {

      if (prop === 'specs_width') {
        print(prop + '=  ' + firstBrick.getSpecs()[prop]);
    }
}

//  specs_width of specs of fiirstBrick is altered- data hiding is failed.
firstBrick.getSpecs()['specs_width'] = 999;

for (var prop in firstBrick.getSpecs()) {
    if (prop === 'specs_width') {
        print(prop + '=  ' + firstBrick.getSpecs()[prop]);
    }
}

print(firstBrick.getBrickWidth());

Output in Netbeans for above snippet:

run:
undefined
specs_width=  10
specs_width=  999
BUILD SUCCESSFUL (total time: 0 seconds)

One of solutions to resolve failure of hiding data  is to use mirroring variables which get declared after object’s name and assigned with  same passed-in arguments  as object’s properties being assigned.  In this way, mirroring variables’ values are “immutable”, meanwhile being mirrored object remains to be mutable. See below snippet codes.


function LegoBrick(brick_width, brick_height, brick_depth, brick_color) {
     //private members act as mirrored varible of objet specs's properties
     //such as specs_width, etc.
    var brickWidth=brick_width,
        brickHeight=brick_height,
        brickDepth=brick_depth,
        brickColor=brick_color;
    
     //private members
    var specs = {
        specs_width: brick_width,
        specs_height: brick_height,
        specs_depth: brick_depth,
        specs_color: brick_color
    };
    
   
    // public function as weel as privileged method.
    this.getSpecs = function ( ) {
        return specs;
    };

    this.getBrickWidth = function () {
        return brickWidth;
    };
   

    this.getBrickHeight = function () {
        return brickHeight;
    };
 
    this.getBrickDepth = function ( ) {
        return brickDepth;
    };
    

    this.getBrickColor = function () {
        return brickColor;
    };

 
 
};

var firstBrick = new LegoBrick(10, 20, 30, 'red');

//'specs' is undefined, it is private
print(firstBrick.specs);

//'brickWidth' is undefined, it is private
print(firstBrick.brickWidth);

for (var prop in  firstBrick.getSpecs()) {
    if (prop === 'specs_width') {
        print(prop + '=  ' + firstBrick.getSpecs()[prop]);
    }
}
//  specs_width of specs of fiirstBrick is altered- data hiding is failed.
firstBrick.getSpecs()['specs_width'] = new 999;

for (var prop in firstBrick.getSpecs()) {
    if (prop === 'specs_width') {
        print(prop + '=  ' + firstBrick.getSpecs()[prop]);
    }
}

print(firstBrick.getBrickWidth());

Output in Netbeans for above snippet:

undefined
undefined
specs_width=  10
specs_width=  999
10

ReentrantLock Caused Threads Run Into Infinite Waiting State, but Appeared as Deadlocked

ReentrantLock offers unconditional, polled, timed and interruptible lock acquisition, and lock and unlock operations. A typical idiom of using ReentrantLock is shown as below.

Lock lock = new();
...
lock.lock();
try {
   ......
} finally {
    lock.unlock();
}

The finally clause  seems  to release the Lock, but it isn’t in all cases. The below codes demonstrate try-finally with enentrantLock could cause threads in infinite waiting statue , though it is easily  assumed those threads in blocked state( see my post about thread deadlock).  Java’s built jmc tool is used to identify the real state of each thread. From jmc’s thread JMX thread console,  it indicates that thread-0 and thread-1 are in waiting state due to LocakSupport.park being invoked.  In plain english, Lock isn’t  working properly.

 


package com.jaja.benchmark;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockInfiniteWait {

    private static class LeftRightLock {
        private final Lock lock = new ReentrantLock();
        private int number = 4000;
   
        public void doSomething(int number) {
            for (int i = 0; i < number; i++) {
                char[] tmp = new char[1024 * 1024];
                tmp[1] = 'a';
            }
        }

        public void leftRight(LeftRightLock other) {
            lock.lock();
            try {
                doSomething(number);
                System.out.println(" left right");
                other.rightLeft(this);
            } finally {
                lock.unlock();
            }
        }

        public void rightLeft(LeftRightLock other) {
            lock.lock();
            try {
                doSomething(number);
                System.out.println(" right left");
                other.leftRight(this);
            } finally {
                lock.unlock();   
            }
        }
    }

    public static void main(String[] args) {
        final LeftRightLock first = new LeftRightLock();
        final LeftRightLock second = new LeftRightLock();

        new Thread(new Runnable() {
            public void run() {
                first.rightLeft(second);
            }
        }).start();

        new Thread(new Runnable() {
            public void run() {
                second.leftRight(first);
            }
        }).start();
    }

}

Clicking the image to see enlarged version of below picture

two threads' waiting state

How to fix this issue?  Replace leftRight and rightLeft methods with below 3 snippets separately

 

The 1st one:

 

public void leftRight(LeftRightLock other) {
lock.lock();
try {
doSomething(number);
System.out.println(” left right”);

} finally {
lock.unlock();

other.rightLeft(this);
}
}

public void rightLeft(LeftRightLock other) {
lock.lock();
try {
doSomething(number);
System.out.println(” right left”);

} finally {
lock.unlock();

other.leftRight(this);
}
}

Here is the second one:

public void leftRight(LeftRightLock other) {
other.lock.lock();
lock.lock();
try {
doSomething(number);
System.out.println(” left right”);
other.rightLeft(this);
} finally {
lock.unlock();
other.lock.unlock();
}
}

public void rightLeft(LeftRightLock other) {
other.lock.lock();
lock.lock();
try {
doSomething(number);
System.out.println(” right left”);
other.leftRight(this);
} finally {
lock.unlock();
other.lock.unlock();
}
}

 

The 3rd one:

public void leftRight( LeftRightLock other){

if (lock.tryLock( )) {
try {

doSomething(number);
System.out.println(” left right”);
other.rightLeft(this);

} finally {
lock.unlock();
}

}else{

System.out.println (    “left Right : lock is not acquired “);
}

}

public void rightLeft( LeftRightLock other ) {
if ( lock.tryLock()) {
try {

doSomething(number);
System.out.println(” right left”);
other.leftRight(this);

} finally {
lock.unlock();
}
}else {

System.out.println (    “right Left : lock is not acquired “);
}
}