It is realy annoying that the newest version of Synolgy DSM (5.2-5644 Update 1) can’t handle properly hfs+ hard drive device out of the box. Thanks to the fact that many users had the same problems as me before I found realy quickly handy article which shows how to make easy workaround. The trick is to disable journaling on the drive and then try to remount the device in nas with ro flag switched off.
So to be able to write to an HSF+ USB drvie you need first
disable journaling on the drive
connect your drive to nas
remount device with ro flag switched off
Disabling journaling in the drive
To be able to do this you need to plug in your device to the mac (I couldn’t do this from my linux). Then to turn journaling off using Disk Utility do following:
open Disk Utility (located in Applications/Utilities).
select the disk device to disable journaling on.
choose Disable Journaling from the File menu.
For someone this option could not be visible (Mac OS X 10.4 and later) then before clicking on the File menu press and hold Option key
First log in as a root to the ds. Then have a look how the drive is mounted
123
ds> mount
/dev/sdq1 on /volumeUSB1/usbshare1-1 type vfat (utf8,umask=000,shortname=mixed,uid=1024,gid=100,quiet)
/dev/sdq2 on /volumeUSB1/usbshare1-2 type hfsplus (ro,force,uid=1024,gid=100,umask=000)
You can spot that the drive is mounted with the ro(read only) flag.
Now unmount the drive.
1
ds> umount -f /dev/sdq2
And remount so it is writable using the same info used when it was mounted automatically.
1
ds> mount -t hfsplus /dev/sdq2 /volumeUSB1/usbshare1-2
Finally, you can notice that device is no longer mounted as read only.
123
ds> mount
/dev/sdq1 on /volumeUSB1/usbshare1-1 type vfat (utf8,umask=000,shortname=mixed,uid=1024,gid=100,quiet)
/dev/sdq2 on /volumeUSB1/usbshare1-2 type hfsplus (0)
To prove this try.
1234
ds> ls /volumeUSB1/usbshare1-2/ | grep 'sampleDir'
ds> mkdir /volumeUSB1/usbshare1-2/sampleDir
ds> ls /volumeUSB1/usbshare1-2/ | grep 'sampleDir'
sampleDir
Note
It is very important to switch off journaling in the drive. When you remount the drive with ro switched off and haven’t yet disabled the journaling in the drive you won’t be able to write anything to the disk though mount will print that the drive is mounted as writable.
I have just released first version of git-svn kata. It is good starting point for those who prefer to use git but are stuck with svn. At the moment there are only two kata, but soon will be much more. To start just clone my repo
1
git clone git@github.com:ssledz/gitsvnkata.git
and run first one
12
cd kata-1-checkout-svn-project-std-layout
./start-kata.sh
Automata course was six weeks long. Before taking the course I had some prior knowledge about automata, regular expressions, context free grammar, turing machine and np-completeness. In my opinion most of the lectures was clear and understandable. I found it very helpful to have a quizzes during each one. They were keeping me up on the track for a whole time. After each module there was a homework consisting of some test questions. For me those homeworks were the most valuable components of the course. It helped me a lot to fully understand the materials.
Of course not everything was straight forward. The most dificult topic, for me, was np-completeness. To be honest I didn’t fully understand it. I can only guessing that it was caused by the fact that I haven’t spent as much time during study as I should. Maybe I will return to that but now there are much more important things to do on top of my todo list.
After taking a final exam I have earned Statement of Accomplishment attached below.
This post describes my development environment driven by Vagrant (Full description what can be found there is here). You can ask why Vagrant ? To be honest this is my first adventure with this tool. I am suprised how easy can be the process of setting brand new development environment. This tool can really save plenty of hours.
Vagrant provides easy to configure, reproducible, and portable work environments built on top of industry-standard technology and controlled by a single consistent workflow to help maximize the productivity and flexibility of you and your team. Sounds cool, isn’t it? One can configure the whole development environment with all the tools, needed libraries and various dependencies and other can just based on that create his own brand new development environment. The Process of introducing new team members into the project can be shortened by the time of setting new development environment.
Vagrant Providers
Vagrant has an ability to manage some of machine types like
VirtualBox
VMware
Docker
Hyper-V
In my setting I am using Virtualbox which is a free cross-platform consumer virtualization product supported by Oracle. To use this provider VirtualBox must be installed on its own. VirtualBox can be installed by downloading a package or installer for your operating system and using standard procedures to install that package.
Vagrant Installation
Visit the downloads page and get the appropriate installer or package for your platform. Then install it using standard procedures for your operating system. The installer will automatically add vagrant to your system path so that it is available in terminals.
Setting development environment
To set up java development environment You need just type the following bunch of commands
123
git clone git@github.com:ssledz/vagrant-boxes.git
cd vagrant-boxes/java-dev-environment
vagrant up
Now vagrant box image is downloading from the box repository and then installation script provision.sh will be called.
Virtual Disk Image (VDI) files grow over time. If You discover that VDI on the host system is much bigger than used space on the guest partition it is time for compaction.
Reboot the guest system in single user mode (Grub menu will appear if you press and hold Shift during starting,
then hit e when Grub boot appear and append single option to the Grub boot parameters).
Remount filesystems as readonly (mount -n -o remount,ro -t auto /dev/sda1 /).
Fill unused block with zeros (zerofree /dev/sda1). It’s time consuming operation. If You have other disk devices (e.g. /dev/sda5) then also perform zerofree on each one.
Shutdown the system (poweroff).
Compact VDI files on the host system (VBoxManage modifyhd my.vdi compact). It’s time consuming operation.
Instead points 1,3-5 to fill free space with zeros You can do following (You don’t need to boot in single user mode)
## Pushing generated _deploy website
To git@github.com:ssledz/ssledz.github.io.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'git@github.com:ssledz/ssledz.github.io.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Some times ago I was scanning Stackoverflow to find a puzzle to solve, and I found one guy was trying to write a piece of software which had needed to answer on one simple question. Is given expression a well formed array? He was searching for a ready to use regular expression but he failed, because this puzzle can’t be solved using regex engine. Why, I will explain later but now I can say that this puzzle can be easily solved using Context free grammar.
Well formed array
You can ask what does the well formed array mean ? I will try to answer by providing some positive and negative examples of such arrays.
Above are well formed arrays. In opposite below are expressions which are not syntactically consistent with the definition of well formed array.
123
[1 2 -34 7] 34]
[1 2 [-34 [7] 34]
[][]
Studying those examples we can try to answer on this question. So well formed array is an expression which fulfills following requirements
first, no blank, character is an open brace '['
the last no blank character needs to be a closed brace
inside array, integers and other well formed arrays can appear
integers are separated with at least one blank character
Why not regex ?
Let’s simplified our example. Let’s say that we want to write a regular expression which will generate following words
1234
[]
[[]]
[[]]
[[[]]]
You can notice that the mention above strings are a subset of the set of strings which we want to parse. And here I don’t have also good news. We can’t use regex engine to parse such strings.
Why is it not possible ? Simply speaking regex engine modeled by a Finite Automata (FA) can’t count how many '[' we have already used and check that the same number of ']' must appear just after the last '['. FA doesn’t have stack to remember such things. If You are curious about formal proof you can try to google Pumping Lemma phrase. Pumping Lemma provides You a useful tool to proof if a given language (set of words which fulfill given conditions) is not a regular.
Context free grammar
I have already mentioned that to solve our problem (if a given array is well formed) we need to write a parser of some context free grammar. The model of Context free grammar is a Finite Automata with a stack. Thanks to this an Automat is able to remember some facts that have happened (e.g count braces). To write a parser we need first to write down a grammar for expression of well formed array. To do this I will use ebnf (Extended Backus–Naur Form) form.
Now we are ready to write a parser. To be precise I will use top-down parsing strategy which let me directly transform written above grammar into set of recursively called procedures.
Parser
It is a good manner to split parser into 2 parts
lexer
parser
Lexer is responsible for grouping letters into tokens. In our grammar we have 4 kinds of tokens
'[' (LB)
']' (RB)
number (NUMBER)
end - token informing that there is no letter left on input (END)
Tokens are expressed by a class Token written below
publicclassParser{privateLexerlexer;privateTokencurrentToken;privatebooleanmatch(Typetype){returntype==currentToken.getType();}privatevoidconsume(Typetype){if(!match(type)){thrownewRuntimeException(String.format("Should be %s is %s",type.name(),currentToken.getType().name()));}currentToken=lexer.next();}privatevoidarray(){consume(Type.LB);while(true){if(match(Type.NUMBER)){consume(Type.NUMBER);}elseif(match(Type.LB)){array();}else{break;}}consume(Type.RB);}privatevoidparse(Stringline){lexer=newLexer(line);currentToken=lexer.next();array();consume(Type.END);}publicbooleanisWellFormedArray(Stringline){try{parse(line);returntrue;}catch(Exceptione){System.out.println(String.format("%s is not a proper array because %s",line,e.getMessage()));returnfalse;}}}
Writing a method to generate the nth Fibonacci number is not a rocket science. The recursive formula for that is very simple and can be written following:
The n-th Fibonacci number is just the sum of two previous Fibonacci numbers and the first and second formula are our ‘base cases’. Based on this we can write a method public static long slowFibonacci(int n)
You have already noticed that instead of writing fibonacci I have written slowFibonacci. There is a reason for that and You may guessing that probably we can do something with this method to make it much faster and You have right. There is a quite usful programming method which we can use to improve the performance of this method. However before doing this let’s try to write a method call stack trace for let’s say 5th Fibonacci number.
The number of dashes means how many delayed operations is on the stack. Dash followed by the ‘>’ (‘->’) means that the operation can be computed (return value is provided) and removed from the stack.
You can notice that the same operations are evaluated many times, for example slowFibonacci(2) is computed 3 times. It is obvious waste of cpu resources. What can we do to use previously computed value instead of evaluating it again and again ?
Dynamic programming
‘Dynamic programming’ method comes to our rescue. According to the wiki, ‘dynamic programming’ is a method for solving a complex problem by breaking it down into a collection of simpler subproblems. It is applicable to problems exhibiting the properties of overlapping subproblems and optimal substructure. The dynamic programming approach seeks to solve each subproblem only once, thus reducing the number of computations: once the solution to a given subproblem has been computed, it is stored or “memoized”: the next time the same solution is needed, it is simply looked up.
What does it mean for us ? Each already solved subproblem (computed i-th Fibonacci number) can be saved in the let’s say global array and if the same solution is needed just simply look for it in that table.
Write a method public static Set<Set<String>> subsets(Set<String> set) which returns all subsets of a given set. From mathematics point of view we need to compute the power set of the given set. The number of such subsets can be easily computed because it just 2 to the power of ‘number of element in a set’. So for a set consisting of 3 elements it is 8. To proceed let’s write some examples.
I bet that everyone who is reading this know how to write a method to revers the string, but does everyone know how to do it using recursion ? To face such puzzle it it always a good idea to write first some results for given arguments and try to find a pattern. There always must be a ‘base case’ which can’t be divided into subproblems. We also need to discover a procedure which solves bigger problem using its smaller subproblems.
So let’s say we need to write a method public static String revers(String arg) which for a given argument returns a reversed string. Below I have written some examples.
To compute a reversed string for 'a' we need to return that string and it is our ‘base case’. In other cases to compute a reversed string we need to get the last char and concatenate it with the reversed string without that last character.